![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 | |
|
Programmer
Join Date: Oct 2005
Posts: 68
Rep Power: 3
![]() |
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? |
|
|
|
|
|
|
#2 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,207
Rep Power: 5
![]() |
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. |
|
|
|
|
|
#3 |
|
Hobbyist Programmer
Join Date: Jun 2005
Location: New Mexico
Posts: 228
Rep Power: 4
![]() |
[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)
{
return 0;
}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. |
|
|
|
|
|
#4 | |||
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,207
Rep Power: 5
![]() |
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:
|
|||
|
|
|
|
|
#5 |
|
Programmer
Join Date: Oct 2005
Posts: 68
Rep Power: 3
![]() |
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 ![]() |
|
|
|
|
|
#6 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: elemental plane
Posts: 1,429
Rep Power: 5
![]() |
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>
#include <math.h>
int main()
{
printf("%d\n", pow(3, 2));
return 0;
}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?
__________________
"Employ your time in improving yourself by other men's writings, so that you shall gain easily what others have labored hard for." -- Socrates |
|
|
|
|
|
#7 |
|
Hobbyist Programmer
Join Date: Jun 2005
Location: New Mexico
Posts: 228
Rep Power: 4
![]() |
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 |
|
|
|
|
|
#8 |
|
Hobbyist Programmer
Join Date: Jun 2005
Location: New Mexico
Posts: 228
Rep Power: 4
![]() |
POSIX and IRIX don't get along too well, as you note, Grumpy.
|
|
|
|
|
|
#9 | ||
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,207
Rep Power: 5
![]() |
Quote:
Quote:
|
||
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|