Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GCC default includes and math.h?

17 views
Skip to first unread message

John

unread,
Apr 29, 2010, 1:08:56 PM4/29/10
to
I'm curious about the behavior of gcc and what includes are considered
default.
gcc version 3.4.6 20060404 (Red Hat 3.4.6-11)

It seems math.h is being included by default but I still need to use -
lm when linking.
Is this behavior normal, and can it be configured?

The code below compiles just fine with gcc -lm mathtest.c I'm not
including stdio.h, or math.h.
I do need the -lm or I get undefined reference from the linker

main()
{
printf("exp(3.3) %f \n", exp(3.3));
printf("2^5 %f \n", pow(2,5));
}
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

Jens Schmidt

unread,
Apr 29, 2010, 7:43:51 PM4/29/10
to
John wrote:

> I'm curious about the behavior of gcc and what includes are considered
> default.
> gcc version 3.4.6 20060404 (Red Hat 3.4.6-11)

Here the language C is discussed, not various implementations of it. To
be sure that your program works as designed and continues to do so with
the next version, follow the documentation.

But anyway:

3.4.6 is a quite old version.

> It seems math.h is being included by default but I still need to use -
> lm when linking.

It only seems to be included. Actually, my gcc has internal definitions
for a number of functions, including printf, exp, and pow.

My gcc (version 4.4.1) says when compiling without any options:
try.c: In function ‘main’:
try.c:3: warning: incompatible implicit declaration of built-in function ‘printf’
try.c:3: warning: incompatible implicit declaration of built-in function ‘exp’
try.c:4: warning: incompatible implicit declaration of built-in function ‘pow’

And it does not even need -lm.

> Is this behavior normal, and can it be configured?

It is not normal, but probably usual for such an old version. Configure
by using options:
-Wall -std=c99 -pedantic

> The code below compiles just fine with gcc -lm mathtest.c I'm not
> including stdio.h, or math.h.
> I do need the -lm or I get undefined reference from the linker
>
> main()
> {
> printf("exp(3.3) %f \n", exp(3.3));
> printf("2^5 %f \n", pow(2,5));
> }

When I add the option -fno-builtins I do need -lm also, but now get
completely wrong results (always 0.0) when running the program.
Adding #include for stdio.h and math.h gives back the correct values.

So again: follow the documentation.
--
Greetings,
Jens Schmidt

Keith Thompson

unread,
Apr 29, 2010, 7:44:21 PM4/29/10
to
John <joh...@gmail.com> writes:
> I'm curious about the behavior of gcc and what includes are considered
> default.
> gcc version 3.4.6 20060404 (Red Hat 3.4.6-11)
>
> It seems math.h is being included by default but I still need to use -
> lm when linking.
> Is this behavior normal, and can it be configured?
>
> The code below compiles just fine with gcc -lm mathtest.c I'm not
> including stdio.h, or math.h.
> I do need the -lm or I get undefined reference from the linker
>
> main()
> {
> printf("exp(3.3) %f \n", exp(3.3));
> printf("2^5 %f \n", pow(2,5));
> }

No, <math.h> is not included by default; neither is <stdio.h>, or any
other header.

Under C90 rules, it's legal to call a function with no visible
declaration; such a function is implicitly assumed to take arguments of
whatever (promoted) types are used in the call, and to return a result
of type int. Since exp doesn't return an int, the program's behavior is
undefined. What's probably happening here is the following:

The compiler sees a call exp(3.3). It assumes a declaration of:
int exp(double);

So the generated code treats the actual double value returned by
exp() as if it were int value, which it then passes to printf().
printf(), because of the "%f" format, treats the int value passed
to it as if it were of type double. If int and double are of
different sizes (which they typically are), this can result in
garbage being printed. When I compiled and ran your program, it
printed "exp(3.3) 27.112639", which is "correct". Either the calling
conventions accidentally hid the error, or the compiler is somehow
taking advantage of its own knowledge of how the standard exp()
function is really declared, or something else strange is going on.

Similar things happen with the second call, with added problems
because pow()'s arguments are of type double, not int.

Note also that calling a variadic function, such as printf, with
no visible prototype is undefined behavior in C90.

In C99, your program violates several constraints (i.e., it's
illegal). In C90, it might work "correctly", but only by accident.

Here's a correct version of your program:

#include <stdio.h>
#include <math.h>
int main(void)
{

printf("exp(3.3) %f \n", exp(3.3));
printf("2^5 %f \n", pow(2,5));

return 0;
}

(The need for "-lm" is a peculiarity of gcc and some other Unixish
compilers.)

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Hans-Bernhard Bröker

unread,
Apr 29, 2010, 7:44:36 PM4/29/10
to
John wrote:
> I'm curious about the behavior of gcc and what includes are considered
> default.

None.

> gcc version 3.4.6 20060404 (Red Hat 3.4.6-11)

That's ancient.

> It seems math.h is being included by default

It's not.

> The code below compiles just fine with gcc -lm mathtest.c

Only because you didn't ask for any diagnostics.

Oh, and BTW you're not really in the right newsgroup. Behaviour of
individual implementations is discussed elsewhere.

Jasen Betts

unread,
Apr 30, 2010, 5:43:36 PM4/30/10
to
On 2010-04-29, John <joh...@gmail.com> wrote:
> I'm curious about the behavior of gcc and what includes are considered
> default.
> gcc version 3.4.6 20060404 (Red Hat 3.4.6-11)
>
> It seems math.h is being included by default but I still need to use -
> lm when linking.

no headers are included by default.
I don't need to use -lm, (GCC 4.3.2, debian 5.0.4 ("Lenny"))

> Is this behavior normal, and can it be configured?

exp pow and printf are built-in functions in GCC
exp and pow resolve to single floating point op-codes
if they were actual functions you'd get weird values returned as the
compiler would expect an int to be returned and look in the wrong place
or, or treat the value inapropriately.


--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

0 new messages