GCC default includes and math.h?

K

Keith Thompson

Rob Kendrick said:
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.

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

Rob Kendrick

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

Alan Curry

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

Tom St Denis

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
 
E

Eric Sosman

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

s.dhilipkumar

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
 
K

Kenny McCormack

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.

--
(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...
 
T

Tom St Denis

     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
 
E

Eric Sosman

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.

;-)
 
C

crisgoogle

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

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

Eric Sosman

[...]
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.)
 
T

Tom St Denis

[...]
  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.)

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

Tom
 
M

Morris Keesan

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

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

Kenny McCormack

Morris Keesan said:
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.

--
(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...
 
W

William Hughes

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

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
 
N

Noob

Morris said:
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.
 

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
474,093
Messages
2,570,610
Members
47,230
Latest member
RenaldoDut

Latest Threads

Top