By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,411 Members | 1,030 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,411 IT Pros & Developers. It's quick & easy.

library and #includes in code

P: n/a
I apologize if this is a trivial question, but it's always made me wonder
when I have to compile my code.

There are some #includes that you don't really need to reference in your
library and header references in the compilation string.

For instance the standard hello.c

#include <stdio.h>
int main()
{
printf("hello world\n");
}

compiles as `cc hello.c -o hello`

Whereas something like this

#include <stdio.h>
#include <math.h>
int main()
{
int x;
x=pow(2,2);
printf("%d\n",x);
}

to compile this you need to reference the math library
`cc math.c -lm -o math`

However, in this 3rd example, I don't have to reference another header file,
even though it isn't ANSI C

#include <stdio.h>
#include <math.h>
#include <unistd.h>

int main()
{
.........................
.....................
.....................
}
Why do you not need to include the reference to the math library for the 2nd
case, but you don't need to reference the stdio header files or the UNIX
headers? More generally, assuming the -lm is a localized compiler
implementation, why would you not reference the math header files like you
would any other external library that you call within your code? If I
wanted to include my own proprietary header files I'd have to give the
compiler a full path, why is the math library different?
Jul 26 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a
On Tue, 25 Jul 2006 18:40:40 -0700, "Eigenvector"
<m4********@yahoo.comwrote in comp.lang.c:
I apologize if this is a trivial question, but it's always made me wonder
when I have to compile my code.
It's not so much trivial, the problem is that it's an implementation
issue with your particular tool chain.
There are some #includes that you don't really need to reference in your
library and header references in the compilation string.
The C standard defines a standard library. All functions, types,
macros, and external objects in the standard library are available to
any program that includes the proper standard headers or otherwise
contains proper declarations of them.

The C standard does not define how the results of translating your
source files and the necessary pieces of the standard library are
combined to produce an executable program, it just requires that a
conforming implementation provide some method of doing so.
For instance the standard hello.c

#include <stdio.h>
int main()
{
printf("hello world\n");
}

compiles as `cc hello.c -o hello`

Whereas something like this

#include <stdio.h>
#include <math.h>
int main()
{
int x;
x=pow(2,2);
printf("%d\n",x);
}

to compile this you need to reference the math library
`cc math.c -lm -o math`
It sounds like you are using a Linux/UNIX implementation, or perhaps a
version of gcc ported to another system. This is due to the ancient
UNIX guru conspiracy to keep newbies in the dark and properly
worshipful to the sys admins.

It is traditional on UNIX systems for the tool set to put part of the
C standard library in on file that is linked automatically, but to put
floating point functions in a separate library that has to be
specified directly. There is nothing in the C standard that requires
this.

Once upon a time, in the days when the library files were read from
punched paper tape (OK, not quite that), it might have made sense and
saved time building a program to leave some functions less commonly
used out of the standard link search. Any such savings that existed
30 plus years ago is no longer significant, and probably not even
noticeable, on today's platforms, given the speed of processors and
disk drives and the amount of physical memory.
However, in this 3rd example, I don't have to reference another header file,
even though it isn't ANSI C

#include <stdio.h>
#include <math.h>
#include <unistd.h>

int main()
{
........................
....................
....................
}
Again, this is a decision made by the implementers of your particular
tool chain, based on reasons that have been obsolete for the past 20
years. And there is no longer any good reason for it at all.

On the Windows platform, which never adopted this silly tradition,
typical native compilers such as Microsoft, Borland, lcc-win32, and
others, never need any special linker commands to use any part of the
standard library defined by the C language.
Why do you not need to include the reference to the math library for the 2nd
case, but you don't need to reference the stdio header files or the UNIX
headers? More generally, assuming the -lm is a localized compiler
implementation, why would you not reference the math header files like you
would any other external library that you call within your code? If I
wanted to include my own proprietary header files I'd have to give the
compiler a full path, why is the math library different?
Every single one of your questions in the final paragraph are
completely decisions made by the tool implementers. I'd suggest you
ask in one of the gcc groups or mailing lists why they still do this,
or perhaps on news:comp.unix.programmer or
news:comp.os.linux.development.apps, as to why they still do this.

Be prepared for a lack of sensible answers.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 26 '06 #2

