![]() |
Weirdness of -l compile flag
Why is it that i need to add the -lm flag during compilation, when i already included #include <math.h> ?
Quote:
If that is the case, why don't we need to add flags such as -lstring, -lstdio for string.h and stdio.h respectively? |
You probably would have received an earlier response if you had actually identified your compiler and operating system .... your question is actually specific to those.
In any event, under most flavours of unix (or on ports of unix compilers, such as gcc, to windows) -lm is not a compiler option, it is a linker option. Your compiler command (eg cc by default on most unixes, gcc if you're using a gnu compiler) does a bit more than you think it does. When you use it in a way that requires a starting point of source code and an end point of an executable, it does (approximately) the following steps; 1) Compile the various source files (with a .c extension for C, or .cpp extension for C++ source) to create an object file (which usually has a .o extension). This is done by invoking the actual compiler (the thing that understands source code). If you're using cc, this step is roughly equivalent to "cc -c <other compiler options> file.c". 2) Collect all of the .o files created in the previous step, and any filenames and command line options, and invoke the linker --- which is a totally different program. The command line options that the linker understand include lists of libraries (the things represented by -l<library_name> and various other things related to creating the final executable file). Essentially it links all the .o files, and the libraries it is told to link in, together to create the executable. 3) Delete the .o files that it created in the first step. So what's the relevance of the above? Well, -lm is an option supplied to the linker, and tells it to link in the math library. By default, the math library is not linked in because (so it is claimed) the majority of applications do not need it. The catch is that the driver program that pulls together the various steps for compilation and linking does not actually interpret the source code, so does not realise that source code which uses #include <math.h> probably needs the math library. So you need to tell it, by specifying "-lm", to do that. It passes that command line option directly on to the linker. The reason you don't need to do this for other standard headers is that, by default, the linker is told to link in the standard C library (-l<some_name_I_cannot_remember_offhand>), and that library includes implementations of the functions in string.h and stdio.h. The above is a very simplistic view of what happens, and is a relatively long-standing tradition in the unix world. In your case, you would (unless you've done something else wrong) have gotten past the compilation phase, and the linker phase will be failing. |
[sarcasm]
-l<somename..> = libc Which is really tough becuase were coding in what language. [/sarcasm] Actually the linking thing with the -ell business is confusing and not aat all meaningful. Plus, it is always :
int main( what goes here may vary):
main()If you run code like this thru lint or compile with gcc -Wall (either one highly recomended) stuff like this generates all kinds of complaints. Rule #1 - Never use C code that has compiler complaints. You'll complain later on. See: http://www.lysator.liu.se/c/ten-commandments.html It's meant somewhat in fun but largely to be taken as gospel. Which is why the Elizabethan english.... Rule #2 If ever in doubt see Rule #1. |
Quote:
The name actually varies between compilers. I encountered one Irix compiler a few years ago that named the standard C library cstd. Quote:
It is often considered bad style (as it is a source of future errors) to rely on that behaviour, which is why .... Quote:
|
hehe sorry...i'll be more specific in my future posts.
i'm using gcc on linux. so basically most compilers would include some -l<??>, and omit some (like for this case, -lm). Thanks ;) |
I may be misunderstanding because of the language barrier, but isn't a linker supposed to link only to those functions used in the source code?
For example :
#include <stdio.h>Then your linker would only link the printf and pow function, and not all the other functions included in stdio.h and math.h right? |
nnxion -
Link editing does just that. It finds external symbols (function entry points and pointers to memory) that are not locally defined. by C standard this means 1. linker brings in a file called crt.0 - which is _startup - the thing that invokes main _startup always does OS dependent stuff- like creating stdin. _startup is not a name defined in the standard, it describes what it does. crt0.o is a standard C object filename in POSIX. What is in crt0.o is also standard - _startup code and _end code. 2. linker brings in _end and then _Exit (from libc because _end invokes it). Al of this is on the "other end" of main(). _Exit is defined in the standard and is called by _end. It unwinds the stack and closes any open file, then does what it takes to get the OS to rundown the process internal data. 3. Look first in libc (standard file name) for any undefined symbols in the object file(s). This is why you should not use names like printf as function names you create. This is the dash big-ell syntax -L <directory> 4. Lookup undefined symbols using either a directory search of libraries or a search in a list of specified libraries. This is the dash lowercase ell thing. -lm |
POSIX and IRIX don't get along too well, as you note, Grumpy.
|
Quote:
Quote:
|
| All times are GMT -5. The time now is 8:47 AM. |
Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC