standard change

  • Thread starter Bill Cunningham
  • Start date
C

CBFalconer

Keith said:
.... snip ...

The standard requires conforming implementations to define __STDC__,
but it can't forbid non-conforming implementations to do so.

However, the marketplace can. A compiler system that fails to
conform normally does so for a good reason, and thus needs to
cooperate in warning its users of non-standardisms. Thus there is
no incentive for defining __STDC__ in illsuited places.
 
D

Dan Pop

In said:
However, the marketplace can. A compiler system that fails to
conform normally does so for a good reason, and thus needs to
cooperate in warning its users of non-standardisms. Thus there is
no incentive for defining __STDC__ in illsuited places.

Actually, the market place has acted in the opposite direction: because
__STDC__ was almost exclusively used to test whether the compiler
supports prototypes, some compilers supporting prototypes define it even
when invoked in non-conforming mode. Try the following example while
invoking your compiler in non-conforming mode and see what you get.

fangorn:~/tmp 42> cat test.c
#include <stdio.h>

int main()
{
#if __STDC__ == 1
puts("The compiler pretends to be standard-conforming.");
#else
puts("The compiler has been invoked in non-conforming mode.");
#endif
return 0;
}
fangorn:~/tmp 43> gcc test.c
fangorn:~/tmp 44> ./a.out
The compiler pretends to be standard-conforming.

Some compilers do the right thing and still define __STDC__ in
non-conforming mode, but give it a different value than 1. Programs that
assume that prototypes are available if __STDC__ is merely defined still
work as intended.

Dan
 
D

Dan Pop

In said:
I see the smiley, but just to make sure I wrote what I actually meant
...

A compiler that, for example, doesn't support prototypes is obviously
non-conforming. If it defines __STDC__, it doesn't become any more
non-conforming than it already was.

That's not what you wrote above, but it's still wrong. The C standard
kindly asks non-conforming compilers not to define __STDC__ as 1. They
can still define __STDC__ as anything else.
The standard requires conforming implementations to define __STDC__,
but it can't forbid non-conforming implementations to do so.

Again, the standard doesn't even try to get a monopoly on __STDC__, it's
only the value 1 that it reserves for this macro.

But your whole analogy with "#pragma once" is broken, because the
standard is not reserving any semantics for it. So, two *conforming*
implementations can legitimately and with bona fide assign different
semantics to this pragma.

Dan
 
C

CBFalconer

Dan said:
Actually, the market place has acted in the opposite direction: because
__STDC__ was almost exclusively used to test whether the compiler
supports prototypes, some compilers supporting prototypes define it even
when invoked in non-conforming mode. Try the following example while
invoking your compiler in non-conforming mode and see what you get.

fangorn:~/tmp 42> cat test.c
#include <stdio.h>

int main()
{
#if __STDC__ == 1
puts("The compiler pretends to be standard-conforming.");
#else
puts("The compiler has been invoked in non-conforming mode.");
#endif
return 0;
}
fangorn:~/tmp 43> gcc test.c
fangorn:~/tmp 44> ./a.out
The compiler pretends to be standard-conforming.

Some compilers do the right thing and still define __STDC__ in
non-conforming mode, but give it a different value than 1. Programs
that assume that prototypes are available if __STDC__ is merely
defined still work as intended.

Aren't you confusing "standard-conforming" with "has extensions"?
I believe than any program that gcc compiles successfully with -W
-Wall -ansi -pedantic will also compile with the same gcc and no
flags.
 
J

Jeremy Yallop

CBFalconer said:
I believe than any program that gcc compiles successfully with -W
-Wall -ansi -pedantic will also compile with the same gcc and no
flags.

Counterexample:

$ cat gcc.c
int main(int typeof, char **b) { return typeof != 0; }
$ gcc -W -Wall -ansi -pedantic gcc.c
$ gcc gcc.c
gcc.c:1: parse error before "typeof"
gcc.c: In function `main':
gcc.c:1: parse error before "typeof"

Jeremy.
 
C

CBFalconer

Jeremy said:
CBFalconer said:
I believe than any program that gcc compiles successfully with -W
-Wall -ansi -pedantic will also compile with the same gcc and no
flags.

Counterexample:

$ cat gcc.c
int main(int typeof, char **b) { return typeof != 0; }
$ gcc -W -Wall -ansi -pedantic gcc.c
$ gcc gcc.c
gcc.c:1: parse error before "typeof"
gcc.c: In function `main':
gcc.c:1: parse error before "typeof"


OK, so my statement is not strictly true. The above is due to the
use of extended keywords, however, so the error would be better
phrased as:

invalid use of keyword "typeof".

and is an illustration of why such extensions should be kept in
the implementors namespace. C99s use of _Bool and bool are a good
example.
 
E

E. Robert Tisdale

Bill said:
I only wanted the headers to be included once.
The compiler said something about obsolete.

#ifndef GUARD_FILE_H
#define GUARD_FILE_H 1
// contents of header file
#endif//GUARD_FILE_H

The C preprocessor is smart enough to distinguish
*idempotent* header files from the "guard" macros.
It remembers which header files are idempotent
and will *not* read them again
so your #pragma once is no longer necessary.
 
K

Keith Thompson

That's not what you wrote above, but it's still wrong. The C standard
kindly asks non-conforming compilers not to define __STDC__ as 1. They
can still define __STDC__ as anything else.

