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

GCC default includes and math.h?

280 views
Skip to first unread message

John

unread,
Apr 29, 2010, 11:10:22 AM4/29/10
to
What headers does GCC include by default and is there any way to
change the behavior?

It seems on my system that math.h is being included by default and I
don't need to include it in source for
math functions. The code below compiles just fine as long as I
include the math library -lm.
I don't even include stdio.h and it works just fine. I'm not sure I
like this.

gcc version 3.4.6 20060404 (Red Hat 3.4.6-11)

gcc -lm mathtest.c

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

Rob Kendrick

unread,
Apr 29, 2010, 11:25:37 AM4/29/10
to
On Thu, 29 Apr 2010 08:10:22 -0700 (PDT)
John <joh...@gmail.com> wrote:

> What headers does GCC include by default and is there any way to
> change the behavior?
>
> It seems on my system that math.h is being included by default and I
> don't need to include it in source for
> math functions. The code below compiles just fine as long as I
> include the math library -lm.
> I don't even include stdio.h and it works just fine. I'm not sure I
> like this.

rjek@trite:~$ cat > tst.c


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

rjek@trite:~$ gcc tst.c
tst.c: In function ‘main’:
tst.c:3: warning: incompatible implicit declaration of built-in
function ‘printf’ tst.c:3: warning: incompatible implicit declaration
of built-in function ‘exp’ tst.c:4: warning: incompatible implicit
declaration of built-in function ‘pow’
rjek@trite:~$ gcc --version
gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1


I'd find it pretty incredible if it did. However, your earlier version
of GCC may not generate the warnings I get with 4.4.1 by default, but
that doesn't mean it's #including math.h by default.

Try this:

rjek@trite:~$ cat > tst.c
main()
{
printf("%f", M_PI);
}
rjek@trite:~$ gcc tst.c
tst.c: In function ‘main’:
tst.c:3: warning: incompatible implicit declaration of built-in
function ‘printf’ tst.c:3: error: ‘M_PI’ undeclared (first use in this
function) tst.c:3: error: (Each undeclared identifier is reported only
once tst.c:3: error: for each function it appears in.)

M_PI is defined in math.h; if this doesn't generate a binary for you,
it's not including math.h by default.

B.

Seebs

unread,
Apr 29, 2010, 11:52:01 AM4/29/10
to
On 2010-04-29, John <joh...@gmail.com> wrote:
> What headers does GCC include by default and is there any way to
> change the behavior?

This question is incoherent.

> It seems on my system that math.h is being included by default and I
> don't need to include it in source for
> math functions. The code below compiles just fine as long as I
> include the math library -lm.
> I don't even include stdio.h and it works just fine. I'm not sure I
> like this.

In general, so far as I know, there's no particular guarantee that standard
library functionality *won't* be included by default, only that it *will*
if you include the headers.

I don't see a problem.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Andrew Poelstra

unread,
Apr 29, 2010, 11:52:23 AM4/29/10
to
On 2010-04-29, John <joh...@gmail.com> wrote:

Try compiling with
gcc -Wall -Wextra -ansi -pedantic -O2 src.c
or
gcc -Wall -Wextra -std=c99 -pedantic -O2 src.c

Whatever suits your fancy.

--
Andrew Poelstra
http://www.wpsoftware.net/andrew

John

unread,
Apr 29, 2010, 12:04:20 PM4/29/10
to
On Apr 29, 11:25 am, Rob Kendrick <n...@rjek.com> wrote:
> On Thu, 29 Apr 2010 08:10:22 -0700 (PDT)
>

M_PI is not defined:

main()
{
printf("%f", M_PI);
}

[] gcc tst.c
tst.c: In function `main':


tst.c:3: error: `M_PI' undeclared (first use in this function)
tst.c:3: error: (Each undeclared identifier is reported only once
tst.c:3: error: for each function it appears in.)

Note that I don't get any error/warning on the printf like you do.

Also, tried this which works fine, despite needing -lm but not having
math.h declared. Any ideas why this is happening? Do exp, pow and cos
not need declarations?

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

