Author Topic: C naming convention and underscores  (Read 11375 times)

ikolev

  • Guest
C naming convention and underscores
« on: March 03, 2006, 12:05:51 am »
Hi guys,

For a first post, let me say first that I'm really impressed by Code::Blocks. It's simply inspiring... a powerful open-source IDE for C++ (and properly conceived and designed, which makes it stand out from the similar projects) - sounds like a dream coming true. I really feel strong urge to help with the development. I hope I'll find the time one day. For now, I'm happy that I compiled successfully the SVN head, so there's a warm sense of confidence that if I'm really bugged by some bug or glitch (like the missing support for last tab switching on Ctrl-Tab, which IIRC is a Scintilla shortcoming), I could try to fix it myself. That's a feeling you don't get with commercial software. Of course, there are still small glitches and weaknesses compared to the well-known giant of C++ IDE's, but I'm sure these will be worked out in time. BTW, I think it would be a good idea to put download links to a much more recent build - the progress since October's RC2 is enormous.

Now to the first problem I couldn't quickly solve myself. I tried to build one of my libraries ( http://www.ikolev.com/DebugTools/ ) with GNU C++, and I got a link time error " undefined reference to `timeGetTime@0' ". The library uses timeGetTime() from libwinmm.a, which as I can see in the binary of the library is named _timeGetTime@0. However, GNU C++ obviously doesn't put a leading underscore when compiling my source code. Question is why? I'm quite new to GNU C++ so maybe I miss something about its options. I have distant memories from more than 10 years ago when I used Watcom C and had similar naming problems (which I had learned how to solve then, but can't remember now - it was somehow related to the calling convention - cdecl, fastcall, etc.). It's strange that this problem doesn't appear when compiling with Dev-Cpp 4.9.9.2. I hope someone has a quick answer to this...

Thanks,
Ivan
« Last Edit: March 03, 2006, 12:13:19 am by ikolev »

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5490
Re: C naming convention and underscores
« Reply #1 on: March 03, 2006, 12:14:46 am »
Quote
BTW, I think it would be a good idea to put download links to a much more recent build - the progress since October's RC2 is enormous.

Follow the nightlies link on the codeblocks.org, or in here in the forum go to the nightlies section.

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: C naming convention and underscores
« Reply #2 on: March 03, 2006, 01:15:54 am »
Follow the nightlies link on the codeblocks.org, or in here in the forum go to the nightlies section.

I think he wants those to be displayed more prominently.  I think there should be a notice right below the RC2 message on the front page that user should try the nightly builds if they have problems.

About the library.  Both C and C++ compilers do name mangling, although the C method is standard, the compiler just puts a "_" in front of the name which is why you set "_timeGetTime()" in the binary.  Can you set the compiler to show the full command line and then post the results.
« Last Edit: March 03, 2006, 01:18:20 am by Game_Ender »

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1441
    • CenizaSOFT
Re: C naming convention and underscores
« Reply #3 on: March 03, 2006, 03:17:53 am »
Be sure to have something like this when you compile with C++ trying to access things compiled with C:

Code: cpp
#ifdef __cplusplus
extern "C" {
#endif
int timeGetTime(); // it's just a guess it returns int, just be sure to write it correctly here
// anything other declarations go here
#ifdef __cplusplus
}
#endif

That should do.

It's because of differences in name mangling, just like Game_Ender said.

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: C naming convention and underscores
« Reply #4 on: March 03, 2006, 07:42:26 am »
The reason you can just include the std C headers and not have to worry about this is because they already have all the proper defines setup to include the "extern C" if you are using a C++ compiler.

ikolev

  • Guest
GNU Linker problems (was: C naming convention and underscores)
« Reply #5 on: March 03, 2006, 12:59:27 pm »
I think he wants those to be displayed more prominently.  I think there should be a notice right below the RC2 message on the front page that user should try the nightly builds if they have problems.

