Community
cancel
Showing results for 
Search instead for 
Did you mean: 
tomcook
Beginner
340 Views

C function symbol names

Jump to solution
We have a product that we currently compile using Intel Fortran and MSVC++ on Windows. I am evaluating using Intel Fortran and C++ to build the same product on Linux.

The problem I am having is that the MSVC++ compiler emits C function names with an underscore prepended to the name, while Linux compilers do not. All through the FORTRAN code, C functions are referenced using these names with leading underscores.

So is there some way to make the Intel C++ compiler give C function names a leading underscore? I have googled extensively and also read through the compiler option and pragma documentation without finding anything very useful.
0 Kudos
1 Solution
Steven_L_Intel1
Employee
340 Views

Tom,

Fortran 2003 has C interoperability features that will do what you want. No need to change the C code. As you have found, different platforms have different conventions.

Replace your Fortran subroutine declaration with this:

SUBROUTINE CreateObjects &
(GenP, GenContP, DCLinkP, GridContP, ProtP, NetworkP, LkUpTables, AcFail) BIND(C,NAME='CreateObjects')

The Fortran compiler will apply whatever the correct decoration is for the platform.

I strongly recommend replacing use of the obsolete and undocumented Microsoft Fortran syntax for attributes with what is supported in Fortran 2003.

View solution in original post

9 Replies
TimP
Black Belt
340 Views
Normally, implicit leading underscores are put in automatically for the cases where they are needed. I believe an underscore you show explicitly would be in addition to the implicit one required by some, but not all, combinations of Windows Fortran and C. You would show the explicit underscore both on the Fortran side (possibly in alias/ bind name=) and in the C++ (extern "C" for use with iso_c_binding).
tomcook
Beginner
340 Views
Quoting - tim18
Normally, implicit leading underscores are put in automatically for the cases where they are needed. I believe an underscore you show explicitly would be in addition to the implicit one required by some, but not all, combinations of Windows Fortran and C. You would show the explicit underscore both on the Fortran side (possibly in alias/ bind name=) and in the C++ (extern "C" for use with iso_c_binding).

Yes. So in our FORTRAN code we have:

[plain]INTERFACE
  SUBROUTINE CreateObjects &
    [C, ALIAS: '_CreateObjects'] (GenP, GenContP, DCLinkP,  GridContP, ProtP, NetworkP, LkUpTables, AcFail)[/plain]


and then in C++ code:
[cpp]extern "C"
{
  void CreateObjects (double *GenPa, double *GenContPa,
double *DCLinkPa, double *GridContPa, double *ProtPa,
double *NetworkPa, double *LookUpTables, int *AcFail); } ... void CreateObjects (double *GenPara, double *GenContPara,
double *DCLinkPara, double *GridContPara,
double *ProtPara, double *NetworkPara,
double *LookUpTables, int *pt_Ac_Fail) { ...[/cpp]

MSVC++ emits a symbol _CreateObjects, while Intel C++ on Linux emits CreateObjects and CreateObjects$$LSDA. My question is still, is there some way to make Intel C++ on Linux emit _CreateObjects, either instead of CreateObjects or in addition to it? I'd prefer a way of doing it using command-line options, but a pragma or something would be acceptable. Writing a wrapper function with a leading underscore should be a last resort.
Steven_L_Intel1
Employee
341 Views

Tom,

Fortran 2003 has C interoperability features that will do what you want. No need to change the C code. As you have found, different platforms have different conventions.

Replace your Fortran subroutine declaration with this:

SUBROUTINE CreateObjects &
(GenP, GenContP, DCLinkP, GridContP, ProtP, NetworkP, LkUpTables, AcFail) BIND(C,NAME='CreateObjects')

The Fortran compiler will apply whatever the correct decoration is for the platform.

I strongly recommend replacing use of the obsolete and undocumented Microsoft Fortran syntax for attributes with what is supported in Fortran 2003.

View solution in original post

tomcook
Beginner
340 Views

Tom,

Fortran 2003 has C interoperability features that will do what you want. No need to change the C code. As you have found, different platforms have different conventions.


Thanks, that seems to be as close as I'll get. I know nothing at all about Fortran, I'm afraid - I've been handed this as the person who knows the most about Linux, not the most about Fortran. I'll have to talk to our Fortran guys about how they want to handle this.

Thanks again,

Tom
Steven_L_Intel1
Employee
340 Views
Tom,

As I suggested earlier, you can probably make this work by removing the text in square brackets (along with the brackets) and then adding, after the closing parenthesis of the SUBROUTINE statement, this:

BIND(C,NAME='CaseSensitiveName')

where CaseSensitiveName is replaced by the exact name as in the C code. That should do what you want.
woleakande
Beginner
340 Views

Hi sir,its really scarce to get people like you so am using a very rear oppurtunity.
I want you to help me on the folowing:
1) writing win32 code in C/C++ for pixel,graphics and installation codes
2)using byte keyword effectively for all possible codes
3)generating application that interact successfully and effectively with hardwares connected to a PC either wired or wirelessly
Thanks in anticipation.
tomcook
Beginner
340 Views
Steve,

