![]() |
|
#1
|
|||
|
|||
Undefined reference to powHi there,
I got stuck for a while on that issue and I've been googleling around to find some info, however I haven't found a post in this forum speaking about that. What I found is that when in both gcc 3.4.4 (cygwin) and gcc 3.3.1 (SUSE 9), the math library has to be explicitly specified at linking time with "-lm", otherwise, even including math.h in the source code the compilation gives an error. Here I found an article describing the problem: http://use.perl.org/~Ovid/journal/10965 Perhaps someone can extend the information a bit more. Regards, Pisuke |
|
#2
|
|||
|
|||
Re: undefined reference to powQuote:
1. Including <math.h> shows the compiler the prototypes for the various functions in the math library. This makes the compiler happy, but has nothing to do with the linker. 2. The tradition for UNIX C compilers is that the math library is not linked into your program without explicitly telling the linker to use libm.a (or its shared library equivalent libm.so). 3. The command line switch that tells the compiler to pass along library information to the linker is "-l". The tradition for UNIX C compilers is that the indication to use "libanything.a" is "-lanything", so a command line for a program that uses the math library, libm, would be something like: cc z.c -lm 5. The good people who control the gcc distributions have apparently made it a little more convenient for users by eliminating the explicit requirement for math library linkage. Current versions of gcc that I use (3.4.4 on my cygwin/Windows XP platform and 4.something.anything on my various Linux (Fedora, Centos, Ubuntu) installations will link into various "built-in" functions like the math functions automatically without the "-lm" command line switch, so I don't know what there is about your cygwin installation that would cause the problem. As far as the Linux: I know that gcc 3.2.2 required the "-lm", and gcc 3.4.anything didn't, but I don't know about gcc 3.3.anything. Bottom line recommendation: If it compiles and links OK with the "-lm" on the command lines, then put "-lm" on the command lines. If you find this annoying (I probably would), then create a simple "make" file to compile. Regards, Dave |
|
#3
|
|||
|
|||
Re: Undefined reference to powWhile your on the subject,
Dave, do you mean that compiling with -lm will link all libraries that begin with m ? In the link Pisuke provided, it was pointed out that the guy could compile successfully with a prototype and an -lm. I found that I can compile ok with prototype alone and no -lm with my: gcc version 3.3.1 (mingw special 20030804-1) CPP / C++ / C Code:
How does this work? Does my gcc automatically search everything in the libraries until it finds the matching function? Along with that, where are the functions? In a binary file? I usually find only the prototypes in the .h files. Just curious, Howard; |
|
#4
|
||||||
|
||||||
Re: Undefined reference to powQuote:
No. Quote:
So -lm means to link libm.a. libm is the math library, so gcc z.c -lm would link in all of the functions in libm that the program used. libm.a is the name of the library file that contains compiled code for the standard library math functions. Now you ask, "Why?" and I answer, "Because". Quote:
Prototypes are for keeping the compiler happy. Period. They have nothing to do with telling anything to the linker (like where or how that function's compile code can be located). Quote:
And what happens if you leave the prototypes off? For my versions of gcc (3.4.something and 4.something.anything), the compiler supplies "built-in" functions (and their prototypes), so it compiles and links perfectly even without the prototypes. All of this kind of behavior is implementation-dependent and is not part of the C standard. I do get warnings about "implicit declaration ..." of the functions. As a matter of fact it also works with Borland and Microsoft compilers that I tested today without the prototypes. So what? In other words, the C standard defines a certain number of header files and describes the standard library functions that are prototyped there, but it doesn't say what a compiler user has to do to get something compiled. (Most compiler vendors, obviously, just tell the user to#include <whatever.h> to get it compiled properly. Quote:
But (One More Time). The specifics of how a compiler finds header files and library files are necessarily implementation-dependent since the C standard is deliberately ignorant of all physical characteristics and system considerations such as the directory structure of the system where the programs are being compiled. [/quote] Quote:
The linker takes all object files created from your source file(s) and whatever library files are specified in order to link everything together into something that can be loaded and executed. Vendors supply "library" files that are compiled object files for whatever functions are in that library. For gcc compilers (Linux systems as well as Windows ports such as mingw and cygwin), the UNIX tradition of calling the files "something.a" is typical (but gcc can also create "dynamic-link library" files that are used like Windows .dll files). For "typical" Windows compilers (Microsoft, Borland) the library files are usually called "something.lib". Common Windows compilers actually put standard C library functions (like the math functions) into library files that are always searched, and for Borland and Microsoft compilers that I have used I don't know of any standard library functions that require a special linker switch to let the compiler find them. As I mentioned in my previous post, older versions of gcc followed the UNIX tradition of requiring a special switch to let the compiler know how to find math library functions. There is a good reason as to why older compilers did it that way, but it became less important in the late 20th century, and the guys at GNU decided to make it easier to use by distributing implementations that don't require any special switch for math functions. That is what you and I have observed. Note that my description of compiler and linker and the separate steps used to create an executable file from source files and library files are merely examples of how "usual" compilers work. None of this is part of any C language standard specification, but applies for compilers typically used by most of us. Regards, dave |
|
#5
|
|||
|
|||
Re: Undefined reference to powOK, I found libm.a . I understand more about that now.
libm.a is interesting, looks maybe like assembly? and shorter than I expected. Maybe it just provides some instructions to find the math stuff? I should just shut up rather than open another can of worms... I see that when I omit the prototypes as well I get 'implicit declarations' warnings on both printf() and pow() and it will run but on my mingw gcc printf(" (int)pow( 2, 4 ) = %d \n", (int)pow( 2, 4 ) ); prints: 4991 . If I place the pow() prototype again OR place the #includes <math.h>, it prints the proper: 16 curiosity again... if it doesn't error on pow() and auto-finds it, why would it not work properly... why ask why... different behaviors on different compilers ... Just expect wrong when I write it wrong and right when I write it right! right? And MOVE ON ! Thanks Dave, ++Howard; |
|
#6
|
|||
|
|||
Re: Undefined reference to powQuote:
The C standard accommodates legacy (pre-standards) code (that is, if the pre-standards stuff worked OK, then it still does). The fact that something compiles without errors doesn't mean that the code is correct. Some compilers try to "guess" whether a particular usage is problematic even though it is not strictly a violation of the rules of the language. (That's when we get "warning" messages instead of "error" messages.) Anyhow: If the compiler encounters a function invocation for a function that has not been previously declared (no prototype, no definition up to the point where the function is called), then the function is assumed to return an int. That is, the compiler creates code to handle an integer data type with whatever function return mechanism is implemented by that compiler. The code in the calling function expects an integer, but the code in the called function, pow(), returns a double. That does not compute. Now, for my gcc compilers (the cygwin port for Windows is, I guess, different from the mingw port), since they have a number of built-in functions, including pow(), it is possible that programs that use pow() will actually compile and execute properly without including <math.h> CPP / C++ / C Code:
Code:
Knowledge of built-in functions includes the prototype and how to link it. If I run that program through my version of gcc, it not only compiles and links correctly; it gives the correct answer. (I get warnings if I use gcc -Wall on the command line, but it still works in this case.) With my Borland compilers, I get warnings about missing prototypes, but the compiler creates an exe file. It gives the wrong answer when I run it. With Microsoft Visual C++ version 6 and Visual C++ version 2003 with default warning message settings: No warnings of any kind, and the wrong answer. Bottom line: Don't depend on the compiler to save you from erroneous code. There is no guarantee that the compiler will do the "right" thing if you do the "wrong" thing. There is no guarantee that the compiler will do the "wrong" thing if you do the "wrong" thing. The language allows you to create software with incredible numbers of bugs and doesn't whimper a bit. The whimpering that you hear is from unsatisfied users of buggy code. Regards, Dave Last edited by davekw7x : 29-Jul-2007 at 13:50.
|
|
#7
|
|||
|
|||
Re: Undefined reference to powHi again...
I've been off for a few days and that's why I didn't reply before. Quote:
I've tried Howard_L's simple function and my cygwin with gcc 3.4.4 in my Windows 2000 platform didn't require the -lm neither. Actually I found the problem for the first time in SUSE Linux 9, and then I checked it out in cygwin and I got an unespecified error, I thought that the -lm issue was the reason. Unfortunately I can not reproduce it, when I tried it today it just worked. About gcc 3.3.1 under SUSE Linux... I got "undefined reference to pow" if I compile it without -lm. Therefore this implementation is like the 3.2.2 commented by Dave. Thanks for your explanations Dave, I have a quite better understanding now. Pisuke |
Recent GIDBlog
Toyota - 2008 August Promotion by Nihal
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| linker error | unpep | FLTK Forum | 4 | 15-Apr-2007 03:03 |
| Coding DLLs with FLTK | n2liquid | FLTK Forum | 0 | 15-Apr-2007 02:57 |
| gnu.linkonce undefined reference | newbie06 | C++ Forum | 4 | 13-Mar-2007 09:53 |
| c++ inheritance | illbemissingu | C++ Forum | 14 | 23-Oct-2005 17:35 |
| fltk-2.0 cvs | Plumb | FLTK Forum | 20 | 13-Nov-2004 07:10 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The