printf("cos(almost pi) %f \n",cos(3.14));
}
[]$ gcc mathtest.c -lm
[]$ ./a.out
exp(3.3) 27.112639
2^5 32.000000
cos(almost pi) -0.999999

Rob Kendrick

unread,
Apr 29, 2010, 12:13:22 PM4/29/10
to
On Thu, 29 Apr 2010 09:04:20 -0700 (PDT)
John <joh...@gmail.com> wrote:

> Also, tried this which works fine, despite needing -lm but not having
> math.h declared. Any ideas why this is happening? Do exp, pow and cos
> not need declarations?

What happens is what I described; your compiler is "inventing" them,
and assuming the take an int, and return an int.

B.

Eric Sosman

unread,
Apr 29, 2010, 12:22:26 PM4/29/10
to

This code snippet is wrong, r-o-n-g, wrong. Does gcc
know it's r-o-n-g? Yes! Even with no command-line flags
to crank up warning levels, I get:

foo.c: In function 'main':
foo.c:3: warning: incompatible implicit declaration of built-in function
'printf'
foo.c:3: warning: incompatible implicit declaration of built-in function
'exp'
foo.c:4: warning: incompatible implicit declaration of built-in function
'pow'

With -Wall added, gcc becomes chattier:

foo.c:2: warning: return type defaults to 'int'
foo.c: In function 'main':
foo.c:3: warning: implicit declaration of function 'printf'
foo.c:3: warning: incompatible implicit declaration of built-in function
'printf'
foo.c:3: warning: implicit declaration of function 'exp'
foo.c:3: warning: incompatible implicit declaration of built-in function
'exp'
foo.c:4: warning: implicit declaration of function 'pow'
foo.c:4: warning: incompatible implicit declaration of built-in function
'pow'
foo.c:5: warning: control reaches end of non-void function

Neither of these results gives evidence to support the idea
that gcc includes headers by default, nor that there is any
behavior you should seek to change. Except your own, of course,
for writing such r-o-n-g code to begin with.

--
Eric Sosman
eso...@ieee-dot-org.invalid

William Hughes

unread,
Apr 29, 2010, 1:54:50 PM4/29/10
to

No, math.h is not being included. What is happening
is that if you use a function without a declaration,
the function is assumed to be int f(), that is to
return int and take an unknown number of parameters.
For printf this is fine, but exp and pow return doubles.
In some cases lying to the compiler about the return
value of a function will cause big problems. This is
not one of them. The compiler thinks that the functions
are returning an int, so it does not apply any default
promotion. You are telling printf to expect a double.
The functions that you are linking to do return doubles
so you were unlucky and things worked. The header math.h
tells the *compiler* what to expect when the code is run.
The -lm tells the *linker* where to find the code.
Crank up your warning levels until you are warned about
implicit declaration.

- William Hughes

crisgoogle

unread,
Apr 29, 2010, 2:11:26 PM4/29/10
to
On Apr 29, 9:13 am, Rob Kendrick <n...@rjek.com> wrote:
> On Thu, 29 Apr 2010 09:04:20 -0700 (PDT)
>
> John <john...@gmail.com> wrote:

<un-snip>


main()
{
printf("exp(3.3) %f \n", exp(3.3));
printf("2^5 %f \n", pow(2,5));
printf("cos(almost pi) %f \n",cos(3.14));
}

</un-snip>

> > Also, tried this which works fine, despite needing -lm but not having
> > math.h declared. Any ideas why this is happening? Do exp, pow and cos
> > not need declarations?
>
> What happens is what I described; your compiler is "inventing" them,
> and assuming the take an int, and return an int.
>

Almost. They implicitly return int, but take as arguments (double),
(int, int), and (double), respectively.

Kenny McCormack

unread,
Apr 29, 2010, 2:35:56 PM4/29/10
to
In article <d6aad9d5-da28-4636...@a27g2000prj.googlegroups.com>,

This thread is actually kinda interesting - although, of course, CLC can
not go beyond the stock "It's UB - you are a schmuck!" type answers.

