standard change

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

There must be some change in the standard because I ran into this error when
I put this line in a header.
# pragma once
I only wanted the headers to be included once. The compiler said something
about obsolete.
 
M

Martin Dickopp

Bill Cunningham said:
There must be some change in the standard because I ran into this
error when I put this line in a header.
# pragma once
I only wanted the headers to be included once. The compiler said
something about obsolete.

The behavior of pragmas is implementation-defined (with a few exceptions
in C99, but `#pragma once' is not one of them). Therefore, the compiler
implementor can change the meaning of or deprecate certain pragmas
without violating the standard.

<OT>
In case the compiler in question is the GCC C compiler: Despite being
marked obsolete in the current version, `#pragma once' will continue to
work in future versions.

To quote from <http://gcc.gnu.org/gcc-3.4/changes.html>:
| File handling in the preprocessor has been rewritten. GCC no longer
| gets confused by symlinks and hardlinks, and now has a correct
| implementation of #import and #pragma once. These two directives have
| therefore been un-deprecated.
</OT>

<even more OT>
Shouldn't the antonym of "deprecate" be "precate" instead of
"un-deprecate"? ;)
</even more OT>

Martin
 
M

Martin Ambuhl

Bill said:
There must be some change in the standard because I ran into this error when
I put this line in a header.
# pragma once
I only wanted the headers to be included once. The compiler said something
about obsolete.

Until C99, no particular #pragma had a meaning defined by the standard.
With the new standard, we have a handful of #pragmas with meanings hoped to
have more than implementation-specific meanings. These include
#pragma STDC FP_CONTRACT on-off-switch
#pragma STDC FENV_ACCESS on-off-switch
#pragma STDC CX_LIMITED_RANGE on-off-switch
where on-off-switch is one of ON, OFF, and DEFAULT
These 9 forms may have been supplemented by others that I don't know, but
#pragma once
has _never_ been standard. Since system headers are, at least from C99,
idempotent, and with normal guards your headers can be made effectively so,
there is no need for '#pragma once' as you describe it.
 
J

jacob navia

Lcc-win32 accepts and implements #pragma once.

It is a useful thing: This include header file will never be
loaded again.

Yes, lcc-win32 can't determine if in a complex
network setup a share path of
\\server23\srcdir34\project56\patch45876.h
is the same physical file as
\\serge\prj\patch45876.h

So it will not work. Let's keep it simple. It will not
test for symlinks either.
 
C

CBFalconer

Martin said:
.... snip ...

Shouldn't the antonym of "deprecate" be "precate" instead of
"un-deprecate"? ;)

In the spirit of flammable, inflammable, uninflammable, I offer
dedeprecate :) Just speaking English as she is spoke :)

None of de flames please.
 
L

Leor Zolman

On 01 Feb 2004 21:00:34 +0100, Martin Dickopp
<even more OT>
Shouldn't the antonym of "deprecate" be "precate" instead of
"un-deprecate"? ;)
</even more OT>

Maybe if it were pronounced "dee-precate"... although then I might
vote for re-precate ;-)
-leor
 
A

Alan Balmer

To quote from <http://gcc.gnu.org/gcc-3.4/changes.html>:
| File handling in the preprocessor has been rewritten. GCC no longer
| gets confused by symlinks and hardlinks, and now has a correct
| implementation of #import and #pragma once. These two directives have
| therefore been un-deprecated.
</OT>

I'll continue to deprecate it anyway <g>.
 
E

Emmanuel Delahaye

jacob navia said:
Lcc-win32 accepts and implements #pragma once.
It is a useful thing: This include header file will never be
loaded again.

What's wrong with the standard 'guard' trick?

#ifndef H_XXX
#define H_XXX

....

#endif /* guard */

I have automated it so that the macro tends to be unique.

H_<company or initials>_<file name>_<YYYY><MM><DD><hh><mm><ss>

From my 'str.h':

#ifndef H_AETA_STR_20021226104232
#define H_AETA_STR_20021226104232

....

#endif /* guard */
 
K

Keith Thompson

Emmanuel Delahaye said:
What's wrong with the standard 'guard' trick?

#ifndef H_XXX
#define H_XXX

...

#endif /* guard */

Nothing, really.

The guard trick does impose a slight performance penalty, since it
requires the compiler to re-process the include file every time it's
referenced (unless the compiler is smart enough to recognize it and
optimize it out). Using "#pragma once" can avoid this overhead
(assuming the compiler is always right about whether it's already seen
a given header -- think about symlinks) at the expense of portability.

Using "#pragma once" in combination with the guard trick is probably
reasonable if you're careful about it; a compiler that doesn't
recognize "#pragma once" is required to ignore it.
 
C

Chris Torek

The [include] guard trick does impose a slight performance penalty ...
(unless the compiler is smart enough to recognize it and
optimize it out). Using "#pragma once" can avoid this overhead
(assuming the compiler is always right about whether it's already seen
a given header -- think about symlinks) at the expense of portability.

For what it is worth, gcc -- which is perhaps the main compiler for
which "#pragma once" is used -- *also* does precisely the above
"optimizing out".

I have not looked at the gcc preprocessor code in a while, but
it would be quite reasonable for it to have a data structure
containing a "system unique file ID" (mount point and inode on
a Unix-like system) and "once-only" flag:

struct include_file_info {
md_fileid_type file_id;
int onceonly;
...
};

Then, "#pragma once" sets:

file->onceonly = 1;

but so does "#ifndef GUARD / #define GUARD / ... / #endif", using
one more field in the "include file info":

file->guard_id = identifier_name;

Now "#include" processing just does:

fi = lookup_file_info(...);
if (fi != NULL &&
(fi->onceonly || (fi->guard_id && cpp_ifdef(fi->guard_id))))
... skip the file ...

which means that "#pragma once" is only very slightly more efficient
anyway (because the #ifndef identifier need not be looked up).
Using "#pragma once" in combination with the guard trick is probably
reasonable if you're careful about it; a compiler that doesn't
recognize "#pragma once" is required to ignore it.

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.)
 
R

Richard Heathfield

Keith said:
Using "#pragma once" in combination with the guard trick is probably
reasonable if you're careful about it; a compiler that doesn't
recognize "#pragma once" is required to ignore it.

A compiler might legitimately (or, at least, legally!) recognise #pragma
once, but with different semantics. Ouch.
 
K

Keith Thompson

Richard Heathfield said:
A compiler might legitimately (or, at least, legally!) recognise #pragma
once, but with different semantics. Ouch.

True -- just as a non-conforming compiler can define __STDC__ without
(further) violating the standard.
 
R

Robert Wessel

Richard Heathfield said:
A compiler might legitimately (or, at least, legally!) recognise #pragma
once, but with different semantics. Ouch.


Presumably a Spanish C compiler will include your header file eleven times. ;-)
 
C

Christian Bau

Keith Thompson said:
Nothing, really.

The guard trick does impose a slight performance penalty, since it
requires the compiler to re-process the include file every time it's
referenced (unless the compiler is smart enough to recognize it and
optimize it out). Using "#pragma once" can avoid this overhead
(assuming the compiler is always right about whether it's already seen
a given header -- think about symlinks) at the expense of portability.

Using "#pragma once" in combination with the guard trick is probably
reasonable if you're careful about it; a compiler that doesn't
recognize "#pragma once" is required to ignore it.

A scheme that safely avoids re-preprocessing an include file in most
cases is not too too difficult. A very simple scheme would be to check
that a file starts with #ifndef, has no matching #else or #elif, and
ends with the matching #endif. That would probably cover 90% of all the
cases at minimal cost and doesn't force the user to use non-portable
code.
 
R

Robert Wessel

Richard Heathfield said:
A compiler might legitimately (or, at least, legally!) recognise #pragma
once, but with different semantics. Ouch.


Presumably a Spanish C compiler will include your header file eleven times. ;-)
 
D

Dan Pop

In said:
Using "#pragma once" in combination with the guard trick is probably
reasonable if you're careful about it; a compiler that doesn't
recognize "#pragma once" is required to ignore it.

OTOH, a compiler is free to assign completely different semantics to
"#pragma once", so its usage is never safe in portable code.

Dan
 
D

Dan Pop

In said:
True -- just as a non-conforming compiler can define __STDC__ without
(further) violating the standard. ^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Then, it is, *by definition* a conforming compiler ;-)

Dan
 
A

Alan Balmer

The [include] guard trick does impose a slight performance penalty ...
(unless the compiler is smart enough to recognize it and
optimize it out). Using "#pragma once" can avoid this overhead
(assuming the compiler is always right about whether it's already seen
a given header -- think about symlinks) at the expense of portability.

For what it is worth, gcc -- which is perhaps the main compiler for
which "#pragma once" is used -- *also* does precisely the above
"optimizing out".
The first place I encountered it was in Microsoft headers.

All the compilers I use have the capability of using precompiled
headers, which is even more efficient than #pragma once.
 
K

Keith Thompson

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Then, it is, *by definition* a conforming compiler ;-)

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.

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

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