Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour of gcc and math.h? [duplicate]

Tags:

c

math

pow

I've been trying to build some code that uses math functions (e.g. pow).

math.h is included, and the flag -lm is used during the build.

When compilation is called like this (-lm flag at the begining of the command), it failed, saying that there is an undefined reference to pow:

gcc -lm -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder
main.o: In function `get_sn_motif_id':
main.c:(.text+0x28d): undefined reference to `pow'

And when the -lm flag is put at the end of the comand, it works!

gcc -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder -lm

Is this normal?

like image 746
jtextori Avatar asked Jan 25 '12 08:01

jtextori


2 Answers

Yes, it is normal. For many linkers, the order in which you specify the object files and the libraries matters.

To quote "An Introduction to GCC - for the GNU compilers gcc and g++":

The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it. This includes libraries specified with the short-cut -l option, as shown in the following command:

$ gcc -Wall calc.c -lm -o calc (correct order)

This behaviour is common, but is by no means universal. When in doubt, it is best to consult your linker's manual. For example, on my Ubuntu system man ld states that:

   -l namespec
   --library=namespec

       ...

       The linker will search an archive only once, at the location where
       it is specified on the command line.  If the archive defines a
       symbol which was undefined in some object which appeared before the
       archive on the command line, the linker will include the
       appropriate file(s) from the archive.  However, an undefined symbol
       in an object appearing later on the command line will not cause the
       linker to search the archive again.

In other words, this linker does behave in the manner described in the gcc book.

like image 130
NPE Avatar answered Oct 14 '22 12:10

NPE


As mentioned in An Introduction to GCC - for the GNU compilers gcc and g++

The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it.

I think you are seeing the same behavior.

Note that it also further states,

Most modern linkers search all libraries, regardless of order, but it is best to follow the convention of ordering libraries from left to right.

like image 4
Alok Save Avatar answered Oct 14 '22 11:10

Alok Save