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

size_t and C90/C99

73 views
Skip to first unread message

Pedro Graca

unread,
Feb 11, 2006, 6:17:06 PM2/11/06
to
#include <stdio.h>

#ifdef C99
#define FMT_STRING "The value is %zu.\n"
#define CAST_SIZE_T
#else
#define FMT_STRING "The value is %lu.\n"
#define CAST_SIZE_T (unsigned long)
#endif

int main(void) {
size_t val=42;

printf(FMT_STRING, CAST_SIZE_T val);
return 0;
}


I don't even know for sure if the C99 macro is defined in my
implementation ... but the code compiled and run without glitches with
gcc

gcc -W -Wall -std=c89 -pedantic c9099.c -oc90
gcc -W -Wall -std=c99 -pedantic c9099.c -oc99


My questions are:

a) Is there a standard way to identify the standard being used to
compile the program (the "C99" predefined macro?)?

b) Is the way I used #ifdef usual accepted practice to code for the two
standards?

--
If you're posting through Google read <http://cfaj.freeshell.org/google>

Eric Sosman

unread,
Feb 11, 2006, 7:29:50 PM2/11/06
to
Pedro Graca wrote:

> #include <stdio.h>
>
> #ifdef C99
> #define FMT_STRING "The value is %zu.\n"
> #define CAST_SIZE_T
> #else
> #define FMT_STRING "The value is %lu.\n"
> #define CAST_SIZE_T (unsigned long)
> #endif

> [...]


>
> My questions are:
>
> a) Is there a standard way to identify the standard being used to
> compile the program (the "C99" predefined macro?)?

#if __STDC_VERSION >= 199901

> b) Is the way I used #ifdef usual accepted practice to code for the two
> standards?

Nothing wrong with it that I can see.

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

Eric Sosman

unread,
Feb 11, 2006, 7:32:56 PM2/11/06
to
Eric Sosman wrote:
>
> #if __STDC_VERSION >= 199901
> [...]

Oh, drat. __STDC_VERSION__, of course.

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

Pedro Graca

unread,
Feb 11, 2006, 11:17:02 PM2/11/06
to
Eric Sosman wrote:

> Pedro Graca wrote:
>> a) Is there a standard way to identify the standard being used to
>> compile the program (the "C99" predefined macro?)?
>
> #if __STDC_VERSION__ >= 199901

>
>> b) Is the way I used #ifdef usual accepted practice to code for the two
>> standards?
>
> Nothing wrong with it that I can see.
>

Thank you Eric.

Peter Nilsson

unread,
Feb 12, 2006, 5:45:48 AM2/12/06
to
Eric Sosman wrote:
> Pedro Graca wrote:
>
> > #include <stdio.h>
> >
> > #ifdef C99
> > #define FMT_STRING "The value is %zu.\n"
> > #define CAST_SIZE_T
> > #else
> > #define FMT_STRING "The value is %lu.\n"
> > #define CAST_SIZE_T (unsigned long)

In terms of style, a function macro would be better IMO.

> > #endif
> > [...]
> >
> > My questions are:
> >
> > a) Is there a standard way to identify the standard being used to
> > compile the program (the "C99" predefined macro?)?
>

> #if __STDC_VERSION__ >= 199901 [corrected]


>
> > b) Is the way I used #ifdef usual accepted practice to code for the two
> > standards?
>
> Nothing wrong with it that I can see.

__STDC_VERSION__ may be set to something larger than 199901 on a C90
implementation. Using it is therefore potentially unreliable.

My alternative would be...

#include <stdio.h>
#include <limits.h>

#ifdef SIZE_MAX /* C99? */
#define FMT_PRI_SIZE_T "z"
#define CAST_PRI_SIZE_T(sz) ((size_t) (sz))
#else
#define FMT_PRI_SIZE_T "l"
#define CAST_PRI_SIZE_T(sz) ((unsigned long)(size_t) (sz))
#endif

int main(void)
{
printf("Maximum size_t value is %" FMT_PRI_SIZE_T "u.\n",
CAST_PRI_SIZE_T(-1));
return 0;
}

