#if typedef()

Discussion in 'C Programming' started by Kenneth Brody, Aug 11, 2005.

  1. Is there any way to know if there is a typedef of a given name?

    Specifically, I need to know if the compiler has a 64-bit integer type,
    and need to know if "int64_t" exists. Something like this pseudo-code:

    #if typedef(int64_t)
    typedef int64_t MY_BIG_INT
    #elif typedef(long long)
    typedef long long MY_BIG_INT
    #else
    typedef long MY_BIG_INT
    #endif

    (Yes, this program needs to work on systems which don't have a 64-bit
    integers, and it needs to take advantage of them if they are there.)

    Also, what is the standard include file which would be needed to have
    the int64_t typedef included? I see it in <stdint.h> on one compiler
    I have, and <native.h> on another. I don't see these headers being
    included by other standard headers on these systems.

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Aug 11, 2005
    #1
    1. Advertising

  2. In article <>,
    Kenneth Brody <> wrote:
    >Is there any way to know if there is a typedef of a given name?


    >Specifically, I need to know if the compiler has a 64-bit integer type,
    >and need to know if "int64_t" exists.



    There is no portable way to test that in C89 (I'm not familiar enough
    with C99 to know if it were extended in that regard, but I suspect not.)


    The usual way to handle this is to have a meta level that tests
    for the existance of appropriate types or functions and sets
    preprocessing tokens appropriately in a constructed include file
    that the rest of the code imports.
    --
    Look out, there are llamas!
    Walter Roberson, Aug 11, 2005
    #2
    1. Advertising

  3. Walter Roberson wrote:
    >
    > In article <>,
    > Kenneth Brody <> wrote:
    > >Is there any way to know if there is a typedef of a given name?

    >
    > >Specifically, I need to know if the compiler has a 64-bit integer type,
    > >and need to know if "int64_t" exists.

    >
    > There is no portable way to test that in C89 (I'm not familiar enough
    > with C99 to know if it were extended in that regard, but I suspect not.)


    I can't depend on C99 being available, so that's not really relevent.

    > The usual way to handle this is to have a meta level that tests
    > for the existance of appropriate types or functions and sets
    > preprocessing tokens appropriately in a constructed include file
    > that the rest of the code imports.


    Well, we already have a bunch of config.h files for different platforms
    to define such things native byte order (yes, some parts of the code need
    to know that), whether "void" is available (we used to run on platforms
    that had no "void" type), which type of varargs are needed, and so on. I
    was just hoping to avoid yet another entry.

    I guess I'll probably end up going with "assume there's an int64_t type
    unless the config file defines NO_INT64_T", or something like that.

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Aug 11, 2005
    #3
  4. Kenneth Brody <> writes:
    > Is there any way to know if there is a typedef of a given name?


    No.

    [snip]

    > Also, what is the standard include file which would be needed to have
    > the int64_t typedef included? I see it in <stdint.h> on one compiler
    > I have, and <native.h> on another. I don't see these headers being
    > included by other standard headers on these systems.


    In C99, int64_t is defined in <stdint.h>, but the C99 standard is not
    universally supported. Strictly speaking, int64_t is optional; it
    will be defined only if the implementation has a two's complement
    integer type with a width of exactly 64 bits and no padding. In
    practice, since C99 requires long long to be at least 64 bits, I'd be
    surprised to see a C99 implementation that doesn't have int64_t.

    Given a C99 implementation, the macro INT64_MAX will be defined in
    <stdint.h> if and only if int64_t is defined, so you can use
    #ifdef INT64_MAX

    You can check whether you have a C99 implementation with

    #if __STDC_VERSION__ >= 199901L

    A pre-C99 compiler is allowed, but not required, to define int64_t in
    an implementation-specific header -- or it can call it int_64_t, or
    anything it likes. There's no way in the preprocessor to test whether
    a given header exists. You pretty much have to track down the details
    for all the implementations you need to support, and write custom code
    for each.

    Perhaps the best approach is to use your own <stdint.h> (or, more
    properly, "stdint.h") header to be used with pre-C99 compilers. See
    <http://www.lysator.liu.se/c/q8/> for a public domain implementation.

    Note that __STDC_VERSION__ >= 199901L doesn't necessarily imply that
    the <stdint.h> header *doesn't* exist. Some compilers might provide
    partial C99 support.

    --
    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, Aug 11, 2005
    #4
  5. Kenneth Brody <> writes:
    [...]
    > Well, we already have a bunch of config.h files for different platforms
    > to define such things native byte order (yes, some parts of the code need
    > to know that), whether "void" is available (we used to run on platforms
    > that had no "void" type), which type of varargs are needed, and so on. I
    > was just hoping to avoid yet another entry.


    Looks like you'll need yet another entry.

    > I guess I'll probably end up going with "assume there's an int64_t type
    > unless the config file defines NO_INT64_T", or something like that.


    You may find that giving a flag a negative name will cause confusion.
    I find thinks like
    #ifdef NO_INT64_T
    or
    #if !defined(NO_INT_64_T)
    more difficult to read than
    #ifdef HAS_INT64_T
    or
    #if defined(HAS_INT_64_T)

    --
    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, Aug 11, 2005
    #5
  6. Kenneth Brody

    Flash Gordon Guest

    Kenneth Brody wrote:
    > Is there any way to know if there is a typedef of a given name?


    No.

    > Specifically, I need to know if the compiler has a 64-bit integer type,
    > and need to know if "int64_t" exists. Something like this pseudo-code:
    >
    > #if typedef(int64_t)
    > typedef int64_t MY_BIG_INT
    > #elif typedef(long long)


    "long long", on systems which have it, won't *be* a type def.

    > typedef long long MY_BIG_INT
    > #else
    > typedef long MY_BIG_INT
    > #endif
    >
    > (Yes, this program needs to work on systems which don't have a 64-bit
    > integers, and it needs to take advantage of them if they are there.)


    For that you obviously need rather more work than merely using the right
    type.

    > Also, what is the standard include file which would be needed to have
    > the int64_t typedef included? I see it in <stdint.h> on one compiler
    > I have, and <native.h> on another. I don't see these headers being
    > included by other standard headers on these systems.


    stdint.h is part of the C99 standard. Unfortunately most implementations
    do not fully meet C99. However, it is simple to write an stdint.h for
    any systems that don't have it.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Aug 11, 2005
    #6
  7. Kenneth Brody

    Eric Sosman Guest

    Kenneth Brody wrote:
    > Is there any way to know if there is a typedef of a given name?


    Not directly, no.

    > Specifically, I need to know if the compiler has a 64-bit integer type,
    > and need to know if "int64_t" exists. Something like this pseudo-code:
    >
    > #if typedef(int64_t)
    > typedef int64_t MY_BIG_INT
    > #elif typedef(long long)
    > typedef long long MY_BIG_INT
    > #else
    > typedef long MY_BIG_INT
    > #endif
    >
    > (Yes, this program needs to work on systems which don't have a 64-bit
    > integers, and it needs to take advantage of them if they are there.)


    `#if __STDC_VERSION__ >= 199901L' means "C99 or later"
    and implies the existence of the <stdint.h> header. Having
    included this header, you can then check for the presence
    of macros like INT64_MAX or UINT_LEAST64_MAX (depending on
    whether you want signed or unsigned, exactly or at least 64
    bits).

    If you don't have C99, you still might be lucky: Some C90
    implementations provide a 64-bit `long'. You can check by
    including <limits.h> and inspecting the values of LONG_MAX
    and/or ULONG_MAX (with care; see below).

    Finally, some pre-C99 implementations provide `long long'
    if invoked in a non-conforming mode. If yours does so and if
    it supports `long long' in the C99 style, <limits.h> will
    define LLONG_MAX and ULLONG_MAX for you to check.

    Putting it all together, you'd get something like this
    (the indirect value tests cater to C90 preprocessors, which
    might not be able to parse longer-than-`long' numbers):

    #if __STDC_VERSION__ >= 199901L
    #include <stdint.h>
    #ifdef INT_LEAST64_MAX
    typedef int_least64_t MyBigInt;
    #define MYBIGBITS 64
    #endif
    #endif

    #ifndef MYBIGBITS
    #include <limits.h>
    #if (LONG_MAX >> 31) >> 31 >= 1
    typedef long MyBigInt;
    #define MYBIGBITS 64
    #elif (LLONG_MAX >> 31) >> 31 >= 1
    /* non-conforming but helpful C90 */
    typedef long long MyBigInt;
    #define MYBIGBITS 64
    #else
    /* oh, well -- better luck next time */
    typedef long MyBigInt;
    #define MYBIGBITS 32
    #endif
    #endif

    > Also, what is the standard include file which would be needed to have
    > the int64_t typedef included? I see it in <stdint.h> on one compiler
    > I have, and <native.h> on another. I don't see these headers being
    > included by other standard headers on these systems.


    C99 specifies <stdint.h> but not <native.h>. C90 specifies
    neither, so don't try to #include it until you've established
    that you've got a C99 implementation.

    --
    Eric Sosman, Aug 11, 2005
    #7
  8. Eric Sosman wrote:
    [...]
    > `#if __STDC_VERSION__ >= 199901L' means "C99 or later"
    > and implies the existence of the <stdint.h> header. Having
    > included this header, you can then check for the presence
    > of macros like INT64_MAX or UINT_LEAST64_MAX (depending on
    > whether you want signed or unsigned, exactly or at least 64
    > bits).

    [...]

    Thanks for the pointers.

    However, what happens when __STDC_VERSION__ isn't defined at all? (I
    suppose this obviously means "not C99".) Neither "cc" under SCO Unix,
    nor MSVC 6.0 define this. (I haven't tried any other platforms yet.)

    That's 2 underscores, "STDC", one underscore, "VERSION", two underscores.
    Correct?

    In any case, I'm going to be stuck with "yet another config item", as it
    doesn't look like all the systems we run on have enough to automatically
    determine it.

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Aug 11, 2005
    #8
  9. Kenneth Brody

    Eric Sosman Guest

    Kenneth Brody wrote:
    > Eric Sosman wrote:
    > [...]
    >
    >> `#if __STDC_VERSION__ >= 199901L' means "C99 or later"
    >>and implies the existence of the <stdint.h> header. Having
    >>included this header, you can then check for the presence
    >>of macros like INT64_MAX or UINT_LEAST64_MAX (depending on
    >>whether you want signed or unsigned, exactly or at least 64
    >>bits).

    >
    > [...]
    >
    > Thanks for the pointers.
    >
    > However, what happens when __STDC_VERSION__ isn't defined at all? (I
    > suppose this obviously means "not C99".) Neither "cc" under SCO Unix,
    > nor MSVC 6.0 define this. (I haven't tried any other platforms yet.)


    An identifier that isn't defined as a macro evaluates
    as zero for the purposes of #if. 6.10.1/2:

    "[...] After all replacements due to macro expansion
    and the defined unary operator have been performed,
    all remaining identifiers are replaced with the pp-
    number 0, [...]"

    (Personally, I wish the ANSI committee had not defined the
    language this way; the "anything unrecognized is zero" rule
    makes spellnig errors potentially more damaging. However,
    that particular horse is no longer proximal to the barn.)

    > That's 2 underscores, "STDC", one underscore, "VERSION", two underscores.
    > Correct?


    Correct. See 6.10.8/1.

    --
    Eric Sosman, Aug 11, 2005
    #9
  10. Eric Sosman wrote:
    >
    > Kenneth Brody wrote:
    > > Eric Sosman wrote:
    > > [...]
    > >
    > >> `#if __STDC_VERSION__ >= 199901L' means "C99 or later"

    [...]
    > > However, what happens when __STDC_VERSION__ isn't defined at all? (I
    > > suppose this obviously means "not C99".) Neither "cc" under SCO Unix,
    > > nor MSVC 6.0 define this. (I haven't tried any other platforms yet.)

    >
    > An identifier that isn't defined as a macro evaluates
    > as zero for the purposes of #if. 6.10.1/2:


    Well, that helps for "#if __STDC_VERSION__ >= 199901L", but it doesn't
    help my test of printf("%ld\n",__STDC_VERSION__);. ;-)

    [...]
    > > That's 2 underscores, "STDC", one underscore, "VERSION", two underscores.
    > > Correct?

    >
    > Correct. See 6.10.8/1.


    Thanks. I just wanted to make sure I didn't have a typo.

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Aug 12, 2005
    #10
  11. Kenneth Brody

    CBFalconer Guest

    Kenneth Brody wrote:
    > Eric Sosman wrote:
    >> Kenneth Brody wrote:
    >>> Eric Sosman wrote:
    >>> [...]
    >>>
    >>>> `#if __STDC_VERSION__ >= 199901L' means "C99 or later"

    > [...]
    >>> However, what happens when __STDC_VERSION__ isn't defined at all?
    >>> (I suppose this obviously means "not C99".) Neither "cc" under
    >>> SCO Unix, nor MSVC 6.0 define this. (I haven't tried any other
    >>> platforms yet.)

    >>
    >> An identifier that isn't defined as a macro evaluates
    >> as zero for the purposes of #if. 6.10.1/2:

    >
    > Well, that helps for "#if __STDC_VERSION__ >= 199901L", but it
    > doesn't help my test of printf("%ld\n",__STDC_VERSION__);. ;-)
    >
    > [...]
    >>> That's 2 underscores, "STDC", one underscore, "VERSION", two
    >>> underscores. Correct?

    >>
    >> Correct. See 6.10.8/1.

    >
    > Thanks. I just wanted to make sure I didn't have a typo.


    You need these gyrations to investigate, since __STDC_VERSION__ is
    not mentioned in C89:

    #include <stdio.h>

    int main(void)
    {
    #ifdef __STDC__
    printf("__STDC__ = %d\n", __STDC__);
    # ifdef __STDC_VERSION__
    printf("__STDC_VERSION__ = %ld\n", __STDC_VERSION__);
    # else
    printf("__STDC_VERSION__ undefined\n");
    # endif
    #else
    printf("__STDC__ undefined\n");
    #endif
    return 0;
    }

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
    CBFalconer, Aug 12, 2005
    #11
    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. Steve Green

    java needs typedef

    Steve Green, Mar 24, 2005, in forum: Java
    Replies:
    11
    Views:
    11,356
    Joona I Palaste
    Mar 25, 2005
  2. qazmlp

    typedef enum

    qazmlp, Jul 2, 2003, in forum: C++
    Replies:
    2
    Views:
    453
    Alexander Terekhov
    Jul 2, 2003
  3. Robert A. T. Kaldy

    template typedef as return type

    Robert A. T. Kaldy, Jul 9, 2003, in forum: C++
    Replies:
    1
    Views:
    406
    Michael Kochetkov
    Jul 9, 2003
  4. Richard van Wegen

    Typedef of a template?

    Richard van Wegen, Jul 14, 2003, in forum: C++
    Replies:
    3
    Views:
    436
    Richard van Wegen
    Jul 15, 2003
  5. oor
    Replies:
    0
    Views:
    1,331
Loading...

Share This Page