compile detection of powf, etc

Discussion in 'C Programming' started by Marco, Jan 30, 2006.

  1. Marco

    Marco Guest

    Is there a standard way using the preprocessor to detect if a given C
    compiler/library environment provides the C99 <math.h> floating point
    functions such as:

    float powf(float x, float y);
    float sqrtf(float x);
    etc

    so we could "provide" these prototypes or not via our

    "xtra_math.h" file

    Note some C environments are incomplete and may define the C90 flag but
    still provide these functions. So I think we need to check each
    function.

    looking for any suggestions

    thanks
    Marco, Jan 30, 2006
    #1
    1. Advertising

  2. In article <>,
    Marco <> wrote:
    >Is there a standard way using the preprocessor to detect if a given C
    >compiler/library environment provides the C99 <math.h> floating point
    >functions such as:


    > float powf(float x, float y);
    > float sqrtf(float x);


    >Note some C environments are incomplete and may define the C90 flag but
    >still provide these functions. So I think we need to check each
    >function.


    C90 does not define any feature-test preprocessor variables,
    so any such macro provided by an environment intermediate between C90
    and C99 is, by definition, non-standard.

    If you need to be able to determine the presence or absence of
    particular routines, I suggest you consider using something like
    "automake".


    > so we could "provide" these prototypes or not via our
    > "xtra_math.h" file


    That hints at a commercial product; if so then if you do look at
    automake, ensure that you read the accompanying licenses.
    --
    All is vanity. -- Ecclesiastes
    Walter Roberson, Jan 30, 2006
    #2
    1. Advertising

  3. Marco

    Eric Sosman Guest

    Marco wrote On 01/30/06 10:21,:
    > Is there a standard way using the preprocessor to detect if a given C
    > compiler/library environment provides the C99 <math.h> floating point
    > functions such as:
    >
    > float powf(float x, float y);
    > float sqrtf(float x);
    > etc
    >
    > so we could "provide" these prototypes or not via our
    >
    > "xtra_math.h" file
    >
    > Note some C environments are incomplete and may define the C90 flag but
    > still provide these functions. So I think we need to check each
    > function.


    `#if __STDC_VERSION__ >= 199901L' tests whether the
    implementation claims to conform to C99; if it does, the
    functions you're looking for are present.

    I can think of no portable way to tell whether these
    functions exist as extensions in earlier implementations.
    You could use `#ifdef powf' to check for a "masking" macro
    and assume that the corresponding function exists if the
    macro is defined, but the function might also exist without
    a masking macro. You may simply need to tailor your
    "xtra_math.h" header to each implementation you care about,
    possibly with a semi-automated tool like autoconf.

    --
    Eric Sosman, Jan 30, 2006
    #3
  4. Marco

    Jordan Abel Guest

    On 2006-01-30, Marco <> wrote:
    > Is there a standard way using the preprocessor to detect if a given C
    > compiler/library environment provides the C99 <math.h> floating point
    > functions such as:
    >
    > float powf(float x, float y);
    > float sqrtf(float x);
    > etc
    >
    > so we could "provide" these prototypes or not via our
    >
    > "xtra_math.h" file
    >
    > Note some C environments are incomplete and may define the C90 flag but
    > still provide these functions. So I think we need to check each
    > function.
    >
    > looking for any suggestions
    >
    > thanks


    (semi-offtopic)
    One way [this is highly system-specific - basically unix-only, and may
    not be guaranteed even by the POSIX standard] would be to provide the
    functions in a static library and link it after libm. If the link editor
    finds it in libm, it won't take the one from your library.
    static library
    Jordan Abel, Jan 30, 2006
    #4
  5. Eric Sosman <> writes:
    > Marco wrote On 01/30/06 10:21,:
    >> Is there a standard way using the preprocessor to detect if a given C
    >> compiler/library environment provides the C99 <math.h> floating point
    >> functions such as:
    >>
    >> float powf(float x, float y);
    >> float sqrtf(float x);
    >> etc
    >>
    >> so we could "provide" these prototypes or not via our
    >>
    >> "xtra_math.h" file
    >>
    >> Note some C environments are incomplete and may define the C90 flag but
    >> still provide these functions. So I think we need to check each
    >> function.

    >
    > `#if __STDC_VERSION__ >= 199901L' tests whether the
    > implementation claims to conform to C99; if it does, the
    > functions you're looking for are present.


    It means that the compiler *claims* to conform to C99. If it's lying,
    then it's not a conforming C compiler, and the requirements of the C
    standard don't apply to it.

    The compiler might not actually know whether the functions are
    available. The compiler and the library are commonly separate (for
    example, gcc uses whatever library is provided by the underlying
    system). If the compiler is conforming and the library isn't, the
    compiler *shouldn't* define __STDC_VERSION__ as 199901L, but it might
    do so anyway.

    > I can think of no portable way to tell whether these
    > functions exist as extensions in earlier implementations.
    > You could use `#ifdef powf' to check for a "masking" macro
    > and assume that the corresponding function exists if the
    > macro is defined, but the function might also exist without
    > a masking macro. You may simply need to tailor your
    > "xtra_math.h" header to each implementation you care about,
    > possibly with a semi-automated tool like autoconf.


    Or you can write a simple test as part of your build process. Try to
    compile and execute a small program that uses the functions. If it
    produces the expected output, you can use <math.h>; if not, you need
    to use "xtra_math.h". You can generate a header file at build time,
    and include the generated header in your actual program.

    This is basically what autoconf does, but if this is the only test you
    need it might be simpler to do it manually.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Jan 30, 2006
    #5
  6. Marco

    Eric Sosman Guest

    Keith Thompson wrote On 01/30/06 14:29,:
    > Eric Sosman <> writes:
    >
    >>Marco wrote On 01/30/06 10:21,:
    >>
    >>>Is there a standard way using the preprocessor to detect if a given C
    >>>compiler/library environment provides the C99 <math.h> floating point
    >>>functions such as:
    >>>
    >>> float powf(float x, float y);
    >>> float sqrtf(float x);
    >>> etc
    >>>
    >>> so we could "provide" these prototypes or not via our
    >>>
    >>> "xtra_math.h" file
    >>>
    >>>Note some C environments are incomplete and may define the C90 flag but
    >>>still provide these functions. So I think we need to check each
    >>>function.

    >>
    >> `#if __STDC_VERSION__ >= 199901L' tests whether the
    >>implementation claims to conform to C99; if it does, the
    >>functions you're looking for are present.

    >
    >
    > It means that the compiler *claims* to conform to C99. If it's lying,
    > then it's not a conforming C compiler, and the requirements of the C
    > standard don't apply to it.


    That's more or less why I wrote "claims" to begin with.

    > The compiler might not actually know whether the functions are
    > available. The compiler and the library are commonly separate (for
    > example, gcc uses whatever library is provided by the underlying
    > system). If the compiler is conforming and the library isn't, the
    > compiler *shouldn't* define __STDC_VERSION__ as 199901L, but it might
    > do so anyway.


    If the compiler lies to me, I will get my revenge ;-)
    My only vehicle for vendetta may be to demand my money back
    and to bad-mouth the vendor in every forum I can find, but
    somehow I will get my revenge. Mwa-ha-haaah!

    Note that the compiler and library are not separable
    (in hosted implementations): Both are simply parts of "the
    implementation" as far as the Standard is concerned. Thus,
    __STDC_VERSION__ (and indeed, __STDC__ itself) assert things
    not only about the compiler but also about the library and
    about support routines that take care of things like opening
    stdin before main() is called. All the pieces must cooperate;
    it invites error to try to isolate them.

    --
    Eric Sosman, Jan 30, 2006
    #6
  7. Eric Sosman <> writes:
    [...]
    > If the compiler lies to me, I will get my revenge ;-)
    > My only vehicle for vendetta may be to demand my money back
    > and to bad-mouth the vendor in every forum I can find, but
    > somehow I will get my revenge. Mwa-ha-haaah!
    >
    > Note that the compiler and library are not separable
    > (in hosted implementations): Both are simply parts of "the
    > implementation" as far as the Standard is concerned. Thus,
    > __STDC_VERSION__ (and indeed, __STDC__ itself) assert things
    > not only about the compiler but also about the library and
    > about support routines that take care of things like opening
    > stdin before main() is called. All the pieces must cooperate;
    > it invites error to try to isolate them.


    As far as the standard is concerned, yes. But there *are* cases where
    the compiler and library are implemented separately. The compiler is
    responsible for defining __STD__ and __STDC_VERSION__ appropriately to
    reflect the conformance of the implementation as a whole. Whether all
    compilers actually do this properly is another question.

    I have seen cases (not necessarily tied to library issues) where a
    compiler's definition of __STDC__ was inconsistent with reality.
    There's not a whole lot you can do to defend against that, other than
    thorough testing.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Jan 30, 2006
    #7
  8. Marco

    Jack Klein Guest

    On Mon, 30 Jan 2006 19:29:04 GMT, Keith Thompson <> wrote
    in comp.lang.c:

    > Eric Sosman <> writes:
    > > Marco wrote On 01/30/06 10:21,:
    > >> Is there a standard way using the preprocessor to detect if a given C
    > >> compiler/library environment provides the C99 <math.h> floating point
    > >> functions such as:
    > >>
    > >> float powf(float x, float y);
    > >> float sqrtf(float x);
    > >> etc
    > >>
    > >> so we could "provide" these prototypes or not via our
    > >>
    > >> "xtra_math.h" file
    > >>
    > >> Note some C environments are incomplete and may define the C90 flag but
    > >> still provide these functions. So I think we need to check each
    > >> function.

    > >
    > > `#if __STDC_VERSION__ >= 199901L' tests whether the
    > > implementation claims to conform to C99; if it does, the
    > > functions you're looking for are present.

    >
    > It means that the compiler *claims* to conform to C99. If it's lying,
    > then it's not a conforming C compiler, and the requirements of the C
    > standard don't apply to it.
    >
    > The compiler might not actually know whether the functions are
    > available. The compiler and the library are commonly separate (for
    > example, gcc uses whatever library is provided by the underlying
    > system). If the compiler is conforming and the library isn't, the
    > compiler *shouldn't* define __STDC_VERSION__ as 199901L, but it might
    > do so anyway.


    [snip]

    I don't agree with the statement that the "compiler and the library
    are commonly separate". I don't know of a single other implementation
    other than some gcc variants where this is so.

    Do you know of any others?

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Jan 31, 2006
    #8
  9. Jack Klein <> writes:
    > On Mon, 30 Jan 2006 19:29:04 GMT, Keith Thompson <> wrote
    > in comp.lang.c:
    >> Eric Sosman <> writes:

    [...]
    >> > `#if __STDC_VERSION__ >= 199901L' tests whether the
    >> > implementation claims to conform to C99; if it does, the
    >> > functions you're looking for are present.

    >>
    >> It means that the compiler *claims* to conform to C99. If it's lying,
    >> then it's not a conforming C compiler, and the requirements of the C
    >> standard don't apply to it.
    >>
    >> The compiler might not actually know whether the functions are
    >> available. The compiler and the library are commonly separate (for
    >> example, gcc uses whatever library is provided by the underlying
    >> system). If the compiler is conforming and the library isn't, the
    >> compiler *shouldn't* define __STDC_VERSION__ as 199901L, but it might
    >> do so anyway.

    >
    > [snip]
    >
    > I don't agree with the statement that the "compiler and the library
    > are commonly separate". I don't know of a single other implementation
    > other than some gcc variants where this is so.
    >
    > Do you know of any others?


    Intel's icc is very similar to gcc. I suspect there are other
    third-party compilers for Linux that use glibc as well.

    But apart from those examples, I actually have very little idea how
    common it is.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Jan 31, 2006
    #9
  10. Marco

    Ed Vogel Guest

    "Jack Klein" <> wrote in message
    news:...
    > I don't agree with the statement that the "compiler and the library
    > are commonly separate". I don't know of a single other implementation
    > other than some gcc variants where this is so.
    >
    > Do you know of any others?
    >
    > --

    Jack,

    All HP C compiler implementations (HP-UX, Tru64 UNIX, and OpenVMS)
    ship separately from the libraries. The libraries ship with the O.S. as
    they
    are needed by many applications that do not require the compilers.

    Ed Vogel
    HP C/C++ Engineering.
    Ed Vogel, Jan 31, 2006
    #10
  11. Marco

    Eric Sosman Guest

    Ed Vogel wrote On 01/31/06 09:06,:
    > "Jack Klein" <> wrote in message
    > news:...
    >
    >>I don't agree with the statement that the "compiler and the library
    >>are commonly separate". I don't know of a single other implementation
    >>other than some gcc variants where this is so.
    >>
    >>Do you know of any others?
    >>
    >>--

    >
    > Jack,
    >
    > All HP C compiler implementations (HP-UX, Tru64 UNIX, and OpenVMS)
    > ship separately from the libraries. The libraries ship with the O.S. as
    > they
    > are needed by many applications that do not require the compilers.


    That's usually the case, but distribution and
    integration are different things. The macros defined
    by the compiler and headers must correctly describe
    the library and the operating environment, or else
    "the implementation" is non-conforming. The Standard
    has no notion (in hosted systems) of separating the
    compiler from the library, just as it has no notion
    of separating the preprocessor from the rest of the
    compiler. Real systems are often built from modules,
    but the Standard speaks only of the integrated whole.

    ... which isn't to say that the compilers and
    libraries are always properly integrated. As Ken
    Thompson pointed out, a compiler that defines
    __STDC_VERSION__ as 199901L might find itself deployed
    with a library that doesn't conform to C99. That's a
    bit like deploying tires of different sizes on the
    left and right sides of your car; none of the tires
    is "wrong" in and of itself, but the combination of
    mismatched sizes is invalid anyhow.

    From the programmer's perspective, I think you must
    trust __STDC_VERSION__, just as you trust longjmp().
    A C99 compiler mis-deployed with a C89 library will
    deceive you; equally, a compiler that uses one flavor of
    compiler magic in its setjmp() will produce code that
    is likely to fail if deployed with a library whose
    longjmp() expects a different sort of magic. Sometimes
    it will turn out that your trust is misplaced; that's
    the way things are in an imperfect world. But what's
    the alternative? Run a complete conformance test suite
    before starting each compilation? Trust the compiler,
    I say, and realize that it may lie very occasionally.

    --
    Eric Sosman, Jan 31, 2006
    #11
  12. Eric Sosman <> writes:
    [...]
    > ... which isn't to say that the compilers and
    > libraries are always properly integrated. As Ken
    > Thompson pointed out, a compiler that defines
    > __STDC_VERSION__ as 199901L might find itself deployed
    > with a library that doesn't conform to C99. That's a
    > bit like deploying tires of different sizes on the
    > left and right sides of your car; none of the tires
    > is "wrong" in and of itself, but the combination of
    > mismatched sizes is invalid anyhow.


    I think you meant Keith Thompson, not Ken Thompson.

    > From the programmer's perspective, I think you must
    > trust __STDC_VERSION__, just as you trust longjmp().
    > A C99 compiler mis-deployed with a C89 library will
    > deceive you; equally, a compiler that uses one flavor of
    > compiler magic in its setjmp() will produce code that
    > is likely to fail if deployed with a library whose
    > longjmp() expects a different sort of magic. Sometimes
    > it will turn out that your trust is misplaced; that's
    > the way things are in an imperfect world. But what's
    > the alternative? Run a complete conformance test suite
    > before starting each compilation? Trust the compiler,
    > I say, and realize that it may lie very occasionally.


    My concern is that this kind of compiler vs. library mismatch may be
    quite common. gcc is one of the most widely used C compilers, and it
    uses whatever C library happens to exist on the system where it's
    installed.

    I remember having a similar problem many years ago under SunOS 4.1.3.
    The system-provided sprintf() function, if I recall correctly,
    returned a char* rather than an int (this was a pre-ANSI
    implementation), but gcc claimed to be C90-conforming (as the compiler
    itself was, as far as I know). Ideally the gcc installation procedure
    should have detected this and adjusted __STDC__ appropriately, but I
    don't think it did.

    If this is a common kind of bug, it's probably worth testing for, at
    least for specific known cases of it.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Jan 31, 2006
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gianni Mariani
    Replies:
    0
    Views:
    331
    Gianni Mariani
    Jan 13, 2005
  2. Robin Cull
    Replies:
    5
    Views:
    402
    Andrew Dalke
    Jul 31, 2003
  3. Nagaraj
    Replies:
    1
    Views:
    854
    Lionel B
    Mar 1, 2007
  4. Replies:
    0
    Views:
    308
  5. Kevin Walzer

    Re: PIL (etc etc etc) on OS X

    Kevin Walzer, Aug 1, 2008, in forum: Python
    Replies:
    4
    Views:
    386
    Fredrik Lundh
    Aug 13, 2008
Loading...

Share This Page