When I ran the tests, I noticed a few interesting things (that are, as I
note above, beyond the ken of CLC):

1) All 4 of the non-declared functions (printf, exp, pow, cos) generate
a message like:
x.c:3: warning: incompatible implicit declaration of built-in function '...'
This does seem to support OP's original idea that math.h is somehow
being magically included. I.e., the compiler does seem to "know" about
these functions in some way. Obviously, it is unlikely that it is
actually including the file (although the standard does not forbid it
from doing so), but it seems that GCC somehow considers these to be
"built-in" functions.

2) Failing to supply -lm results in the linker complaining about 'exp'
and 'cos', but not, interestingly, 'pow', even though 'man pow' does
mention math.h and -lm.

--
> No, I haven't, that's why I'm asking questions. If you won't help me,
> why don't you just go find your lost manhood elsewhere.

CLC in a nutshell.

John

unread,
Apr 29, 2010, 2:43:46 PM4/29/10
to

Thanks for the responses. I understand what is happening now.
We are porting some code between several systems with different
versions of GCC and the Intel compiler and I wanted to understand
the behavior. btw, I do know that is not good code :) I didn't write
it but we are having to deal with it. A programmer left off the
math.h in some of the routines and it compile/worked just fine.

Kenny McCormack

unread,
Apr 29, 2010, 2:43:51 PM4/29/10
to
In article <0ca98555-61c2-44ff...@z17g2000vbd.googlegroups.com>,
William Hughes <wpih...@hotmail.com> wrote:
...

>In some cases lying to the compiler about the return
>value of a function will cause big problems. This is
>not one of them. The compiler thinks that the functions
>are returning an int, so it does not apply any default
>promotion. You are telling printf to expect a double.
>The functions that you are linking to do return doubles
>so you were unlucky and things worked.

The implication behind this statement is not true.

Try it with your own defined functions, with and without a prototype.

The reason it works with the built-in type functions is because gcc
"knows" about them.

--
(This discussion group is about C, ...)

Wrong. It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch [sic] revelations of the childhood
traumas of the participants...

William Hughes

unread,
Apr 29, 2010, 2:53:58 PM4/29/10
to
On Apr 29, 1:04 pm, John <john...@gmail.com> wrote:

> Do exp, pow and cos
> not need declarations?


Nope, like any functions, if used without a declaration
they are assumed to return int and take an arbitrary number
of arguments. This is wrong, but you are unlucky and things
work because the functions you are actually using (the ones
the linker finds) return double, and the compiler does not
need to use the fact that you told it (implicitly) the the functions
return int.


- William Hughes

Eric Sosman

unread,
Apr 29, 2010, 2:58:26 PM4/29/10
to
On 4/29/2010 2:43 PM, John wrote:
> [...]

> Thanks for the responses. I understand what is happening now.
> We are porting some code between several systems with different
> versions of GCC and the Intel compiler and I wanted to understand
> the behavior. btw, I do know that is not good code :) I didn't write
> it but we are having to deal with it. A programmer left off the
> math.h in some of the routines and it compile/worked just fine.

As others have suggested, crank up the warning levels.
With gcc, I'd recommend "-Wall -W -ansi -pedantic" (or use
"-std=c99" instead of "-ansi") as a starting point. Some code
isn't squeaky-clean enough for "-pedantic" and you might wind
up taking it out later, but as a screen for sloppy source it's
a good beginning.

Also, look into the various lint-like tools you can find.
Even if you can't find a lint specifically for Platform X, a
Platform Y lint will be helpful in catching some portability
problems.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Huibert Bol

unread,
Apr 29, 2010, 3:01:28 PM4/29/10
to
John wrote:

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

Some more GCC fun, the program

char aap[(int) pow (2, 3)];

main()
{
printf("%zu\n", sizeof aap);
}

compiles with just some warnings and prints, as expected, 8.

(Using GCC 4.3.2; I believe 4.5 added a warning about non-standard
constant expression for cases like this.)

--
Huibert
"Okay... really not something I needed to see." --Raven

William Hughes

