GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 27-Jul-2007, 01:16
pisuke pisuke is offline
New Member
 
Join Date: May 2007
Posts: 19
pisuke is on a distinguished road

Undefined reference to pow


Hi 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  
Old 27-Jul-2007, 08:30
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,693
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: undefined reference to pow


Quote:
Originally Posted by pisuke
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.

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  
Old 27-Jul-2007, 21:55
Howard_L Howard_L is offline
Regular Member
 
Join Date: Apr 2007
Location: Maryland/PA, USA
Posts: 464
Howard_L has a spectacular aura aboutHoward_L has a spectacular aura about

Re: Undefined reference to pow


While 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:
 
/* #include <stdio.h> */
/* #include <math.h> */

int printf (const char*, ...);
double pow(double x, double y);    /* prototypes  only , no -lm, no #include */

int main(void)
{
  printf("  (int)pow(2, 4 ) = %d \n", (int)pow(2, 4 ) );
  return 0;
}
...and for printf too. I would assume that my gcc does the automatic linking. Also that Pisuke would also be able to compile this with the -lm in his non-automatic gcc.

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  
Old 28-Jul-2007, 08:29
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,693
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Undefined reference to pow


Quote:
Originally Posted by Howard_L
While your on the subject,
Dave, do you mean that compiling with -lm will link all libraries that begin with m ?

No.
Quote:
Originally Posted by davekw7x
the indication to use "libanything.a" is "-lanything"

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:
Originally Posted by Howard_L

In the link Pisuke provided, it was pointed out that the guy could compile successfully with a prototype and an -lm.
As my musician friends would say, "One more time..."

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:
Originally Posted by Howard_L
I found that I can compile ok with prototype alone and no -lm with my:
gcc version 3.3.1 (mingw special 20030804-1)...

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:
Originally Posted by Howard_L
Does my gcc automatically search everything in the libraries until it finds the matching function?
Well, I wouldn't know if it searches everything but it knows what to do with the function in the example. As I mentioned, there are a number of "built-in" functions in my versions of gcc that will be linked automatically even if you don't tell it where.

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:
Originally Posted by Howard_L

I usually find only the prototypes in the .h files.
That's because the header files are used by the compiler to find out what kind of functions they are. The return type. The number of arguments. The data type of each argument. Those are the only things the compiler needs to know in order to create an object file for that .c source file. The compiler has to know this in order to create the part of the code that deals with arguments and return values of functions invoked in a particular source file. The compiler (at compile time) of your example does not have to know anything about the internal workings of the function.

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  
Old 29-Jul-2007, 10:03
Howard_L Howard_L is offline
Regular Member
 
Join Date: Apr 2007
Location: Maryland/PA, USA
Posts: 464
Howard_L has a spectacular aura aboutHoward_L has a spectacular aura about

Re: Undefined reference to pow


OK, 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  
Old 29-Jul-2007, 12:55
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,693
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Undefined reference to pow


Quote:
Originally Posted by Howard_L

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
We spend most of our learning process trying to learn why things work (or at least how things work). I like your question because I think it is also important to try to understand why things don't work. Maybe even more important, since I spend a lot more time trying to figure out what the heck is going on when something doesn't work as expected than I spent writing the stuff in the first place.


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:
main()
{
    double x, y, z;
    x = 2.0;
    y = 3.0;
    z = pow(x, y);
    printf("z = %f\n", z);
}
Output from code compiled by gcc:
Code:
z = 8.000000

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  
Old 02-Aug-2007, 08:39
pisuke pisuke is offline
New Member
 
Join Date: May 2007
Posts: 19
pisuke is on a distinguished road

Re: Undefined reference to pow


Hi again...

I've been off for a few days and that's why I didn't reply before.

Quote:
Originally Posted by davekw7x
...so I don't know what there is about your cygwin installation that would cause the problem...

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 GIDBlogToyota - 2008 August Promotion by Nihal

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

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

All times are GMT -6. The time now is 19:58.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.