Correspondence between headers and macros

S

spibou

My understanding is that when you write a library
then the header should be of the form
#ifndef macro_corresponding_to_the_library
#define macro_corresponding_to_the_library
..
.. ...definitions...
..
#endif

This prevents the objects in the library to be
defined more than once in case the header gets
included more than once. Assuming that I got that
correctly my question is whether there is some
convention which connects the name of the header
with the name of the macro. If no widespread convention
exists do you have any suggestions about a rule which
gives a macro name from a header name ?

Spiros Bousbouras
 
B

Ben Pfaff

My understanding is that when you write a library
then the header should be of the form
#ifndef macro_corresponding_to_the_library
#define macro_corresponding_to_the_library
.
. ...definitions...
.
#endif

This prevents the objects in the library to be
defined more than once in case the header gets
included more than once.

Multiple definitions of objects aren't the problem being solved.
You can put "extern int x;" into a translation unit as many times
as you like and the effect is the same. (This is not, in fact, a
definition; it's merely a declaration.)

The problem is multiple definitions of entities that may only be
defined once per translation unit; for example, structures.
Assuming that I got that correctly my question is whether there
is some convention which connects the name of the header with
the name of the macro. If no widespread convention exists do
you have any suggestions about a rule which gives a macro name
from a header name ?

There is no universally accepted convention. What I would do is
to use a macro name from a name space reserved by the library in
question. For example, if your library is named foolib, so that
all of its declared names start with "foolib_", then you could
use "foolib_h" or "FOOLIB_H" as the macro name.
 
E

Eric Sosman

My understanding is that when you write a library
then the header should be of the form
#ifndef macro_corresponding_to_the_library
#define macro_corresponding_to_the_library

`macro_corresponding_to_the_header' would be better.
There is not necessarily a one-to-one correspondence
between headers and "libraries." (Consider the number of
different headers associated with the Standard library,
for example.)
.
. ...definitions...
.
#endif

This prevents the objects in the library to be
defined more than once in case the header gets
included more than once. Assuming that I got that
correctly my question is whether there is some
convention which connects the name of the header
with the name of the macro. If no widespread convention
exists do you have any suggestions about a rule which
gives a macro name from a header name ?

The name of the header usually forms part of the name
of the macro. If the header is called "grizzle.h", some
people use GRIZZLE_H as the macro name. That scheme, though,
has a flaw: for a header called "eyes.h" the recipe would
suggest EYES_H, but macro names starting with E and another
upper-case letter may clash with <errno.h>. As an alternative,
I'd suggest using H_EYES and H_GRIZZLE.

One thing you should *not* do is imitate what you find in
the standard headers that come with your implementation. They
will often have inclusion-guard macros with names like _TIME_H
or _STDIO_H, and many people have been seduced into thinking
they should use the same scheme for their own headers: _EYES_H
and _GRIZZLE_H. But the reason for the leading underscore is
specifically to avoid collisions with user-defined macros --
the implementation is scrupulously avoiding the name space that
belongs to you. The flip side of that agreement is that you
should in turn avoid the implementation's name space; if it
turns out that the implementation defines _GRIZZLE_H for its
own purposes and this messes up your header file, you have only
yourself to blame.
 
S

spibou

Ben said:
Multiple definitions of objects aren't the problem being solved.
You can put "extern int x;" into a translation unit as many times
as you like and the effect is the same. (This is not, in fact, a
definition; it's merely a declaration.)

Yes , of course ; I meant declarations. But wouldn't multiple
declarations in the same unit produce warnings even if they
won't affect the executable ?
The problem is multiple definitions of entities that may only be
defined once per translation unit; for example, structures.

I didn't choose the terminology in my previous post with sufficient
care. I used the word "object" but I really meant anything we can be
defined/declared in C ie variables , structures , macros , data types
etc.

So the point of the technique I mentioned is to prevent some of these
to be defined more than once in the same unit , right ?
 
B

Ben Pfaff

Yes , of course ; I meant declarations. But wouldn't multiple
declarations in the same unit produce warnings even if they
won't affect the executable ?

No, most compilers won't warn about it.
I didn't choose the terminology in my previous post with sufficient
care. I used the word "object" but I really meant anything we can be
defined/declared in C ie variables , structures , macros , data types
etc.

So the point of the technique I mentioned is to prevent some of these
to be defined more than once in the same unit , right ?

Yes, that's correct.
 
J

jacob navia

(e-mail address removed) a écrit :
My understanding is that when you write a library
then the header should be of the form
#ifndef macro_corresponding_to_the_library
#define macro_corresponding_to_the_library
.
. ...definitions...
.
#endif

This prevents the objects in the library to be
defined more than once in case the header gets
included more than once. Assuming that I got that
correctly my question is whether there is some
convention which connects the name of the header
with the name of the macro. If no widespread convention
exists do you have any suggestions about a rule which
gives a macro name from a header name ?

Spiros Bousbouras

To avoid having to invent a name, Microsoft has proposed a

#pragma once

This pragma means that the header file should be included once.
It is very convenient, and it is used in other compilers
that I will not mention :)
 
R

Richard Heathfield

jacob navia said:

To avoid having to invent a name, Microsoft has proposed a

#pragma once

This pragma means that the header file should be included once.

Or it could mean "launch /usr/games/hack - if that fails, launch
/usr/games/rogue - if that fails, launch emacs, diving straight into its
Towers of Hanoi feature - and if that fails, print a fatal error and quit".

And it did mean precisely that, in at least one C implementation. So it
would be unwise to rely on Microsoft's semantics when writing portable
code.
 
M

Malcolm

jacob navia said:
To avoid having to invent a name, Microsoft has proposed a

#pragma once

This pragma means that the header file should be included once.
It is very convenient, and it is used in other compilers
that I will not mention :)
The inclusion guard workaround is certainly inconvenient.
The problem is that, unless everyone agrees on a standard, it is more
trouble than it is worth to mess about with extensions.
 
J

jacob navia

Richard Heathfield a écrit :
jacob navia said:




Or it could mean "launch /usr/games/hack - if that fails, launch
/usr/games/rogue - if that fails, launch emacs, diving straight into its
Towers of Hanoi feature - and if that fails, print a fatal error and quit".

And it did mean precisely that, in at least one C implementation. So it
would be unwise to rely on Microsoft's semantics when writing portable
code.

#pragma once is supported by

1) MSVC (windows)
2) Intel compiler
2) Comeau C/C++ (Unix and windows)
3) Digital Mars C/C++ (Unix+Windows I think)
4) gcc (versions later than 3.4) (Unix)
5) lcc-win32 (Windows)
6) Delorie C/C++ (MSDOS)
7) MIPS PRO C/C++ (SGI)
8) Code Warrior (MacIntosh version)
9) Digital C++ (Unix)
10) MPW C compiler (Macintosh)
11) The Watcom compiler

What gcc is concerned here is an excerpt of the GCC 3.4 release:
< quote >
Features and fixes
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.
< end quote>

Older versions may complain.


Obviously this is not a portable feature :)
 
R

Richard Heathfield

jacob navia said:
Richard Heathfield a écrit :

#pragma once is supported by

1) MSVC (windows)
2) Intel compiler
2) Comeau C/C++ (Unix and windows)
3) Digital Mars C/C++ (Unix+Windows I think)
4) gcc (versions later than 3.4) (Unix)
5) lcc-win32 (Windows)
6) Delorie C/C++ (MSDOS)
7) MIPS PRO C/C++ (SGI)
8) Code Warrior (MacIntosh version)
9) Digital C++ (Unix)
10) MPW C compiler (Macintosh)
11) The Watcom compiler

Assuming your list is accurate, and removing the ones that aren't actually
used very much, leaves us with:

1) MSVC (windows)
4) gcc (versions later than 3.4) (Unix)
8) Code Warrior (MacIntosh version)

Missing from this list are a number of compilers I've used in what we like
to call The Real World:

1) earlier versions of gcc (some shops work on the basis that "if the
version we're using now does what we need, don't even *think* about
changing it");
2) Borland
3) LE370
4) C/370
5) Norcroft (used fairly heavily in the embedded world)

No doubt others could add to this list if they cared enough.

Obviously this is not a portable feature :)

Precisely so. And therefore I would not dream of recommending its use to
anybody concerned with portability.
 
J

jacob navia

Richard Heathfield a écrit :
jacob navia said:




Assuming your list is accurate, and removing the ones that aren't actually
used very much, leaves us with:

1) MSVC (windows)
4) gcc (versions later than 3.4) (Unix)
8) Code Warrior (MacIntosh version)

Missing from this list are a number of compilers I've used in what we like
to call The Real World:

1) earlier versions of gcc (some shops work on the basis that "if the
version we're using now does what we need, don't even *think* about
changing it");
2) Borland
3) LE370
4) C/370
5) Norcroft (used fairly heavily in the embedded world)

Excuse me but...
The reference Manual for the Norcroft compiler ARM
says in page 2-50
< quote >
2.13.3 Pragmas controlling the preprocessor
....
include_only_once

Asserts that the containing #include file is included
only once, and that if its name recurs in a subsequent
#include directive, the directive is ignored.
< end quote>

Before speaking about them you should read the docs Heathfield.

This is a very ancient compiler, and development seems to have
stopped around 1993... There is a GCC port for the ARM that
explicitely says that the Norcroft compiler is outdated in
their motivation.

Still, pragma once is supported in a slightly different but equivalent form.

No doubt others could add to this list if they cared enough.

No doubt they should first read the docs. I did not follow the
other compilers you mention.
 
R

Richard Heathfield

jacob navia said:
Richard Heathfield a écrit :

Excuse me but...
The reference Manual for the Norcroft compiler ARM
says in page 2-50
< quote >
2.13.3 Pragmas controlling the preprocessor
...
include_only_once

Asserts that the containing #include file is included
only once, and that if its name recurs in a subsequent
#include directive, the directive is ignored.

strcmp("once", "include_only_once") != 0

My point stands.
 
F

Frederick Gotham

jacob navia posted:
#pragma once is supported by
<snip>


Yes, but given that the canonical method of "#ifndef" works 100% of the time,
and given that it is fully Standard-compliant and fully portable, and given
that it isn't really that much hassle to implement:

#ifndef INCLUDE_FILENAME_H
#define INCLUDE_FILENAME_H

/* Header contents go here */

#endif


, I don't think any serious C programmer would opt to use the alternative of
"pragma once" which will not work 100% of the time.

And at the end of the day, "pragma once" just isn't C.
 
J

J. J. Farrell

jacob said:
Richard Heathfield a écrit :

Excuse me but...
The reference Manual for the Norcroft compiler ARM
says in page 2-50
< quote >
2.13.3 Pragmas controlling the preprocessor
...
include_only_once

Asserts that the containing #include file is included
only once, and that if its name recurs in a subsequent
#include directive, the directive is ignored.
< end quote>

How is that in the slightest way relevant? We were talking about files
which contain
#pragma once
Before speaking about them you should read the docs Heathfield.

I'm sure he did, since what he said appears to be entirely accurate.
No doubt they should first read the docs. I did not follow the
other compilers you mention.

No doubt. Understanding the relevance of what they read would also be
useful.
 
K

Keith Thompson

jacob navia said:
Richard Heathfield a écrit :
jacob navia said: [...]
#pragma once is supported by

1) MSVC (windows) [snip]
11) The Watcom compiler
Assuming your list is accurate, and removing the ones that aren't
actually used very much, leaves us with:
1) MSVC (windows)
4) gcc (versions later than 3.4) (Unix)
8) Code Warrior (MacIntosh version)
Missing from this list are a number of compilers I've used in what
we like to call The Real World:
1) earlier versions of gcc (some shops work on the basis that "if
the version we're using now does what we need, don't even *think*
about changing it");
2) Borland
3) LE370
4) C/370
5) Norcroft (used fairly heavily in the embedded world)

Excuse me but...
The reference Manual for the Norcroft compiler ARM
says in page 2-50
< quote >
2.13.3 Pragmas controlling the preprocessor
...
include_only_once

Asserts that the containing #include file is included
only once, and that if its name recurs in a subsequent
#include directive, the directive is ignored.
< end quote>

Before speaking about them you should read the docs Heathfield.

Right. So Norcroft doesn't support "#pragma once". Were you under
the impression that this supports your argument and refutes Richard's?

There are three ways to achieve the desired effect:

1. #pragma include_only_once
Supported only by Norcroft.

2. #pragma once
Supported by some, but not all compilers.

3. The usual "#ifndef" method.
Supported by every C conforming compiler.

Of course, you could write portable code that *conditionally* uses one
of the above methods, depending on which compiler you're using
(assuming that each compiler defines some unique symbol for this kind
of thing) -- but the result would be far more complex than the
*guaranteed* portable method.

And speaking of reading the documentation, section 11.3.2 of the GNU
cpp.info manual, "Obsolete once-only headers", says:

CPP supports two more ways of indicating that a header file should
be read only once. Neither one is as portable as a wrapper
`#ifndef', and we recommend you do not use them in new programs.

[snip description of "#import"]

Another way to prevent a header file from being included more than
once is with the `#pragma once' directive. If `#pragma once' is
seen when scanning a header file, that file will never be read
again, no matter what.

`#pragma once' does not have the problems that `#import' does, but
it is not recognized by all preprocessors, so you cannot rely on
it in a portable program.

This is under section 11.3, "Obsolete Features":

CPP has a number of features which are present mainly for
compatibility with older programs. We discourage their use in new
code. In some cases, we plan to remove the feature in a future
version of GCC.

This kind of thing is why we tend to discourage discussion of
compiler-specific extensions here. Even a list of dozens of compilers
that support a given feature can't compete with a statement that it's
defined by the standard, and therefore is supported by *all*
conforming compilers.
 
H

Herbert Rosenau

#pragma once is supported by

It is NOT supported by the standard. In this group it doesn't matter
what properitary things do. The only relevant is the standard. jacob
navia is too crazy to understund that as proven again.


--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top