P: n/a
<Wayyyyyy down at the bottom>

"Jack Klein" <ja*******@spamcop.netwrote in message
news:km********************************@4ax.com...
On Tue, 25 Jul 2006 18:40:40 -0700, "Eigenvector"
<m4********@yahoo.comwrote in comp.lang.c:
>I apologize if this is a trivial question, but it's always made me wonder
when I have to compile my code.

It's not so much trivial, the problem is that it's an implementation
issue with your particular tool chain.
>There are some #includes that you don't really need to reference in your
library and header references in the compilation string.

The C standard defines a standard library. All functions, types,
macros, and external objects in the standard library are available to
any program that includes the proper standard headers or otherwise
contains proper declarations of them.

The C standard does not define how the results of translating your
source files and the necessary pieces of the standard library are
combined to produce an executable program, it just requires that a
conforming implementation provide some method of doing so.
>For instance the standard hello.c

#include <stdio.h>
int main()
{
printf("hello world\n");
}

compiles as `cc hello.c -o hello`

Whereas something like this

#include <stdio.h>
#include <math.h>
int main()
{
int x;
x=pow(2,2);
printf("%d\n",x);
}

to compile this you need to reference the math library
`cc math.c -lm -o math`

It sounds like you are using a Linux/UNIX implementation, or perhaps a
version of gcc ported to another system. This is due to the ancient
UNIX guru conspiracy to keep newbies in the dark and properly
worshipful to the sys admins.

It is traditional on UNIX systems for the tool set to put part of the
C standard library in on file that is linked automatically, but to put
floating point functions in a separate library that has to be
specified directly. There is nothing in the C standard that requires
this.

Once upon a time, in the days when the library files were read from
punched paper tape (OK, not quite that), it might have made sense and
saved time building a program to leave some functions less commonly
used out of the standard link search. Any such savings that existed
30 plus years ago is no longer significant, and probably not even
noticeable, on today's platforms, given the speed of processors and
disk drives and the amount of physical memory.
>However, in this 3rd example, I don't have to reference another header
file,
even though it isn't ANSI C

#include <stdio.h>
#include <math.h>
#include <unistd.h>

int main()
{
........................
....................
....................
}

Again, this is a decision made by the implementers of your particular
tool chain, based on reasons that have been obsolete for the past 20
years. And there is no longer any good reason for it at all.

On the Windows platform, which never adopted this silly tradition,
typical native compilers such as Microsoft, Borland, lcc-win32, and
others, never need any special linker commands to use any part of the
standard library defined by the C language.
>Why do you not need to include the reference to the math library for the
2nd
case, but you don't need to reference the stdio header files or the UNIX
headers? More generally, assuming the -lm is a localized compiler
implementation, why would you not reference the math header files like
you
would any other external library that you call within your code? If I
wanted to include my own proprietary header files I'd have to give the
compiler a full path, why is the math library different?

Every single one of your questions in the final paragraph are
completely decisions made by the tool implementers. I'd suggest you
ask in one of the gcc groups or mailing lists why they still do this,
or perhaps on news:comp.unix.programmer or
news:comp.os.linux.development.apps, as to why they still do this.

Be prepared for a lack of sensible answers.

--
Jack Klein
I think I understand given your examples. It makes sense to have HAD the
math libraries available but only upon request in order to shrink the memory
size of the executable being called. I hadn't thought of it in those terms
until you made your observation.

I don't think the -lm flag is totally universal anymore, but you never know,
FEA coders are pretty damn conservative. Probably one of the reasons why
I'm still having to scrounge up F77 compilers for my Linux clusters because
the programmers still think Fortran is faster than C when it comes to
mathematical operations and scalability. But I don't want to start a war on
that topic, because I'm not sure a proper benchmark has ever been done
against Fortran 77 and C modern using the same FEA code.
Jul 26 '06 #3

P: n/a
>On Tue, 25 Jul 2006 18:40:40 -0700, "Eigenvector"
><m4********@yahoo.comwrote in comp.lang.c:
>to compile [some programs] you need to reference the math library
`cc math.c -lm -o math` [yet nothing extra is needed for other
extensions like <unistd.h>]

