Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   #if typedef() (http://www.velocityreviews.com/forums/t439050-if-typedef.html)

Kenneth Brody 08-11-2005 03:09 PM

#if typedef()
 
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:ThisIsASpamTrap@gmail.com>


Walter Roberson 08-11-2005 04:18 PM

Re: #if typedef()
 
In article <42FB6A21.DE1B10B5@spamcop.net>,
Kenneth Brody <kenbrody@spamcop.net> 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!

Kenneth Brody 08-11-2005 04:38 PM

Re: #if typedef()
 
Walter Roberson wrote:
>
> In article <42FB6A21.DE1B10B5@spamcop.net>,
> Kenneth Brody <kenbrody@spamcop.net> 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:ThisIsASpamTrap@gmail.com>


Keith Thompson 08-11-2005 04:41 PM

Re: #if typedef()
 
Kenneth Brody <kenbrody@spamcop.net> 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) kst-u@mib.org <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 08-11-2005 04:57 PM

Re: #if typedef()
 
Kenneth Brody <kenbrody@spamcop.net> 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) kst-u@mib.org <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.

Flash Gordon 08-11-2005 05:08 PM

Re: #if typedef()
 
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.

Eric Sosman 08-11-2005 05:08 PM

Re: #if typedef()
 


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@sun.com


Kenneth Brody 08-11-2005 05:36 PM

Re: #if typedef()
 
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:ThisIsASpamTrap@gmail.com>


Eric Sosman 08-11-2005 06:21 PM

Re: #if typedef()
 


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@sun.com


Kenneth Brody 08-12-2005 06:06 PM

Re: #if typedef()
 
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:ThisIsASpamTrap@gmail.com>



All times are GMT. The time now is 08:31 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.