Exactly. I understand that the nightly builds are probably less stable and change a lot, but RC2 simply doesn't show the state of the project. And I guess most people don't like to try the "bleeding edge" expecting that it's much less stable, and don't bother downloading nightly builds. But I guess it's a matter of policy when the authors will decide to announce "a new and much improved build". BTW, calling these builds "release candidates" is not a good idea, since one expects from RC's to represent the final state of the project and only contain bug-fixes from there on.

The reason you can just include the std C headers and not have to worry about this is because they already have all the proper defines setup to include the "extern C" if you are using a C++ compiler.

Exactly. Naturally, I had examined MMSystem.h and noticed that it includes an extern "C" declaration.

About the library.  Both C and C++ compilers do name mangling, although the C method is standard, the compiler just puts a "_" in front of the name which is why you set "_timeGetTime()" in the binary.  Can you set the compiler to show the full command line and then post the results.

The problem turned out to be entirely different. First I discovered that the function name was actually the same in the object file that uses timeGetTime and in libwinmm.a - it was "_timeGetTime@0". I should have checked the .o file, but since the GNU linker message was about 'timeGetTime@0' (without a leading _), I decided that this is the exact name of the function as listed in the .o file. It turns out that the linker tries to "beatify" the name a bit, which confused me.
Then I started comparing the command lines issued by C::B and Dev-Cpp. One worked while the other didn't. I couldn't see any important differences. I started converging the two lines step by step and testing them. Finally I found out that the order of listing the object and library files in the command line is important - the linker searches for references only in the following objects on the command line. At this point I realized why in the build options of the C::B IDE you can select whether the target options are to be appended or prepended to the project options. Setting the proper order of command line generation fixed the problem.

So I guess these are just typical experience lessons from using a new compiler/linker... first the misleading error message, then the discovery about importance of order in the command line (I'm sure the MS linker doesn't require any order). I guess the explanation about this "append/prepend" option should be included in a future detailed documentation, for people without GNU C++ experience.
(BTW, I changed the topic to make it a bit more relevant.)
« Last Edit: March 03, 2006, 01:02:47 pm by ikolev »

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: C naming convention and underscores
« Reply #6 on: March 03, 2006, 09:14:20 pm »
I have a releated problem.  I am creating a C++ library with G++, that has needs to have C linkage so it can be loaded by another program.  I thought the way to do this was to create some functions that use your classes, then the wrap the declartions for those functions in extern "C".  After you have done that, compile and linked the shared library, and you will have a shared library with the C symbols properly exported.

I created a very simple test that has two library both which should export the function "add", one in C, and the other in C++.  Then I have two test targets which create a C program.  One tries to link with the C library the other with the C++.  The C++ one fails to link.  Here is the a zip file of the project.
Code
-------------- Build: CppLib in C2C++Lib ---------------
g++  -Iinclude -I/usr/include  -c src/adder.cpp -o .objs/src/adder.o
g++  -Iinclude -I/usr/include  -c src/cinterface.cpp -o .objs/src/cinterface.o
g++ -shared -L/usr/lib  .objs/src/adder.o .objs/src/cinterface.o   -o libcpplib.so 

-------------- Build: CLib in C2C++Lib ---------------
gcc  -Iinclude -I/usr/include  -c src/cadd.c -o .objs/src/cadd.o
g++ -shared -L/usr/lib  .objs/src/cadd.o   -o libclib.so 

-------------- Build: testC in C2C++Lib ---------------
gcc  -Iinclude -I/usr/include  -c src/test.c -o .objs/src/test.o
g++ -L. -L/usr/lib  -o testc .objs/src/test.o    -lclib
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings
 
-------------- Build: testCpp in C2C++Lib ---------------
g++ -L. -L/usr/lib  -o testcpp .objs/src/test.o    -lcpplib
.objs/src/test.o: In function `main':
test.c:(.text+0x55): undefined reference to `add'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
0 errors, 0 warnings

