C-FAQ 14.3

B

Billy Mays

http://c-faq.com/fp/libm.html

The answer to question 14.3 suggests linking against libm, "due to a
longstanding bug in Unix and Linux systems". Is there any elaboration
on what the bug is or where it came from? Is this solution portable?
 
E

Eric Sosman

http://c-faq.com/fp/libm.html

The answer to question 14.3 suggests linking against libm, "due to a
longstanding bug in Unix and Linux systems". Is there any elaboration on
what the bug is or where it came from? Is this solution portable?

The FAQ author evidently considers it a "bug" that the <math.h>
functions are only available if an extra command-line argument is
used. However:

- Since the Standard does not specify what the command line should
look like, this "bug" in no way violates the Standard. The need
to begin the command line with "cc" or "gcc" or whatever is just
as much a "bug" as the need to end it with "-lm".

- Although the earliest Unix systems required "-lm" and I think
some still may today, at least some Unix systems do not.

As to portability: "-lm" will work on all Unixoid systems I know
of (even those where it's not needed). I don't know what Microsoft's
compilers might need, I no longer remember what VMS uses (it wasn't
"-lm", that's for sure), and I've never compiled C on an IBM mainframe.
It's "partially portable," at the very least -- but since the entire
command line is platform-dependent, there's bound to be some variation.
 
K

Keith Thompson

Billy Mays said:
http://c-faq.com/fp/libm.html

The answer to question 14.3 suggests linking against libm, "due to a
longstanding bug in Unix and Linux systems". Is there any elaboration
on what the bug is or where it came from? Is this solution portable?

The nature of the "bug" is that Unix compilers typically do not
load the math library by default, even if the program calls math
functions.

The C standard library is typically implemented in one or more
separate system libraries; the nature of the system libraries is
entirely implementation-defined. When you link your program, the
linker has to know which libraries to search to resolve function
calls in your program. Most of the C standard library is usually
in the set of system libraries that are searched by default, so
you don't need to specify them.

The choice of which system libraries to search by default, and
which to require the user to ask for, is largely an arbitrary one.
Since C is (perceived as) primarily a systems programming language,
and system-level programs typically don't need math functions, the
choice was made several decades ago *not* to load the system math
library unless the user specifically asks for it. This was not an
unreasonable decision at the time, when computers were slower and
searching the math library on every link operation could have been
a significant burden.

I put the word "bug" in quotation marks above because this was a
deliberate decision, not a mistake. But the majority opinion these
days seems to be that it should be changed. Implicitly searching
the math library should be relatively harmless; the extra time is
minimal, and if no math functions are actually called the library
won't actually be loaded (this may not have been the case for early
Unix linkers).

On the other hand, most C compilations are not done manually on the
command line, but are automated via Makefiles or something similar.
If Makefiles are to be somewhat portable, they'll have to specify
"-lm" explicitly, until all C implementations have "fixed" the
"bug". Most of them, for whatever reason, have shown little
interest in doing so, so we'll be stuck with the explicit "-lm"
for a long time to come.

As for whether it's portable: No. Using "-lm" is likely to be
portable to most or all Unix-like environments, including the various
flavors of Unix, Linux, Cygwin, and whatever other Unix-like things
are out there. Non-Unix-like systems are likely to have an entirely
different syntax for invoking the compiler and/or linker.

The C standard itself has nothing to say on the issue; it's (almost?)
entirely silent on the way in which a C compiler and/or linker is
invoked.
 
E

Ersek, Laszlo

http://c-faq.com/fp/libm.html

The answer to question 14.3 suggests linking against libm, "due to a
longstanding bug in Unix and Linux systems". Is there any elaboration on
what the bug is or where it came from? Is this solution portable?

That is no bug in UNIX(R). The ISO C Standard very probably doesn't
specify how you should build an executable from a C program (or what an
"executable" is to begin with). One needs to consult the implementation's
documentation.

The Single UNIX(R) Specification defines, for a family of implementations,
how C programs are built.

http://www.opengroup.org/onlinepubs/007908775/xcu/c89.html
http://www.opengroup.org/onlinepubs/000095399/utilities/c99.html
http://www.opengroup.org/onlinepubs/9699919799/utilities/c99.html

Look for "-l m", and also the parts which describe the order of options
and operands.

The solution is portable across UNIX(R) certified systems. Additionally,
it should work on any non-certified system that nonetheless aims at
POSIX(R) or UNIX(R) conformance, like GNU/Linux, FreeBSD, etc.

lacos
 
B

Billy Mays

I put the word "bug" in quotation marks above because this was a
deliberate decision, not a mistake. But the majority opinion these
days seems to be that it should be changed. Implicitly searching
the math library should be relatively harmless; the extra time is
minimal, and if no math functions are actually called the library
won't actually be loaded (this may not have been the case for early
Unix linkers).
[...]


