"undefined reference" / "relocation truncate&

I am receiving many sets of the following error messages, and do not understand why:

-undefined reference to [i]function_name/i
-relocation truncated to fit R_RPC_REL24 [i]function_name/i

function_name exists in another file, but it has been prototyped in a header file which is included in the file where the errors are received. Are these compile or link errors?

Similarly, in the file where function_name is defined, there are sets of these error messages for other functions that are being called.

QNX support has suggested that the Makefile may need to be tweaked, and coworkers have suggested that I “somehow” need to change the order in which the header files are included.

Any suggestions??? Thanks!

There are linker error. There are LOTS of way to end up with that error, compiler flag, linker flags, header file, c files etc… Can you post a strip down version of .h .c and makefile involved in this.

StevenK,

You aren’t by chance mixing C and C++ code are you?

This kind of error often occurs when you try to call functions in C++ files from C files. The name manging of C++ is what causes this and there is a simple solution if this is indeed your problem.

Tim

I`v never seen -relocation truncated to fit R_RPC_REL24 function_name(void) though. So I wonder if it would be object build with -shared option and some without

The code is pretty horrific, as I have been cutting and pasting from various other files to put everything into one single file.

I made a chage to my makefile. I included “-Bstatic” on the line for the linker before my libraries. Now the many sets of those two error messages are gone. :exclamation: However, I’m getting a different error message, “skipping incompatible” while looking for a library. :question: Someone built that library for me, and I’m wondering if perhaps it was built for a different platform - like x86 rather than ppcbe. The library should be in the format of the target machine it is going to run on (rather than the machine it is being built on), right? Any thoughts as to what “skipping incompatible” means?

Not building with -shared option. Since I’m inserting code into my C++ file, would it matter if they were originally from a C file? As long as the function prototypes are C++ rather than C, I thought I’d be OK.

Thx!

I just discovered ntox86-objdump! It tells me that the file formats in the library are elf32-i386 rather than ppcbe.

I guess that explains why it is incompatible, since my target machine is ppc!

DUH!

StevenK,

As long as all the C files are renamed to .cpp (and hence treated as C++ by the compiler) you won’t suffer the name mangling problem. If you want to maintain seperate C and C++ files there is another step you need to take to prevent the undefined reference error. In your case if your making 1 large messy file you won’t have this problem at all since all the code is contained in that file. However if the library you want to link to is a C one this undefined reference problem will come back and haunt you again with library calls.

BTW, why are you merging all the files into one large messy file? Is this an experiment to solve your ‘undefined reference’ problem or are you really planning to leave it this way?

Since you mention much of the code came from C files my guess is that your original errors may well have been name manging problems.

Tim

Yes, Tim - the single file was an attempt to resolve the “undefined reference” problem. I generally try not to write messy code, but as a temporary step it is tolerable. :wink:

I’ve had a couple people mention “name mangling”. Can you describe what that is, and how to avoid that problem?

Thx.

In C++ functions can have the same name but different type of argument

int foo(int);
int foo( char *);

Are two different functions. For the linker and compiler to generate proper code it must be able to tell them apart. This is where name mangling comes in. The compiler will generate different internal name for these two functions

int foo(int) becomes _int_foo_int
int foo(char *) becomes _int_foo_charpt

I’m making the name up, but there is a standard way for mangling the names.

So from within a C program it becomes impossible to call either verion of foo, because C doesn’t know about the mangling.

In C++ it’s possible to turn off mangling, that is how C function can be called. Typically c files will have a matching header file

so if foo.c

void foo(int)
{
// some code
}

and foo.h

#if defined(__cplusplus)
extern “C” {
#endif

void foo(int);

}

#if defined(__cplusplus)
};
#endif

If foo.h is included by a C file the if defined prevent some specific C++ option to be process. If it’s included by a C++, whatever is between the bracket of the extern C statement will have name mangling disabled. That is how C++ code can call C function.

Thank you for your clear explanation! Now I know what to be careful to avoid!

It does look like a right-brace in your explanation, right after “void foo(int);” doesn’t belong there, because the two #if statements will supply both braces if needed. Right? I’m not picking on your example, I’m just making sure I understand!

Thx.

Yes that extra { is a mistake, sorry.

Mario, I realize that you were just making sure I understood the code snippet! :smiley: Thx!

well not really, lol!