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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

752 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