Solved

Checking addresses of fortran passed variables in a c func

Posted on 2003-12-01
10
380 Views
Last Modified: 2013-11-08
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
0
Comment
Question by:egley
  • 6
  • 4
10 Comments
 
LVL 45

Expert Comment

by:Kdo
ID: 9855077

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

0
 
LVL 45

Expert Comment

by:Kdo
ID: 9855099
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
0
 

Author Comment

by:egley
ID: 9859464
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
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9859667

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
0
 

Author Comment

by:egley
ID: 9860210
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
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 45

Expert Comment

by:Kdo
ID: 9860486

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
0
 

Author Comment

by:egley
ID: 9861378

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
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9861620

Hi Skip,

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

Kent
0
 

Author Comment

by:egley
ID: 9861983

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
0
 
LVL 45

Accepted Solution

by:
Kdo earned 350 total points
ID: 9862027

:)

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
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The purpose of this article is to demonstrate how we can use conditional statements using Python.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now