-1

I compiled an .cc file with the following command, which is in Makefile code:

bin/bash ../libtool --silent --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I.
-I.. -I../include/ -I..    -g -O2 -MT rtpsession_inet.lo -MD -MP -MF 
.deps/rtpsession_inet.Tpo -c -o rtpsession_inet.lo rtpsession_inet.cc

There is a function named rtp_session_rtp_recv in the .cc file. However, it is said that the reference of this function cannot be found when I use the library generated by the Makefile.

So I checked the .o file generated by rtpsession_inet.cc and find that there is not a function named rtp_session_rtp_recv while the function name is changed to _Z20rtp_session_rtp_recvP11_RtpSessionj.

Meanwhile, there are several other functions changes their name, e.g. rtp_session_rtp_send -> _Z20rtp_session_rtp_sendP11_RtpSessionP4msgb.

But functions such as rtp_session_set_remote_addr_full are not changed at all.

What is the additional characters' meaning? How can I deal with this problem?

I compile the file in Linux and use command

nm rtpsession_inet.o

to read the .o file. (All the functions including the one with incorrect name are with T tag, which means the reference exists)

Thanks!

zzy
  • 751
  • 1
  • 13
  • 25
  • 1
    possible duplicate of [What is name mangling, and how does it work?](http://stackoverflow.com/questions/1314743/what-is-name-mangling-and-how-does-it-work) –  Aug 14 '13 at 23:05
  • But it doesn't works....... It seems that name mangling is a normal mechanism. I'm not sure whether the difference of name would have effect. – zzy Aug 14 '13 at 23:33

2 Answers2

1

This is called name mangling.

It's for the benefit of the linker. A C++ compiler is able to resolve multiple functions of the same name, based on their argument types. For example, you might have a function called print that takes an int argument, and another that takes a char* argument. The compiler knows which one to generate a call to based on what type of argument you pass to it.

Calls across translation units, though, have to be resolved by the linker, which typically is not aware of C++ overloading rules and has to resolve calls based only on the name. So the C++ compiler decorates the name with enough information to resolve the overload.

The C++ standard doesn't specify how this is done, but if you look at the name you can probably work out how the mangled name is generated.

How can I deal with this problem?

The compiler and linker should resolve calls correctly. What problem are you referring to?

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • I met the problem in a project and the final result of the project is a library (.so) file. When trying to compile another sample program using this library, it is said that: `/usr/local/lib//libortp.so: undefined reference to rtp_session_rtp_recv`. I don't know why it cannot find the reference and suspect that it is caused by the difference of the function name. BTW, the command I used to compile the sample program is `g++ -L /usr/local/lib/ -I /usr/local/include/ortp/ -I /usr/include/ rtpsend.c -o rtpsend -lortp`. – zzy Aug 14 '13 at 23:18
  • @zzy Take a look at 'extern "C"{}' to avoid mangling straight C calls. – Peter L. Aug 14 '13 at 23:31
  • When I add `extern "C"` to the head of `int rtp_session_rtp_recv (RtpSession * session, uint32_t user_ts)', it is said that 'rtpsession_priv.h:49:5: error: previous declaration of 'int rtp_session_rtp_recv(RtpSession*, uint32_t)' with 'C++' linkage `. And when after adding `extern "C"` to the head file as well, it is said that `rtpsession_priv.h:49:8: error: expected identifier or '(' before string constant`. So how can I use it? – zzy Aug 14 '13 at 23:40
  • `extern "C"` is valid only in C++ code. If you need it in a header to be `#include`d by both C and C++ source files, you need to enclose it in `#include __cplusplus`. See [this section](http://www.parashift.com/c++-faq/mixing-c-and-cpp.html) of the [C++ FAQ](http://www.parashift.com/c++-faq/) for information on mixing C and C++ code. – Keith Thompson Aug 14 '13 at 23:45
  • @zzy: Are you mixing C and C++ code in the same program? If so, you should have mentioned that in your question rather than assuming name mangling is the problem and just asking about that. http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Keith Thompson Aug 14 '13 at 23:47
  • That's true! Name mangling is only one possibility I find. Because I don't know it before, it seems serious to me before asking this question. Also , do you mean `#define __cplusplus` when you mentioned `#include __cplusplus`? It really looks strange maybe.... – zzy Aug 14 '13 at 23:53
  • @zzy: No, I meant **`#ifdef __cplusplus`**; sorry about that. – Keith Thompson Aug 15 '13 at 00:06
  • @KeithThompson: It seems that the __cplusplus has been defined yet in the program. And the declaration `extern "C" int rtp_session_rtp_recv (RtpSession * session, uint32_t user_ts)` in the head file isn't compiled, which caused an error called `implicit declaration of function`. So how can I use `extern "C"` in the .h file? I am still confused. – zzy Aug 15 '13 at 00:28
  • `__cplusplus` is always predefined for C++ code, and is never predefined for C code. `extern "C"` is used in C++ code, and is a syntax error in C code. That's why you need to surround it with `#ifdef __cplusplus`. Please read the [C++ FAQ section](http://www.parashift.com/c++-faq/mixing-c-and-cpp.html) on mixing C and C++; it explains this better than I could. – Keith Thompson Aug 15 '13 at 00:42
0

The additional characters are symbol "decorations" added by the compiler and are used to identify the function/method signature, i.e. the return type and the parameters. It helps the runtime determine which one of many functions of the same name (overloading) to invoke in any given invocation.

amrith
  • 953
  • 6
  • 17