unread,
Apr 29, 2010, 3:29:03 PM4/29/10
to

Apparently, this is false. Gcc does not produce working
code if it does not know that the function returns double.
It would appear that gcc knows the return types of the standard
functions, I suspect that it is also inlining code.

> > The header math.h
> > tells the *compiler* what to expect when the code is run.
> > The -lm tells the *linker* where to find the code.
> > Crank up your warning levels until you are warned about
> > implicit declaration.
>
> >                       - William Hughes
>
> Thanks for the responses. I understand what is happening now.
> We are porting some code between several systems with different
> versions of GCC and the Intel compiler and I wanted to understand
> the behavior. btw, I do know that is not good code :) I didn't write
> it but we are having to deal with it. A programmer left off the
> math.h in some of the routines and it compile/worked just fine.


Well, probably all you have to do is add math.h to the files
where it is missing. (It is possible that you are *really*
unlucky and this will change the behaviour, but this does not
seem likely). If you crank up the warnings you will be told when
math.h was left off, so you can add it back gradually if you want.

- William Hughes

Keith Thompson

unread,
Apr 29, 2010, 3:39:34 PM4/29/10
to
Seebs <usenet...@seebs.net> writes:
[...]

> In general, so far as I know, there's no particular guarantee that standard
> library functionality *won't* be included by default, only that it *will*
> if you include the headers.
>
> I don't see a problem.

C99 guarantees that if you call a standard library function without
a visible declaration, you'll get a diagnostic. You *can* provide
the declaration yourself, but it's insane not to just #include the
appropriate header unless you have a specific reason not to.

--
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"

Keith Thompson

unread,
Apr 29, 2010, 3:40:31 PM4/29/10
to
Rob Kendrick <nn...@rjek.com> writes:
[...]

> Try this:
>
> rjek@trite:~$ cat > tst.c
> main()
> {
> printf("%f", M_PI);
> }
[...]

>
> M_PI is defined in math.h; if this doesn't generate a binary for you,
> it's not including math.h by default.

M_PI is a non-standard extension.

William Hughes

unread,
Apr 29, 2010, 3:47:15 PM4/29/10
to
On Apr 29, 4:39 pm, Keith Thompson <ks...@mib.org> wrote:

> C99 guarantees that if you call a standard library function without
> a visible declaration, you'll get a diagnostic.  You *can* provide
> the declaration yourself,

Yes, but you cannot override the function with one of your
own. I was playing around (gcc 4.1.1) and I found that I could
override exp() with int exp (double) but if I used double exp
(double) I got the system exp().

- William Hughes

Rob Kendrick

unread,
Apr 29, 2010, 4:08:32 PM4/29/10
to
On Thu, 29 Apr 2010 12:40:31 -0700
Keith Thompson <ks...@mib.org> wrote:

> > M_PI is defined in math.h; if this doesn't generate a binary for
> > you, it's not including math.h by default.
>
> M_PI is a non-standard extension.

But it will be in the implementation he's using, so it's an easy test.

B.

Keith Thompson

unread,
Apr 29, 2010, 6:09:00 PM4/29/10
to

That depends on the compiler options he uses. With either "-ansi" or
"-std=c99", the declaration of M_PI in <math.h> is hidden.

It's better to use a reasonable set of options and pay attention to
warnings.

Rob Kendrick

unread,
Apr 29, 2010, 6:51:17 PM4/29/10
to
On Thu, 29 Apr 2010 15:09:00 -0700
Keith Thompson <ks...@mib.org> wrote:

> >> M_PI is a non-standard extension.
> >
> > But it will be in the implementation he's using, so it's an easy
> > test.
>
> That depends on the compiler options he uses. With either "-ansi" or
> "-std=c99", the declaration of M_PI in <math.h> is hidden.

Which is why I included the command line I executed it with.

B.

Alan Curry

unread,
Apr 29, 2010, 7:24:31 PM4/29/10
to
In article <773f6642-5414-4ee3...@37g2000yqm.googlegroups.com>,