In article <km********************************@4ax.com>,
Jack Klein <ja*******@spamcop.netwrote:
>It sounds like you are using a Linux/UNIX implementation, or perhaps a
version of gcc ported to another system. This is due to the ancient
UNIX guru conspiracy to keep newbies in the dark and properly
worshipful to the sys admins.
Or just plain stubbornness. :-)
>It is traditional on UNIX systems for the tool set to put part of the
C standard library in on file that is linked automatically, but to put
floating point functions in a separate library that has to be
specified directly. There is nothing in the C standard that requires
this.
On the other hand, there *is* stuff in the C standard that requires
an ANSI/ISO C compiler to compile code like:

int asm;
char *typeof;

which will fail when you just use "cc" on those systems.

The trick here is that "cc" is *not* the ANSI/ISO C compiler! It
is the "not-quite-C-Compiler". These systems should (but usually
do not) come with a command spelled something like "acc" or "isocc"
or, perhaps best, just "c89", which invokes the actual C compiler.

The "c89" command not only compiles C code, but automatically adds
"-lm" whenever needed. Ideally:

c89 ./foo.c

produces ./foo (not ./a.out), and handles code that uses pow() and
log() and so on, and correctly accepts code that uses "asm" and
"typeof" as ordinary identifiers, and correctly diagnoses code that
uses nonstandard extensions (those that require diagnostics anyway).
>Every single one of your questions in the final paragraph are
completely decisions made by the tool implementers. I'd suggest you
ask in one of the gcc groups or mailing lists why they still do this,
or perhaps on news:comp.unix.programmer or
news:comp.os.linux.development.apps, as to why they still do this.

Be prepared for a lack of sensible answers.
Or, if you are lucky, you may actually get a "c89" command. Failing
that, you can use "cc -ansi -pedantic file.c -o file -lm" every
time (although I would suggest adding more -W options, and at
least -O1 if not -O2).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jul 26 '06 #4

P: n/a
Jack Klein wrote, regarding the need to explicitly specify
libraries against which to link:
>
Once upon a time, in the days when the library files were read from
punched paper tape (OK, not quite that), it might have made sense and
saved time building a program to leave some functions less commonly
used out of the standard link search. Any such savings that existed
30 plus years ago is no longer significant, and probably not even
noticeable, on today's platforms, given the speed of processors and
disk drives and the amount of physical memory.
Isn't there also an issue of namespace clutter? ie, by not linking
against everything, I have the freedom to build library foo that
includes a function that has the same name as library bar,
and I simply select which library to use at link time. I
thought that was the primary reason for having this, actually.

--
Bill Pursell

Jul 26 '06 #5

P: n/a
Chris Torek <no****@torek.netwrites:
[...]
The "c89" command not only compiles C code, but automatically adds
"-lm" whenever needed. Ideally:

c89 ./foo.c

produces ./foo (not ./a.out), and handles code that uses pow() and
log() and so on, and correctly accepts code that uses "asm" and
"typeof" as ordinary identifiers, and correctly diagnoses code that
uses nonstandard extensions (those that require diagnostics anyway).
Ideally, yes, but not necessarily.

On Solaris 9, the "c89" command (/opt/SUNWspro/bin/c89) gives me:

Undefined first referenced
symbol in file
sqrt tmp.o
ld: fatal: Symbol referencing errors. No output written to tmp

Adding "-lm" makess it work.

Recent versions of gcc seem to do the "-lm" implicitly.

Of course none of this violates the C standard. It just means that
"c89 tmp.c" is not a conforming C89 compiler, but "c89 tmp.c -lm" is.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 26 '06 #6

P: n/a
On Wed, 26 Jul 2006 21:48:15 GMT, Keith Thompson <ks***@mib.org>
wrote:
>Chris Torek <no****@torek.netwrites:
[...]
>The "c89" command not only compiles C code, but automatically adds
"-lm" whenever needed. Ideally:

c89 ./foo.c

produces ./foo (not ./a.out), and handles code that uses pow() and
log() and so on, and correctly accepts code that uses "asm" and
"typeof" as ordinary identifiers, and correctly diagnoses code that
uses nonstandard extensions (those that require diagnostics anyway).

Ideally, yes, but not necessarily.

On Solaris 9, the "c89" command (/opt/SUNWspro/bin/c89) gives me:

Undefined first referenced
symbol in file
sqrt tmp.o
ld: fatal: Symbol referencing errors. No output written to tmp

Adding "-lm" makess it work.

Recent versions of gcc seem to do the "-lm" implicitly.

Of course none of this violates the C standard. It just means that
"c89 tmp.c" is not a conforming C89 compiler, but "c89 tmp.c -lm" is.
If "none of this" violates the C standard, then how can "one of this"
not be a conforming C89 compiler? Doesn't "violate" imply "not
conforming"?

regards
--
jay
Jul 27 '06 #7

P: n/a
jaysome <ja*****@spamcop.netwrites:
On Wed, 26 Jul 2006 21:48:15 GMT, Keith Thompson <ks***@mib.org>
wrote:
>>Chris Torek <no****@torek.netwrites:
[...]
>>The "c89" command not only compiles C code, but automatically adds
"-lm" whenever needed. Ideally:

c89 ./foo.c

produces ./foo (not ./a.out), and handles code that uses pow() and
log() and so on, and correctly accepts code that uses "asm" and
"typeof" as ordinary identifiers, and correctly diagnoses code that
uses nonstandard extensions (those that require diagnostics anyway).

Ideally, yes, but not necessarily.

On Solaris 9, the "c89" command (/opt/SUNWspro/bin/c89) gives me:

Undefined first referenced
symbol in file
sqrt tmp.o
ld: fatal: Symbol referencing errors. No output written to tmp

Adding "-lm" makess it work.

Recent versions of gcc seem to do the "-lm" implicitly.

Of course none of this violates the C standard. It just means that
"c89 tmp.c" is not a conforming C89 compiler, but "c89 tmp.c -lm" is.

If "none of this" violates the C standard, then how can "one of this"
not be a conforming C89 compiler? Doesn't "violate" imply "not
conforming"?
Sorry, I wasn't entirely clear.

A conforming compiler doesn't have to be conforming *by default*. If
"cc tmp.c" isn't conforming and "cc tmp.c -lm" is conforming, then
that's ok. In effect, they're two different implementations, one
conforming and one not.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 27 '06 #8

P: n/a
On Thu, 27 Jul 2006 09:50:48 GMT, Keith Thompson <ks***@mib.org>
wrote:
>jaysome <ja*****@spamcop.netwrites:
>On Wed, 26 Jul 2006 21:48:15 GMT, Keith Thompson <ks***@mib.org>
wrote:
>>>Chris Torek <no****@torek.netwrites:
[...]
The "c89" command not only compiles C code, but automatically adds
"-lm" whenever needed. Ideally:

c89 ./foo.c

produces ./foo (not ./a.out), and handles code that uses pow() and
log() and so on, and correctly accepts code that uses "asm" and
"typeof" as ordinary identifiers, and correctly diagnoses code that
uses nonstandard extensions (those that require diagnostics anyway).

Ideally, yes, but not necessarily.

On Solaris 9, the "c89" command (/opt/SUNWspro/bin/c89) gives me:

Undefined first referenced
symbol in file
sqrt tmp.o
ld: fatal: Symbol referencing errors. No output written to tmp

Adding "-lm" makess it work.

Recent versions of gcc seem to do the "-lm" implicitly.

Of course none of this violates the C standard. It just means that
"c89 tmp.c" is not a conforming C89 compiler, but "c89 tmp.c -lm" is.

If "none of this" violates the C standard, then how can "one of this"
not be a conforming C89 compiler? Doesn't "violate" imply "not
conforming"?

Sorry, I wasn't entirely clear.

A conforming compiler doesn't have to be conforming *by default*. If
"cc tmp.c" isn't conforming and "cc tmp.c -lm" is conforming, then
that's ok. In effect, they're two different implementations, one
conforming and one not.
How can a linker option affect the conformity of a C implementation? I
would think that in your example the conforming C89 compiler part
should stop with the "-c" option.

# gcc ${C89_OPTIONS} -c tmp.c
#

# gcc ${C89_OPTIONS} -c tmp.c -lm
# gcc: -lm: linker input file unused because linking not done

Maybe I'm missing something.
--
jay

Jul 27 '06 #9

P: n/a
jaysome <ja*****@spamcop.netwrites:
On Thu, 27 Jul 2006 09:50:48 GMT, Keith Thompson <ks***@mib.org>
wrote:
[...]
>>A conforming compiler doesn't have to be conforming *by default*. If
"cc tmp.c" isn't conforming and "cc tmp.c -lm" is conforming, then
that's ok. In effect, they're two different implementations, one
conforming and one not.

How can a linker option affect the conformity of a C implementation?
In this case, by linking the math library.
I would think that in your example the conforming C89 compiler part
should stop with the "-c" option.
The compiler, yes, but not the implementation.

C99 3.12:

implementation

particular set of software, running in a particular translation
environment under particular control options, that performs
translation of programs for, and supports execution of functions
in, a particular execution environment

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 27 '06 #10

P: n/a
jaysome wrote:
On Thu, 27 Jul 2006 09:50:48 GMT, Keith Thompson <ks***@mib.org>
wrote:
>jaysome <ja*****@spamcop.netwrites:
>>On Wed, 26 Jul 2006 21:48:15 GMT, Keith Thompson <ks***@mib.org>
wrote:
Chris Torek <no****@torek.netwrites:
[...]
The "c89" command not only compiles C code, but automatically adds
"-lm" whenever needed. Ideally:
>
c89 ./foo.c
>
produces ./foo (not ./a.out), and handles code that uses pow() and
log() and so on, and correctly accepts code that uses "asm" and
"typeof" as ordinary identifiers, and correctly diagnoses code that
uses nonstandard extensions (those that require diagnostics anyway).
Ideally, yes, but not necessarily.

On Solaris 9, the "c89" command (/opt/SUNWspro/bin/c89) gives me:

Undefined first referenced
symbol in file
sqrt tmp.o
ld: fatal: Symbol referencing errors. No output written to tmp

Adding "-lm" makess it work.

Recent versions of gcc seem to do the "-lm" implicitly.

Of course none of this violates the C standard. It just means that
"c89 tmp.c" is not a conforming C89 compiler, but "c89 tmp.c -lm" is.
If "none of this" violates the C standard, then how can "one of this"
not be a conforming C89 compiler? Doesn't "violate" imply "not
conforming"?
Sorry, I wasn't entirely clear.

A conforming compiler doesn't have to be conforming *by default*. If
"cc tmp.c" isn't conforming and "cc tmp.c -lm" is conforming, then
that's ok. In effect, they're two different implementations, one
conforming and one not.

How can a linker option affect the conformity of a C implementation?
You are missing something. The linker, the library and anything else
required are also part of the implementation. That is why we refer to
implementations rather than compilers.
I
would think that in your example the conforming C89 compiler part
should stop with the "-c" option.

# gcc ${C89_OPTIONS} -c tmp.c
#

# gcc ${C89_OPTIONS} -c tmp.c -lm
# gcc: -lm: linker input file unused because linking not done

Maybe I'm missing something.
Yes, see above. You are only looking at part of the implementation, not
a full implementation.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Jul 27 '06 #11

P: n/a
On 26 Jul 2006 14:24:04 -0700, "Bill Pursell" <bi**********@gmail.com>
wrote in comp.lang.c:
Jack Klein wrote, regarding the need to explicitly specify
libraries against which to link:

Once upon a time, in the days when the library files were read from
punched paper tape (OK, not quite that), it might have made sense and
saved time building a program to leave some functions less commonly
used out of the standard link search. Any such savings that existed
30 plus years ago is no longer significant, and probably not even
noticeable, on today's platforms, given the speed of processors and
disk drives and the amount of physical memory.

Isn't there also an issue of namespace clutter? ie, by not linking
against everything, I have the freedom to build library foo that
includes a function that has the same name as library bar,
and I simply select which library to use at link time. I
thought that was the primary reason for having this, actually.
When you are talking about third party libraries, yes indeed that is
find and dandy, and on most tool chains these add-on libraries need to
be specified directly.

But we are talking about parts of the standard C library, basically
the parts that are prototyped in <math.h>. As far as C is concerned,
if you name a function the same as any of the standard functions in
<math.h>, you produce undefined behavior no matter what else you do.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 27 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.