Thanks again for your quick help. I have modified our Fortran code to use the new binding mechanism. Now I have the opposite problem - underscores at the ends of names! It seems on Windows the Fortran compiler does not add these by default, while on Linux it does add them. So all our C code that refers to Fortran functions does not expect the symbols to have a trailing underscore.

I have found the '-assume nounderscore' commandline option, which fixes the linkage between the Fortran and C code, but it then breaks the linkage between the Fortran code and the IFPORT library; code like this:
[plain]USE IFPORT
...
CALL FLUSH(6)[/plain]
generates an undefined symbol called 'flush' in the object file:
[shell]$ nm lib.a | grep flush
       U  flush
[/shell]
but libifport.a has 'flush_':
[shell]$ nm /opt/intel/Compiler/11.1/059/lib/ia32/libifport.a | grep flush
flush.o:
00000000 T flush_
[/shell]
Is there a way to resolve this?

Sorry for asking what must be stupid newby Fortran questions, but Google doesn't seem to know many answers about this. Feel free to tell me to go away to the Fortran compiler forum if that would be better, too.

Tom
Steven_L_Intel1
Employee
340 Views

Tom,

It probably would be better for you to ask Fortran questions in the Fortran forum, but the topic of C interoperability may be of interest here, so we can continue in this thread.

You are correct that on Linux, the convention is that Fortran routines have a trailing underscore whereas on Windows that convention does not exist. You can solve this the same way as you solve calling C routines - add BIND(C) to the Fortran routines you want to call. For example:

subroutine MySub (arg) bind(C)

by default, the name will be downcased, but you can add NAME= the same as above if you want something else. No trailing underscore will be added.

This is the recommended way of declaring Fortran procedures to be called from C. Again, you can add the VALUE attribute to argument declarations if you want them received by value, such as:

integer(C_INT), value :: arg

You'll need to add:

USE ISO_C_BINDING

to get the definition of C_INT, etc.
joelkatz
Novice
340 Views
Quoting - woleakande

Hi sir,its really scarce to get people like you so am using a very rear oppurtunity.
I want you to help me on the folowing:
1) writing win32 code in C/C++ for pixel,graphics and installation codes
2)using byte keyword effectively for all possible codes
3)generating application that interact successfully and effectively with hardwares connected to a PC either wired or wirelessly
Thanks in anticipation.

You can't really get specific answers unless you ask specific questions. Your questions are like:
1) How can I build a bridge?
2) How do you drive a car?
3) How do you use the buildings in a city?

Worse, you don't state what your areas of knowledge and expertise are. So it's hard to give you an appropriate answer. If an 8 year old asks "how do you build a suspension bridge", they get a very different answer than if a professional civil engineer who has designed and built truss bridges that carry traffic gets.

Please try to focus your questions and clarify your level of knowledge so that you can get appropriate and detailed answers.
Reply