William Hughes <wpih...@hotmail.com> wrote:
|
|Apparently, this is false. Gcc does not produce working
|code if it does not know that the function returns double.
|It would appear that gcc knows the return types of the standard
|functions, I suspect that it is also inlining code.

gcc does have special knowledge of the most common math functions. If you
want to see it fail as completely as possible, use -fno-builtin

--
Alan Curry

Tom St Denis

unread,
Apr 30, 2010, 7:57:04 AM4/30/10
to
On Apr 29, 2:35 pm, gaze...@shell.xmission.com (Kenny McCormack)
wrote:

> This thread is actually kinda interesting - although, of course, CLC can
> not go beyond the stock "It's UB - you are a schmuck!" type answers.

First off, grow up.

Second, it is NOT UB. The standard defines this very well.

> 2) Failing to supply -lm results in the linker complaining about 'exp'
>     and 'cos', but not, interestingly, 'pow', even though 'man pow' does
>     mention math.h and -lm.

It might have been inlined (e.g. to FPU opcodes). GCC will do that
for various trig functions. It can also optimized them out if it
knows the computation is compile time answerable.

Tom

Eric Sosman

unread,
Apr 30, 2010, 8:06:13 AM4/30/10
to
On 4/30/2010 7:57 AM, Tom St Denis wrote:
> On Apr 29, 2:35 pm, gaze...@shell.xmission.com (Kenny McCormack)
> wrote:
>> This thread is actually kinda interesting - although, of course, CLC can
>> not go beyond the stock "It's UB - you are a schmuck!" type answers.
>
> First off, grow up.

If anything, he's going the other way.

> Second, it is NOT UB. The standard defines this very well.

Calling a function via a function pointer of a mismatched type
is undefined behavior. Also, in the absence of a prototype only
the "default argument promotions" are applied; if these do not
produce values compatible with the actual parameter types the
behavior is undefined. So, for example, the `pow(2,5)' in the
original sample (with no declaration of `pow' in sight) produces
undefined behavior on both counts: The (implied) type of the
function pointer expression `pow' disagrees with the actual type
of the real `pow' function, and the argument types disagree with
the parameter types.

--
Eric Sosman
eso...@ieee-dot-org.invalid

s.dhil...@gmail.com

unread,
Apr 30, 2010, 8:32:38 AM4/30/10
to
or a

$gcc -E mathtest.c
# 1 "mathtest.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "mathtest.c"


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

will give a clue on what is happening?

Is this <built-in> the same as Alan (-fno-builtin flag) referring to?

Regards,
Dhilip

Kenny McCormack

unread,
Apr 30, 2010, 8:51:06 AM4/30/10
to
In article <hreh54$9pk$1...@news.eternal-september.org>,

Eric Sosman <eso...@ieee-dot-org.invalid> wrote:
>On 4/30/2010 7:57 AM, Tom St Denis wrote:
>> On Apr 29, 2:35 pm, gaze...@shell.xmission.com (Kenny McCormack)
>> wrote:
>>> This thread is actually kinda interesting - although, of course, CLC can
>>> not go beyond the stock "It's UB - you are a schmuck!" type answers.
>>
>> First off, grow up.

I think we can all agree that "It's UB - you are a schmuck!" is an
entirely accurate summary of your last post to the OP, Eric.

It (your post) was very condescending and rude.

Tom St Denis

unread,
Apr 30, 2010, 11:38:20 AM4/30/10
to
On Apr 30, 8:06 am, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
>      Calling a function via a function pointer of a mismatched type
> is undefined behavior.  Also, in the absence of a prototype only
> the "default argument promotions" are applied; if these do not
> produce values compatible with the actual parameter types the
> behavior is undefined.  So, for example, the `pow(2,5)' in the
> original sample (with no declaration of `pow' in sight) produces
> undefined behavior on both counts: The (implied) type of the
> function pointer expression `pow' disagrees with the actual type
> of the real `pow' function, and the argument types disagree with
> the parameter types.

I disagree in that I'm splitting hairs and it's friday and I feel like
posting.

It's well defined what the default promotions are so calling pow()
without a prototype is not UB. What pow() does with it's parameters
is UB.

:-)

Tom

Eric Sosman

unread,
Apr 30, 2010, 12:48:27 PM4/30/10
to
On 4/30/2010 11:38 AM, Tom St Denis wrote:
> On Apr 30, 8:06 am, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
>> Calling a function via a function pointer of a mismatched type
>> is undefined behavior. Also, in the absence of a prototype only
>> the "default argument promotions" are applied; if these do not
>> produce values compatible with the actual parameter types the
>> behavior is undefined. So, for example, the `pow(2,5)' in the
>> original sample (with no declaration of `pow' in sight) produces
>> undefined behavior on both counts: The (implied) type of the
>> function pointer expression `pow' disagrees with the actual type
>> of the real `pow' function, and the argument types disagree with
>> the parameter types.
>
> I disagree in that I'm splitting hairs and it's friday and I feel like
> posting.

This must be Friday. I never could get the hang of Fridays.

> It's well defined what the default promotions are so calling pow()
> without a prototype is not UB. What pow() does with it's parameters
> is UB.

The hair, I think, remains un-split (thanks to that expensive
shampoo-conditioner-gunk the salon employee applied.)

The Standard says only that "the behavior is undefined" when
the faulty call executes, not that the behavior is defined up to
some specified moment and undefined thereafter. There's no way
to decide whether the call is OK and the UB only begins somewhere
inside pow(), or whether the call itself goes off the rails. Nor
can I see that such a localization of UB would make any difference,
since it's clear that UB has occurred by the time pow() returns to
the caller (if it returns at all).

It is possible, though silly, to call pow() without a prototype
and have well-defined behavior. Two conditions must be met:

- The type of the function pointer in the calling expression
must be compatible with the actual type of pow(). Since the
actual pow() returns a double, and since an undeclared pow()
is assumed to return an int (in C90), pow() must be declared
prior to the point of the call. The original code did not
declare pow() at all, so it gets UB.

- The number and as-promoted types of the argument expressions
must be compatible with the actual parameters of pow(). Since
pow() takes two doubles, two double arguments must be supplied
(because no other type promotes to double). The original code
provides two int values, which do not promote to doubles --
once again, we have UB.

> :-)

;-)

--
Eric Sosman
eso...@ieee-dot-org.invalid

crisgoogle

unread,
Apr 30, 2010, 1:00:28 PM4/30/10
to
On Apr 30, 9:48 am, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 4/30/2010 11:38 AM, Tom St Denis wrote:
>
> > On Apr 30, 8:06 am, Eric Sosman<esos...@ieee-dot-org.invalid>  wrote:
> > I disagree in that I'm splitting hairs and it's friday and I feel like
> > posting.
>
>      This must be Friday.  I never could get the hang of Fridays.
>

<snip>

>  Since
>        pow() takes two doubles, two double arguments must be supplied
>        (because no other type promotes to double).

> > :-)
>
>      ;-)

More Friday hair-splitting? =)

Floats also promote to double (in the absence of the prototype), so
you could provide two floats and still be safe.


Eric Sosman

unread,
Apr 30, 2010, 1:10:36 PM4/30/10
to
On 4/30/2010 1:00 PM, crisgoogle wrote:
> On Apr 30, 9:48 am, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
>> [...]

>> Since
>> pow() takes two doubles, two double arguments must be supplied
>> (because no other type promotes to double).
>>> :-)
>>
>> ;-)
>
> More Friday hair-splitting? =)
>
> Floats also promote to double (in the absence of the prototype), so
> you could provide two floats and still be safe.

"I never could get the hang of Fridays." (You're right,
of course, and my brain was on Friday furlough.)

--
Eric Sosman
eso...@ieee-dot-org.invalid

Tom St Denis

unread,
Apr 30, 2010, 1:24:07 PM4/30/10
to

In all seriousness thanks for the incite. Now I'm off to find a
better conditioner...

Tom

Morris Keesan