The reason I ask is that I am wary about linking against lots of
libraries. I know that add just 1 extra library isn't excessively
dangerous, but it just means 1 more potential place for bugs. It also
seems a little unusual to have the "Standard Library" as two disjoint
libraries.

For my the program that spawn my question, I am making numerous calls to
the math.h functions. I fear that the compiler wouldn't be able to make
some optimizations it would have otherwise been able to had the math
functions been directly compiled in. However, this problems might still
have occurred had the math.h functions been rolled directly into libc
anyways so meh.

Is it possible / a good idea to statically compile in the math library
into program for execution speed related reasons?
 
E

Eric Sosman

I put the word "bug" in quotation marks above because this was a
deliberate decision, not a mistake. But the majority opinion these
days seems to be that it should be changed. Implicitly searching
the math library should be relatively harmless; the extra time is
minimal, and if no math functions are actually called the library
won't actually be loaded (this may not have been the case for early
Unix linkers).
[...]


The reason I ask is that I am wary about linking against lots of
libraries. I know that add just 1 extra library isn't excessively
dangerous, but it just means 1 more potential place for bugs. It also
seems a little unusual to have the "Standard Library" as two disjoint
libraries.

For my the program that spawn my question, I am making numerous calls to
the math.h functions. I fear that the compiler wouldn't be able to make
some optimizations it would have otherwise been able to had the math
functions been directly compiled in. However, this problems might still
have occurred had the math.h functions been rolled directly into libc
anyways so meh.

Is it possible / a good idea to statically compile in the math library
into program for execution speed related reasons?

It may or may not be possible. It's certainly possible on some
systems, impossible (or extremely difficult) on others.

As for execution speed -- well, again, the answer will vary from
platform to platform. On many platforms there is in fact a speed
penalty for calling things in "shared libraries," but the platform
vendors have a lot of incentive to keep the penalty as small as they
can manage. Meanwhile, the ability to have forty programs share a
single copy of a library instead of filling memory with forty different
copies (even partial copies) may make the whole system faster by keeping
page fault rates lower. It'd be awfully hard to make a really good
measurement -- and the results might come out differently tomorrow.

Finally: If you've linked against a shared library and the vendor
replaces it with a speeded-up or more accurate or otherwise "better"
version, you get the improvement[*] without lifting a finger. But if
you've copied and pasted the old library's source code into your own
program, you don't get the benefit until you re-copy and re-build --
and don't forget to count the re-building time in your computation
of "How fast is it?"

[*] Very occasionally, a program simply must have version so-and-so
of some library, and not anything more modern. But even with shared
libraries, most vendors have ways to accommodate such oddball needs --
and in any case, a decision made on these grounds would not be for
"speed related reasons."
 
N

Nobody

Since C is (perceived as) primarily a systems programming language,
and system-level programs typically don't need math functions, the
choice was made several decades ago *not* to load the system math
library unless the user specifically asks for it. This was not an
unreasonable decision at the time, when computers were slower and
searching the math library on every link operation could have been
a significant burden.

ISTR the issue was that, on some systems, simply linking in the math
library would "enable" floating point for the program, requiring the FPU
state to be saved and restored on each context switch, which incurred a
significant performance penalty.
I put the word "bug" in quotation marks above because this was a
deliberate decision, not a mistake. But the majority opinion these
days seems to be that it should be changed.

Personally, I haven't seen any evidence of this "majority opinion".
Implicitly searching
the math library should be relatively harmless; the extra time is
minimal, and if no math functions are actually called the library
won't actually be loaded (this may not have been the case for early
Unix linkers).

And isn't the case for modern ones. Typically, linking against a *static*
library only links in object files which are required to satisfy an
unresolved reference, but linking against a *dynamic* library will cause
that library to always be loaded at run-time, regardless of whether or not
it is actually required.

This behaviour is necessary to deal with issues such as constructors and
destructors (functions executed during initialisation and termination
without an explicit call), the fact that exactly which dynamic libraries
will be loaded at run-time isn't known at link-time, weak symbols (which
can be overriden by other libraries), etc.
 
K

Keith Thompson

Nobody said:
ISTR the issue was that, on some systems, simply linking in the math
library would "enable" floating point for the program, requiring the FPU
state to be saved and restored on each context switch, which incurred a
significant performance penalty.

I've seen references to some system (I don't remember which) where a
program that called printf with a floating-point argument would fail
unless you added some workaround, because printf itself wouldn't load
the floating-point something-or-other. (Is that vague enough?)
Personally, I haven't seen any evidence of this "majority opinion".

Most of the people who've expressed an opinion on the topic here have
said it would be better if the "-lm" weren't required. Of course I
haven't done a formal survey of any short.
And isn't the case for modern ones. Typically, linking against a *static*
library only links in object files which are required to satisfy an
unresolved reference, but linking against a *dynamic* library will cause
that library to always be loaded at run-time, regardless of whether or not
it is actually required.

I sit corrected, thank you.

[...]
 
E

Eric Sosman

I've seen references to some system (I don't remember which) where a
program that called printf with a floating-point argument would fail
unless you added some workaround, because printf itself wouldn't load
the floating-point something-or-other. (Is that vague enough?)

FAQ 14.13.
 
S

Sjouke Burry

Keith said:
I've seen references to some system (I don't remember which) where a
program that called printf with a floating-point argument would fail
unless you added some workaround, because printf itself wouldn't load
the floating-point something-or-other. (Is that vague enough?)
Old compilers from M$ did that, you had to add something like
x=x+.2;
to make it load the math and make a proper print statement.
 
N

Nobody

[-lm]

Personally, I haven't seen any evidence of this "majority opinion".

I have. You have to look long and hard to find a -lm supporter, but you
can't chuck a brick in clc without hitting half a dozen people who think
the math library should be linked in by default.

Ah; that may be the case on clc. On Linux/gcc/glibc fora, there seems to
be more support for libm being separate.

Much of the opposition to -lm seems to come from novices, as it's often
the first "extra" library which they encounter. Once you progress to
"real" programming and start having to deal with autoconf, pkg-conf and
the like, it becomes harder to view the -lm issue as even worth
discussing, let alone changing.
 
N

Nick Keighley

Nobody wrote:


Sure, but it [math.h] shouldn't /be/ an extra library. It's part of C,
not some
optional adjunct. It's a great shame that GNU C should get this so
wrong, when Borland and even Microsoft manage to get it right.
Once you progress to
"real" programming and start having to deal with autoconf, pkg-conf and
the like, it becomes harder to view the -lm issue as even worth
discussing, let alone changing.

That's pretty much the same attitude that makes Firefox so unusable.

just curious what's hard to use about Firefox? I must admit I tried it
didn't get on with it but I couldn't really say what I didn't like
about it.
 
F

FredK

Bob Doherty said:
VMS didn't need to link an additional library, the math routines were
in the common SYS$LIBRARY as MTH$xxxxxx routines, which is what were
called by stubs in the C run time library IIRC.

The rest of the command line stuff for VMS would be completely unlike
most other impementations.

There is nothing special needed on the command line to use any of the
routines that require <math.h>. The command line can however specify
defaults for various things like IEEE vs VAX FP as well as the precision for
float.
 
N

Nick

Richard Heathfield said:
Nick Keighley wrote:


Left running for long enough, it takes up approximately half your
physical memory, without apparent regard for need. Under some
circumstances, it can take up well over 90% of your clocks, too, for
long periods of time. I don't know what kind of person considers that
kind of performance to be acceptable, but it isn't the kind of person
whose opinion I respect a great deal.

It does it your memory. Well it eats mine. It seems that it doesn't do
this for everyone. But of the browsers I've got available it still wins
as my general purpose and development one: the features and add-ons more
than pay for the need to shut it down every day or two.
 
N

Nick

William Ahern said:
On shutdown Firefox sometimes hits 100% cpu. The longer it has been running
the longer it takes to shutdown. I suspect it's dutifully destroying all its
internal state as a, perhaps, debug measure. That's something comp.lang.c
regulars should be able to respect, if that's indeed the case.

I very nearly posted something to that effect in the discussion a couple
of months ago about whether you should dutifully and recursively walk
all your linked lists and trees, freeing every node, at program
termination; or whether you should just quit and leave it to the OS.
Firefox certainly seems to be doing the former.
 
E

Ersek, Laszlo

Nick Keighley wrote:


Left running for long enough,

Why?

The faster my browser forgets, the better. I don't *suspect* I'm being
spied after, I *know* I am, like every other WWW user. I do employ
adblock, but I don't try to convince myself that it catches everything
(web bugs, analytics links, tracking cookies, access to my browsing
history [0] etc). I also avoided setting up Privoxy, because I'm afraid it
would only give me a false sense of privacy. These tools need constant
tuning.

I do exert bursts of browsing activity, where history and cookies et al
are useful, and I do have 30-40 tabs open at times (just as I have xterms
in the tens). This happens especially when I'm researching something
focused, and it's sometimes quicker to open a new tab/xterm than to tab
across the existing ones. But then comes the great scythe. If something is
worth stashing away, I bookmark it (and remove session id's and the like
from the URL), or search for it later [2].

(If somebody is thinking now "I have nothing to hide": think again [1].)

lacos
[0] http://whattheinternetknowsaboutyou.com/
[1] http://www.schneier.com/blog/archives/2006/05/the_value_of_pr.html
[2] https://ssl.scroogle.org/
 
N

Nobody

On shutdown Firefox sometimes hits 100% cpu. The longer it has been
running the longer it takes to shutdown. I suspect it's dutifully
destroying all its internal state as a, perhaps, debug measure. That's
something comp.lang.c regulars should be able to respect, if that's indeed
the case.

I suspect that it's less likely to be a debug measure and more just an
inevitability given the complexity of the program (coupled with the fact
that much of Firefox written in C++ and JavaScript, where destructors get
called automatically).

E.g. I suspect that closing a window involves the same sequence of steps
regardless of whether or not you're quitting the application. And it
probably isn't feasible to make quitting a special case, especially if
there's a possibility that the user will be permitted to cancel the
shutdown at any point.
 
U

Uno

Richard said:
Nobody said:
On Fri, 16 Jul 2010 12:53:34 -0700, Keith Thompson wrote:
[-lm]
I put the word "bug" in quotation marks above because this was a
deliberate decision, not a mistake. But the majority opinion these
days seems to be that it should be changed.

If there's no definition of atan, then the program that calls it is just
plain broken.
I have. You have to look long and hard to find a -lm supporter, but you
can't chuck a brick in clc without hitting half a dozen people who think
the math library should be linked in by default.

And what a serious gotcha it is. You're sitting there on this beautiful
platform that makes programming so much more effective and your
implementation decided that by writing
#include <math.h>
, you were just kidding.

And so it makes another one of those cases where you have to ask
someone, "why isn't this basic thing working," leaving you open to the
usual replies
1) why don't you first man man (there's a guy in alt.os.linux.ubuntu who
says this as 50% of his forum contribution. The other 50 is to
denigrate those who don't like being told to man man anymore.)
2) JFGI (just fucking google what? if I knew what to google for, I'd
understand more than I do.)
3) "Can't you read your own error messages. You're missing what's right
in front of your face." --(that's a seebs classic)
4) Read the fucking manual (Gordon Sande yelling at the paperboy.)
5) See faq 14.*, but we can't really talk about faq 14.*. (clc Topic
worship)

// end rant

I'm glad that OP brought up this non standard, implementation specific
question.
 

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

Forum statistics

Threads
474,262
Messages
2,571,046
Members
48,769
Latest member
Clifft

Latest Threads

Top