--
Peter

Keith Thompson

unread,
Feb 12, 2006, 5:54:16 AM2/12/06
to
"Peter Nilsson" <ai...@acay.com.au> writes:
[...]

> __STDC_VERSION__ may be set to something larger than 199901 on a C90
> implementation. Using it is therefore potentially unreliable.

Theoretically, yes, but I don't think that's a realistic concern.
Since the C90 standard doesn't mention __STDC_VERSION__, a C90
compiler can define it any way it likes -- but an implementation that
sets it to something larger than 199901L would be deliberately lying,
and you wouldn't be able to depend on *anything* it tells you.

If the compiler lies to me, I will get my revenge.

--
Keith Thompson (The_Other_Keith) ks...@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.

Peter Nilsson

unread,
Feb 12, 2006, 8:59:07 AM2/12/06
to
Keith Thompson wrote:
> "Peter Nilsson" <ai...@acay.com.au> writes:
> [...]
> > __STDC_VERSION__ may be set to something larger than 199901 on a C90
> > implementation. Using it is therefore potentially unreliable.
>
> Theoretically, yes, but I don't think that's a realistic concern.

I don't think so either, but not for the same reason that you do.

I don't think it's a concern because I think the few C90
implementations that bother to specify __STDC_VERSION__
will be those that came in after the normative additions to C90.

> Since the C90 standard doesn't mention __STDC_VERSION__, a C90
> compiler can define it any way it likes -- but an implementation that
> sets it to something larger than 199901L would be deliberately lying,

Why would it be a _deliberate_ lie? For decades, I've been using
YYYYMMDD style in version constants of my own, even when the
gap between versions is likely to be months (even years).

I don't see why an implementor of C90 in the late 80s, who didn't
have the luxury of a crystal ball, would think that 19891101 (say)
would be unusual, let alone a _deliberate_ attempt to usurp
future C programmers!

> and you wouldn't be able to depend on *anything* it tells you.

Even gcc ports can be made to set __STDC__ to 1 in _non_ conforming
mode. Do you still trust gcc? I do, for the most part.

> If the compiler lies to me, I will get my revenge.

I just ask the author to modify future updates, or I hack the
compiler (or more likely a default header) myself. I don't call
it revenge, I just call it fixing a problem. But in reality, in this
case, it would be fixing a problem of my own making.

--
Peter

Keith Thompson

unread,
Feb 12, 2006, 10:07:51 AM2/12/06
to
"Peter Nilsson" <ai...@acay.com.au> writes:
> Keith Thompson wrote:
>> "Peter Nilsson" <ai...@acay.com.au> writes:
>> [...]
>> > __STDC_VERSION__ may be set to something larger than 199901 on a C90
>> > implementation. Using it is therefore potentially unreliable.
>>
>> Theoretically, yes, but I don't think that's a realistic concern.
>
> I don't think so either, but not for the same reason that you do.
>
> I don't think it's a concern because I think the few C90
> implementations that bother to specify __STDC_VERSION__
> will be those that came in after the normative additions to C90.

Sure, Amendment 1 (1995) introduced __STDC_VERSION__ and specified a
value of 199409L.

>> Since the C90 standard doesn't mention __STDC_VERSION__, a C90
>> compiler can define it any way it likes -- but an implementation that
>> sets it to something larger than 199901L would be deliberately lying,
>
> Why would it be a _deliberate_ lie? For decades, I've been using
> YYYYMMDD style in version constants of my own, even when the
> gap between versions is likely to be months (even years).
>
> I don't see why an implementor of C90 in the late 80s, who didn't
> have the luxury of a crystal ball, would think that 19891101 (say)
> would be unusual, let alone a _deliberate_ attempt to usurp
> future C programmers!

Before Amendment 1 was released, such an implementer would have had to
independently invent the name __STDC_VERSION__, which seems unlikely
(and I've never heard of an implementation that actually did so).
After Amendment 1, the meaning was established, and it's hard to
imagine that setting it to anything greater than 199901L would be
anything but a deliberate lie.

(This is all hypothetical, of course.)

0 new messages