library and #includes in code

E

Eigenvector

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?
 
J

Jack Klein

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 or
as to why they still do this.

Be prepared for a lack of sensible answers.
 
E

Eigenvector

<Wayyyyyy down at the bottom>

Jack Klein said:
It's not so much trivial, the problem is that it's an implementation
issue with your particular tool chain.


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.


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.


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.


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 or
as to why they still do this.

Be prepared for a lack of sensible answers.

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.
 
C

Chris Torek

to compile [some programs] you need to reference the math library
`cc math.c -lm -o math` [yet nothing extra is needed for other
[/QUOTE]
extensions like <unistd.h>]

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 or
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).
 
B

Bill Pursell

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.
 
K

Keith Thompson

Chris Torek said:
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.
 
J

jaysome

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
 
K

Keith Thompson

jaysome said:
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.
 
J

jaysome

jaysome said:
[...]
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.
 
K

Keith Thompson

jaysome said:
[...]
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
 
F

Flash Gordon

jaysome said:
jaysome said:
[...]
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.
 
J

Jack Klein

Jack Klein wrote, regarding the need to explicitly specify
libraries against which to link:

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,139
Latest member
JamaalCald
Top