Link to home
Start Free TrialLog in
Avatar of egley
egley

asked on

Checking addresses of fortran passed variables in a c func

Hi,

I'm having some trouble with some fortran code. Arithmetic exception at the return from a subroutine. This only occurs with optimization; if I turn on debugging it works fine. I've checked everything I possibly can, but I don't see anything wrong. It could be something farther up the line is awry.

I suspect that memory is a bit screwed up. The code is too big to have the cross reference checker available on the sun do this for me. It bombs at the end, complaining of too many files or something like that.

I thought I would write a generic c function that would check the addresses of passed variables before a call, and then call it again once inside the routine, via some sort of c function. I could place this at points in the code which I suspect are giving me problems.

I don't know if this is possible in fortran, but I don't think so. So I'm looking to c.

Since fortran always passes by reference, or address, and c will allow me access to the address of the pointer, it seems the way to go.

What I've done so far is copied the signature of the fortran subroutine call into a call to a c routine, declared the integer variables as int *'s, real variables as float *'s, and double precision variables as double *'s. Then I store the addresses of the variables (first element in array case) in a long int on the c side. But they all have the same value?! What am I doing wrong? For instance, here is one line which is supposed to store an address:

i1[3] = (long int*) rtest;

i1 is declared as long int, and in this particular case rtest is coming from fortran declared as real, and declared as float* on the c side.

If I print out the i1's, they all have the same value.
What stupid thing am I doing wrong here?
I've also tried it without the cast - no luck.

Once I have this going, I'm wondering if there's a more robust way of doing this. Something that would work regardless of the number of variables being passes...


Thanks very much!
Skip Egley
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image


One thing that you're doing is setting i1[] to a value instead of an address.  If you're convinced that you have a parameter problem with a fortran program, you need to check the addresses being passed, not the value at the address.

void *i1[ArraySize];

i1[3] = &rtest;


Also, remember that when you recast something, the compiler generates the code to convert it from its "native" state to the data type that the cast indicates.

float v = 3.14159;
int i;

i = (int) v;

All you've done is trunctate v to 3 and stored it into i.  C will do this without the cast.


Kent

hi egley,

Another thing, many FORTRAN compilers have an addr() macro/function that will return the address of a variable.  It's a run-time evaluation so it returns a memory address.  You might be able to take advantage of this.

I recall some very old FORTRAN code where addr() was used to march through memory looking for "something".  Memory on that system was not virtual so the first address of a program space was 0.  Defining an array and indexing into it "out of bounds" made the entire job's memory available to the program.

      int K(1)

      do 10 i = 1, 10000
 10  IntVal = K(i - addr(K) - 1)

Dunno, but this trick might help, too.


Kent
Avatar of egley
egley

ASKER

Hi Kent,

Thanks for the comment.

I thought that if they are coming in as pointers, I didn't use the & operator to obtain the address of the thing pointed to. I just used the pointer without the dereference operator (i.e., *). Is this not true? All variables coming into the c routine are declared as pointers, which I believe is the correct way to handle variables coming from fortran. Using the & operator on a pointer would give me the address of the pointer, no?

I will try this addr() on my fortran compiler...

Thanks again,
Skip

Hi Skip,

You're right.  I misread your statement about how you'd declared the C function.  But this does bring up another possibility.  :)


Func(int *a, char *b, long *c, int *d, int *e)
{
  char * Ptr;

  Ptr = (char *) &a;

/*
  *Ptr is a
  *(Ptr+1) is b (recast as necesary)
  *(Ptr+2) is c
  etc...
*/

}

Kent
Avatar of egley

ASKER

Hi Kent,

Your 'possibility' spurred a thought.
Is there a problem to simply declare all received variables on the c side as char *'s? I really only want the address of the first element in the case of an array. I don't care if they  are actually doubles, floats, or whatever. But I don't understand exactly what is returned.

I mean if I pass a double precision array a, and then print out the address on the c side, would it be the same whether it was a double precision array or an integer array or a float array? Does it give the address of the first byte?

Thanks,
Skip

Hi Skip,

You can certainly do that.  Pointers are pointers are pointers.  It's only how you use the object that the pointer references that suggests a difference.  (The difference is the usage of the referenced object.)

That 'possibility' can be simplified:

Func(int *a, char *b, long *c, int *d, int *e)
{
  char *Ptr[];

  Ptr = (char **) &a;

/*
  Ptr[0] is a
  Ptr[1] is b (recast as necesary)
  Ptr[2] is c
  etc...
*/

}

Kent
Avatar of egley

ASKER


Kent,

Casting all of them to char *'s appears to work fine.
I've checked the addresses of all passed arrays and variables right before the call, then again when I'm in the subroutine.

The good news is they are the same.
The bad news is that some of them are negative.
This is not possible is it?

I'm a bit worried about misinterpreting the hex addresses when declaring as char and they end up coming out signed, and the sign being negative when it shouldn't actually be negative if interpreted correctly.

Skip

Hi Skip,

The sign bit doesn't necessarily mean a problem.  What are some of the addresses?

Kent
Avatar of egley

ASKER


Kent,

THey typically are between 100-200 million when printed out, except for the negative ones which are typically only a couple of milliong with a negative sign.

Here's a few of them, including a negative one.

Address 24: 188638432
Address 25: 159232664
Address 26: -4262840
Address 27: 190726448


Think these are OK?

Skip
ASKER CERTIFIED SOLUTION
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial