Is it ok to define __STDC_VERSION__?

  • Thread starter =?ISO-8859-1?Q?Bj=F8rn_Augestad?=
  • Start date
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Hi,

I currently use a compiler which emits a warning on the following statement:
#if defined(__STDC_VERSION__) || __STDC_VERSION__ < 19990601L
....
#endif

The compiler complains that __STDC_VERSION__ isn't defined. It obviously
doesn't short circuit the expression, but evaluates both sides of the
||. I have, as a workaround, changed the statements into this:

#if !defined(__STDC_VERSION__)
#define __STDC_VERSION__ 0
#endif

#if __STDC_VERSION__ < 19990601L
....
#endif

Apart from any typos, is it legal to define __STDC_VERSION__ in user code?
 
E

Eric Sosman

Bjørn Augestad said:
Hi,

I currently use a compiler which emits a warning on the following statement:
#if defined(__STDC_VERSION__) || __STDC_VERSION__ < 19990601L
...
#endif

The compiler complains that __STDC_VERSION__ isn't defined. It obviously
doesn't short circuit the expression, but evaluates both sides of the
||. [...]

As it should, if __STDC_VERSION__ isn't defined. Are
you sure you're not missing a `!' at the beginning of the
test expression?

#if !defined(__STDC_VERSION__) || ...
^
 
A

Arthur J. O'Dwyer

I currently use a compiler which emits a warning on the following statement:
#if defined(__STDC_VERSION__) || __STDC_VERSION__ < 19990601L
...
#endif

The compiler complains that __STDC_VERSION__ isn't defined. It obviously
doesn't short circuit the expression, but evaluates both sides of the
||. I have, as a workaround, changed the statements into this:

#if !defined(__STDC_VERSION__)
#define __STDC_VERSION__ 0
#endif

#if __STDC_VERSION__ < 19990601L
...
#endif

Apart from any typos, is it legal to define __STDC_VERSION__ in user code?

Hallvard has kindly tracked down the bit of the standard that makes this
invalid. However, an equivalent but legal workaround would be

#ifndef __STDC_VERSION__
#define C_VERSION_NUMBER 0
#else
#define C_VERSION_NUMBER __STDC_VERSION__
#endif

#if C_VERSION_NUMBER < 19990601L
....
#endif

or anything along those lines.

Note that your compiler may be complaining about __STDC_VERSION__'s not
being defined, but if it actually refuses to compile your program because
of this, it's not conforming to the Standard in more than one way.
I myself also subscribe to the idea of getting rid of even the most
harmless warnings, though.

-Arthur
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Eric said:
Bjørn Augestad said:
Hi,

I currently use a compiler which emits a warning on the following statement:
#if defined(__STDC_VERSION__) || __STDC_VERSION__ < 19990601L
...
#endif

The compiler complains that __STDC_VERSION__ isn't defined. It obviously
doesn't short circuit the expression, but evaluates both sides of the
||. [...]


As it should, if __STDC_VERSION__ isn't defined. Are
you sure you're not missing a `!' at the beginning of the
test expression?

#if !defined(__STDC_VERSION__) || ...
^

My apologies to all that has answered the original post, which had a
very sloppy and incorrect illustration of the problem. For some stupid
reason I decided to write the code instead of copying it from the source
file, and I even mixed in elements from _POSIX_C_SOURCE. Duh.

Here is the exact code causing problems. It's from the libclc file
clc_settings.h and causes problems on the st20cc cross compiler v. 1.9.6
(windows version) for the os20 embedded os:

/* Handle differences between C89 and C99 */
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
# define CLC_RESTRICT
#else
# define CLC_RESTRICT restrict
#endif


Thanks again to all. I'll experiment more with the compiler on monday
and try to come up with a portable and working solution.
 
E

Eric Sosman

Bjørn Augestad said:
Here is the exact code causing problems. It's from the libclc file
clc_settings.h and causes problems on the st20cc cross compiler v. 1.9.6
(windows version) for the os20 embedded os:

/* Handle differences between C89 and C99 */
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
# define CLC_RESTRICT
#else
# define CLC_RESTRICT restrict
#endif

Thanks again to all. I'll experiment more with the compiler on monday
and try to come up with a portable and working solution.

Actually, the `defined' piece is unnecessary:

#if __STDC_VERSION__ < 199901L

is a portable solution, because any unrecognized identifiers
in an #if or #elif directive are replaced with zeroes.

Another formulation found favor with pre-Standard compilers,
some of whose preprocessors simply deleted unrecognized names
in such expressions:

#if __STDC_VERSION__ + 0 < 199901L

the idea being that you'd wind up with `value + 0' or with
`0 + 0' (the Standard answers) or with unadorned `+ 0' (for
some pre-Standard compilers). You might want to see if this
old dodge might calm your compiler's nervousness.

