Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


Initialization of fortran common character variables from c

Posted on 2003-11-14
Medium Priority
Last Modified: 2013-11-08

For enhancing portability I am attempting to modify this inherited piece of fortran and c software to change from passing char *'s to fortran from a c function, and instead initializing character variables (in the c code) stored in common on the fortran side.

If you have a better way, please suggest. I thought this might be the best way to avoid all of the portability issues that I have come across. Some systems pass an int at the end of the argument list, some long ints, it core dumps on the sun at the call, seems to be OK on linux, but in general the thing is a constant source of pain; hence, the reason I'm trying to change it.

I thought that if I created a struct declared as extern with the same name as the common block in the fortran code, that I could then initialize the character variables in fortran common from within the c code via the struct of the same name. This works for int's, floats, etc..

Don't ask or suggest doing it on the fortran side. I wish I could. This thing also uses lex and yacc to parse the input deck, and the initialization of all the variables is done via lex, yacc and c. I know nothing of lex and yacc. I wouldn't even attempt to change the parsing over to fortran.

So initialization of the variables from the input deck has to be done within c, and I have to then initialize fortran common. As I said it's working fine for int's and floats, etc. The original author elected to not do this for strings, hence, the reason I'm  asking this question here.

THe compiler is accepting it, and I can print out the values of the strings on the c side, but when I go to the fortran side they have garbage in them. So, as an example, say I have a struct named 's'.     And a common of the same name on the fortran side. On the fortran side I have a character array of a large size, say string. ON the c side the 's' struct has string as a member and is declared as a char *.

On the c side I do

       c.string = something from the lex/yacc parser.

I printf it out and can see that it is set correctly.

But on the fortran side, if I print out the value of string it's got garbage.

Anyone have any ideas, or have a better suggestion?

Thanks very much,
Skip Egley
Question by:egley
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 46

Expert Comment

by:Kent Olsen
ID: 9751083

Hi Skip,

This is a tough one.  (Which also makes it interesting....)

I would be very surprised if you can define fortran variables in labelled common and get to them directly from C.  The label name acts as a qualifier in a way that just isn't supported in C.

But that doesn't mean that it can't be done!

On the C side, can you define a struct that matches the common block description?  Then write a small assembler function that simply returns the address of the labelled common block.  My x80 assembler is horrible or I'd write it for you, but it seems that a simple function would do.

struct TCommonBlockA *CommonBlockA;
struct TCommonBlockB *CommonBlockB;

CommonBlockA = GetCommonBlockAAddress ();
CommonBlockB = GetCommonBlockBAddress ();



Author Comment

ID: 9752185

THanks Kent.

THe compilers I've had the pleasure to come across (which isn't that many) have all supported the equivalent of named common blocks via structs. That is how the original author of this code is initializing all of the other fortran common coming from the input parser.

But I notice that none of them have strings. He had been passing the strings through the calls, which was/is giving me all kinds of portability problems, because the compilers don't handle them the same. Some times it simply doesn't appear to work. I can't be quite sure, the thing just core dumps. And of course everything runs fine when debugging is on. But try the simplest optimization and it crashes and burns. THis thing without optimizations is useless.

I have to find another way...

LVL 11

Expert Comment

ID: 9753155
Many of the C compilers push their parameters on the stack back to front.  In Fortran, it is normally front to back.  Also, in C, the caller normally manages the stack whereas in Fortran, the called routine manages the stack.  You've done well to get past that lot.

How about using char [] instead of char*?  You are probably seeing a pointer address which is garbage instead of real data.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 22

Accepted Solution

grg99 earned 2000 total points
ID: 9758835
There's no standard way that FORTRAN compilers use for labeling common blocks.  Some use external symbols, some use segment names.  There's no easy way to make this portable by using structs.

What I would do is write a little glue routine, either in FORTRAN or in C, that passes the variables to the other side.
For example, something like:

COMMON /ALLTHEVARS/X(1000),Y(1000),NAMES(1000)


oops, that's going from FORTRAN to C, I see you mostly want to go the other way:

float getmearrayx( int Index ) { return( X[ Index ] ); }

... and so on.....

If you have a lot of variable sto pass, you could try passing more than one  back at a time, but this gets into array order issues.
If you haev the time, just pass back the elements one at a time as we do above.

For passing thru characters, you can do it the same way, a character at a time is best to avoid string format issues.

Author Comment

ID: 9768397
Thanks grg99,

Although not elegant (doubt if one can be elegant in this situation), I think your solution is best.

Could you explain to me what you mean by 'some use external symbols, some use segment names'? I'm not a compiler guy.

I continued on in the spirit of structs and named common, by storing them as 'signed char' and declaring them as one byte integers in fortran, then calling a fortran routine to convert these to strings. It's working, but your comment has me worried that this may not be portable either...

LVL 22

Expert Comment

ID: 9771368
At the linker's level, most linkers aloow a compiler to say "put these data bytes in an area we will call "_DATA"",
put these code bytes in an area named "_CODE", and so forth.   Many FORTRAN compilers map common  block names to linker segment names.
In C, some compilers have #pragmas that let you direct code or data to a particular linker segment.  So you might get away with:

/This is C:
#pragma data("XX")

int X[1000], Y[1000];

... which *might* map right onto the FORTRAN common block:

COMMON /XX/ X(1000), Y(1000)


But mapping multi-dimensional arrays can be a problem, as FORTRAN usually IIRC stores arrays in row-first order, most other languagesw do it the other way.   Also char arrays I have no idea how FORTRAN stores them.

Good luck,



Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This video teaches viewers about errors in exception handling.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses

636 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