unread,
May 4, 2010, 1:43:20 PM5/4/10
to
On Thu, 29 Apr 2010 15:47:15 -0400, William Hughes <wpih...@hotmail.com>
wrote:

I don't think this is completely true. You can't override a standard
library function with one of your own with external linkage, but you should
be able to replace it with your own function with internal linkage, as
long as you don't #include the associated header.

C99 7.1.3 Reserved Identifiers
says

— All identifiers with external linkage in any of the following
subclauses (including the future library directions) are always
reserved for use as identifiers with external linkage.

— Each identifier with file scope listed in any of the following
subclauses (including the future library directions) is reserved
for use as a macro name and as an identifier with file scope
in the same name space if any of its associated headers is included.


I read this as giving me permission to write

static int fabs(int x)
{
if (x < 0) return -x; else return x;
}

int foo(void)
{
return fabs(-3);
}

if I don't #include <math.h>

Am I missing something?
--
Morris Keesan -- mke...@post.harvard.edu

Kenny McCormack

unread,
May 4, 2010, 2:34:39 PM5/4/10
to
In article <op.vb6ziiky5qv6o3@toshiba-laptop>,
Morris Keesan <mke...@post.harvard.edu> wrote:
...

>I read this as giving me permission to write
>
> static int fabs(int x)
> {
> if (x < 0) return -x; else return x;
> }
>
> int foo(void)
> {
> return fabs(-3);
> }
>
>if I don't #include <math.h>
>
>Am I missing something?

As I'm sure you are aware (since you must have tested this before
posting it), gcc still complains. It seems to "do the right thing"
though, anyway.

William Hughes

unread,
May 4, 2010, 4:20:29 PM5/4/10
to
On May 4, 2:43 pm, "Morris Keesan" <mkee...@post.harvard.edu> wrote:
> On Thu, 29 Apr 2010 15:47:15 -0400, William Hughes <wpihug...@hotmail.com>  

No. Indeed gcc works fine with static double acos(double)
(and in my version, with no flags, does not complain)


But, if you enter the realm of undefined behaviour and
define your own function with double acos(double)
you get the usual acos not the version you provide.
On the other hand if you say int acos(double)
you do get your function. Isn't undefined
behaviour fun.

- William Hughes


Noob

unread,
May 5, 2010, 4:32:34 AM5/5/10
to
Morris Keesan wrote:

> I don't think this is completely true. You can't override a standard
> library function with one of your own with external linkage, but you should
> be able to replace it with your own function with internal linkage, as
> long as you don't #include the associated header.
>
> C99 7.1.3 Reserved Identifiers
> says
>
> — All identifiers with external linkage in any of the following
> subclauses (including the future library directions) are always
> reserved for use as identifiers with external linkage.
>
> — Each identifier with file scope listed in any of the following
> subclauses (including the future library directions) is reserved
> for use as a macro name and as an identifier with file scope
> in the same name space if any of its associated headers is included.
>
>
> I read this as giving me permission to write
>
> static int fabs(int x)
> {
> if (x < 0) return -x; else return x;
> }
>
> int foo(void)
> {
> return fabs(-3);
> }
>
> if I don't #include <math.h>
>
> Am I missing something?

C89 says

4.1.2 Standard headers

Each library function is declared in a header, whose contents
are made available by the #include preprocessing directive. The
header declares a set of related functions, plus any necessary types
and additional macros needed to facilitate their use. Each header
declares and defines only those identifiers listed in its associated
section. All external identifiers declared in any of the headers are
reserved, whether or not the associated header is included. All
external identifiers that begin with an underscore are reserved. All
other identifiers that begin with an underscore and either an
upper-case letter or another underscore are reserved. If the program
defines an external identifier with the same name as a reserved
external identifier, even in a semantically equivalent form, the
behavior is undefined.

Noob

unread,
May 5, 2010, 6:42:58 AM5/5/10
to
Tom St Denis wrote:

> In all seriousness thanks for the incite. Now I'm off to find a
> better conditioner...

Would this make Eric's post an incitation to buy shampoo?

( http://www.merriam-webster.com/dictionary/incite )

0 new messages