I am using Rev 2133.  I think I have to export the symbols in another way but I am unsure.

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: C naming convention and underscores
« Reply #7 on: March 03, 2006, 10:03:40 pm »
I haven't tried your project, but something seems wrong:

Code
-------------- Build: testCpp in C2C++Lib ---------------
g++ -L. -L/usr/lib  -o testcpp .objs/src/test.o    -lcpplib
.objs/src/test.o: In function `main':

I see no compiling here. Just linking.
This leads me to believe the object directory for this target is not unique and so it tries to link the object file already created from another of your targets.
Be patient!
This bug will be fixed soon...

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: C naming convention and underscores
« Reply #8 on: March 03, 2006, 10:15:36 pm »
I tried separating the obj directories for the two test programs, didn't help.  I expected this, because at the start I only had the one program that tried to link in the C++ library.   I added the C version for testing purposes.  Thanks for the tip though.
« Last Edit: March 03, 2006, 10:19:36 pm by Game_Ender »

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: C naming convention and underscores
« Reply #9 on: March 03, 2006, 11:46:24 pm »
I found your problem.
Your test file is named "test.c". This makes gcc compile it as a C file, not C++, so the linking is tried using the C name mangling, even when compiling the C++ version of the test program...

To fix this, add -xc++ in the testCpp target other compiler options. This will force all files built under this target, to be built as C++ no matter what gcc thinks ;).

Be patient!
This bug will be fixed soon...

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: C naming convention and underscores
« Reply #10 on: March 04, 2006, 01:30:14 am »
Ok, then.  But I have a question:  I am trying to make an interface for a simple render I made with Ogre and Matlab.  Matlab can load any library with C linkage.  So I am trying compile the render (written in C++) with some simple C functions as an interface and give them C linkage (there declartions to be specific) in the shared library with "extern C".  This will provide a nice bridge between Ogre and Matlab.

Is this possilbe?

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: C naming convention and underscores
« Reply #11 on: March 04, 2006, 08:41:04 am »
Ok, then.  But I have a question:  I am trying to make an interface for a simple render I made with Ogre and Matlab.  Matlab can load any library with C linkage.  So I am trying compile the render (written in C++) with some simple C functions as an interface and give them C linkage (there declartions to be specific) in the shared library with "extern C".  This will provide a nice bridge between Ogre and Matlab.

Is this possilbe?

I don't quite understand. I thought your example project did just that. The only problem it had was with the test program, not the library...
If I understand correctly, you 're writing a library for MatLab so you want it to have C linkage. Is that correct?
Be patient!
This bug will be fixed soon...

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: C naming convention and underscores
« Reply #12 on: March 04, 2006, 11:26:56 pm »
I don't quite understand. I thought your example project did just that. The only problem it had was with the test program, not the library...
If I understand correctly, you 're writing a library for MatLab so you want it to have C linkage. Is that correct?

Yes.  The testCpp target is supposed be a C program linked to a library compiled in C++ but with C linkage for "add" function.  The testC target is just the same program but linked against a C library with the "add" function.  Of course if I compile testCpp as C++ it will work, but the whole idea is to produce as C++ library that has some functions exported with C name mangling so Matlab can load it, because matlab only understands C name mangling.  If the testCpp target works (a C program linking to the C++ library) then I have succeeded.  As it stands right now the C++ library with the externed "C" function, does not load properly in Matlab and the C one does.

So to say it shortly: I was trying to a test to make sure the G++ did not mangle the function name I labeled with "extern "C"", and this test was the only way I could do this until I found the unix tool "nm" a few minutes ago.  I am going to keep plugging away and see if I can get G++ to not mangle the externed function.

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: C naming convention and underscores
« Reply #13 on: March 04, 2006, 11:40:31 pm »
I have succeeded I have to wrap the both the implementation and declaration of the functions I use for the matlab interface with extern "C", in order to G++ to not mangle the names.  That was not really stated in anywhere, but I dug it out an only HP related mailing list posting.  Thanks for the IDE and the help mandrav.