Finally, there's Arthur O'Dwyer's suggestion, using the
defined-ness of __STDC_VERSION__ to govern the definition of
an "intermediate" symbol, and then testing that symbol. For
the case at hand, you could eliminate the intermediate with
some extra coding:

#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
#define CLC_RESTRICT restrict
#endif
#endif
#ifndef CLC_RESTRICT
#define CLC_RESTRICT /* nil */
#endif

This, I think, stands the best chance of quieting the
whines -- but nothing's guaranteed; the compiler is within
its rights to complain about the vapidity of American beer,
if it so chooses. It must, though, accept and translate
your code (barring other problems, of course).
 
E

Ed Morton

Hi,
I currently use a compiler which emits a warning on the following statement:
#if defined(__STDC_VERSION__) || __STDC_VERSION__ < 19990601L
^^
Shouldn't that be an "&&"?

Ed.
 
M

Mark McIntyre

Hi,

I currently use a compiler which emits a warning on the following statement:
#if defined(__STDC_VERSION__) || __STDC_VERSION__ < 19990601L
...
#endif

The compiler complains that __STDC_VERSION__ isn't defined.

Is it a pre-ANSI compiler, and you're trying to use a header that
doesn't belong to it? Did you a header from some another
implementation?
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Mark said:
Is it a pre-ANSI compiler,

Pre C99, but post C89 AFAIK. ;-)
The st20cc compiler is quite nice to work with, apart for a few quirks.

and you're trying to use a header that
doesn't belong to it? Did you a header from some another
implementation?

Pretty sure I don't, I'll check it though. I just get a warning about
__STDC_VERSION__ beeing undefined when I compile the libclc source code,
a warning I'd like to get rid of. The rest of libclc worked perfectly
from day one, BTW. :)
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Eric Sosman wrote:

[snip]
Actually, the `defined' piece is unnecessary:

#if __STDC_VERSION__ < 199901L

is a portable solution, because any unrecognized identifiers
in an #if or #elif directive are replaced with zeroes.

That's what I thought too, but according to the official libclc archives
(aka google, http://tinyurl.com/gpss), the "#if !defined" construct has
been there since day one, code written by Dan Pop. I assume he had a
reason to do it like that, instead of just writing
#if __STDC_VERSION__ < 199901L ?


[...]
Finally, there's Arthur O'Dwyer's suggestion, using the
defined-ness of __STDC_VERSION__ to govern the definition of
an "intermediate" symbol, and then testing that symbol. For
the case at hand, you could eliminate the intermediate with
some extra coding:

#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
#define CLC_RESTRICT restrict
#endif
#endif
#ifndef CLC_RESTRICT
#define CLC_RESTRICT /* nil */
#endif

This, I think, stands the best chance of quieting the
whines -- but nothing's guaranteed; the compiler is within
its rights to complain about the vapidity of American beer,
if it so chooses. It must, though, accept and translate
your code (barring other problems, of course).

Looks fool proof to me and is most likely the way to go. :)
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
I currently use a compiler which emits a warning on the following
statement: #if defined(__STDC_VERSION__) || __STDC_VERSION__ < 19990601L

Try with &&.
 
D

Dan Pop

In said:
Actually, the `defined' piece is unnecessary:

#if __STDC_VERSION__ < 199901L

is a portable solution, because any unrecognized identifiers
in an #if or #elif directive are replaced with zeroes.

Nope, it ain't, because __STDC_VERSION__ may be any kind of preprocessor
magic which isn't a macro. So, before attempting to use it as a macro,
you *have* to check that a macro with this name is defined.

Your argument would have worked for STDC_VERSION, but thingies starting
with __ are special.

Dan
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Dan Pop wrote:
[snip]
You can try rewriting the code like this, but there is no guarantee that
the broken preprocessor won't barf again:

#if !defined __STDC_VERSION__
# define CLC_RESTRICT
#elif __STDC_VERSION__ < 199901L
# define CLC_RESTRICT
#else
# define CLC_RESTRICT restrict
#endif

If it works, throw in a comment explaining the goofy code.

It didn't work. Now the compiler whines about the #elif using an
undefined macro. I guess I can live with that one warning, as the rest
of libclc works like a charm. :)

Thanks.
 

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

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top