Ok, I was imprecise; I referred to defining __STDC__ (which the
standard doesn't address) when I should have referred to defining
__STDC__ as 1 (which it does). (And yes, that is what I wrote
earlier, but let's not waste everyone's time arguing about it.)
But your whole analogy with "#pragma once" is broken, because the
standard is not reserving any semantics for it. So, two *conforming*
implementations can legitimately and with bona fide assign different
semantics to this pragma.

Strictly speaking, that's true. On the other hand, there are several
compilers, including gcc, that implement "#pragma once" with the
obvious semantics. I know of none that implement it with any other
semantics. I think it's common enough that nobody is likely to
implement "#pragma once" with something radically different from the
existing (implementation-defined) semantics. That's why I wrote
"probably reasonable if you're careful about it" rather than
"perfectly portable and safe".

On the other hand, an old version of gcc responded to all #pragmas by
playing rogue, so assuming limits to compiler perversity isn't
*entirely* safe. (The DS9000 C compiler probably interprets "pragma
#once" as a directive to print the next 11 error messages in Spanish.)

On the other other hand, the guard trick has the advantage of being
portable; the only advantage of "#pragma once" (if it works) is that
it avoids opening the file *on some implementations*, and that's
probably insignificant on modern systems. I don't think I've ever
used "#pragma once" myself.
 
K

Keith Thompson

E. Robert Tisdale said:
#ifndef GUARD_FILE_H
#define GUARD_FILE_H 1
// contents of header file
#endif//GUARD_FILE_H

The C preprocessor is smart enough to distinguish
*idempotent* header files from the "guard" macros.
It remembers which header files are idempotent
and will *not* read them again
so your #pragma once is no longer necessary.

Correction: *some* implementations of the C preprocessor are smart
enough to recognize "guard" macros and avoid re-reading the file.

Even for those that aren't quite that smart, though, "#pragma once"
only saves a small amount of overhead; it's probably not worth
worrying about it.
 
A

August Derleth

Chris said:
Perhaps; but what about a compiler for which this means "turn on
ce", as opposed to "#pragma offce" (turning off C.E., whatever that
is)? :) (GCC1 used to recognize *all* #pragma constructs, treating
them as requests to run rogue or nethack.)

I guess this is a big QoI issue. But any implementation so bizarre as to
parse once as on_ce is probably asking to be replaced by a Real Compiler. ;)

As for GCC1 and `#pragma's: I guess I'm assuming that's a joke, but I
know odder things have happened in the world of software. And given that
GCC was a tool originally for the Unix-like GNU system (as opposed to
the UNIX-like Linux system), where you might reasonably assume a rogue
or nethack program to exist, well... could you at least say `#pragma
rogue' or `#pragma nethack' to control /which/ it would launch? ;)
 
E

Eric Sosman

August said:
I guess this is a big QoI issue. But any implementation so bizarre as to
parse once as on_ce is probably asking to be replaced by a Real Compiler. ;)

While "on ce" may be far-fetched, there are certainly
other plausible meanings for "once:"

#pragma once
int main(void) ...

might mean "the main() function will not be called recursively,
so the compiler can take shortcuts in its calling conventions."

A confusion I actually encountered long ago (long enough
that the details have faded from memory) involved two compilers
that supported a "#pragma align N" directive, where N specified
the desired memory alignment for a variable. Unfortunately,
one compiler interpreted N as asking for N-byte alignment while
the other thought of it as asking for 2**N-byte alignment ...
"#pragma align 3" was clearly in the second compiler's style (and
an error to the first compiler), but "#pragma align 4" was
acceptable and meaningful to both -- with different meanings.
 
K

Keith Thompson

August Derleth said:
As for GCC1 and `#pragma's: I guess I'm assuming that's a joke, but I
know odder things have happened in the world of software. And given
that GCC was a tool originally for the Unix-like GNU system (as
opposed to the UNIX-like Linux system), where you might reasonably
assume a rogue or nethack program to exist, well... could you at least
say `#pragma rogue' or `#pragma nethack' to control /which/ it would
launch? ;)

Yes, it was a joke, but it really was implemented that way. It would
first try to run "rogue"; if that failed, it would try to run "hack";
if that failed, it would try to run GNU Emacs displaying the Towers of
Hanoi; if that failed, it would report a fatal error. (I think this
was before "nethack" existed.)

The C90 standard just says that #pragma "causes the implementation to
behave in an implementation-defined manner" (and that unrecognized
pragmas are ignored), so gcc's behavior was conforming, if odd.

Here's an excerpt from the oldest gcc sources I have, version 1.35,
released in 1989 (note the "#if 0"):

#if 0
/* This was a fun hack, but #pragma seems to start to be useful.
By failing to recognize it, we pass it through unchanged to cc1. */

/*
* the behavior of the #pragma directive is implementation defined.
* this implementation defines it as follows.
*/
do_pragma ()
{
close (0);
if (open ("/dev/tty", O_RDONLY, 0666) != 0)
goto nope;
close (1);
if (open ("/dev/tty", O_WRONLY, 0666) != 1)
goto nope;
execl ("/usr/games/hack", "#pragma", 0);
execl ("/usr/games/rogue", "#pragma", 0);
execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
nope:
fatal ("You are in a maze of twisty compiler features, all different");
}
#endif

This version actually handled "#pragma once".

Newer versions of gcc are starting to do something very sensible. All
#pragmas are implemented as "#pragma GCC ..."; if you want to use
"#pragma GCC once", it's unlikely that another compiler will have
defined inconsistent semantics for it. Previously implemented pragmas
are still supported without the "GCC" prefix, but that form is
deprecated.
 

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
474,139
Messages
2,570,806
Members
47,353
Latest member
TamiPutnam

Latest Threads

Top