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
egleyAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenDBACommented:

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

Kent OlsenDBACommented:
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
egleyAuthor Commented:
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
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

Kent OlsenDBACommented:

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
egleyAuthor Commented:
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
Kent OlsenDBACommented:

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
egleyAuthor Commented:

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
Kent OlsenDBACommented:

Hi Skip,

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

Kent
egleyAuthor Commented:

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
Kent OlsenDBACommented:

:)

Addresses are usually printed in hex.

188638423  B3E64E0
159232664  97DB298
-4262840    FFBEF448
190726448  B5E4130

Three of these addresses are positive, as they are only 28 bits in length.  The 32-bit address certainly seems reasonable, too.

I think that they are just fine.  You can test Address 26 just by trying to reference it, but I don't expect any problem.
Kent

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.