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

Re: upper case enumerator

51 views
Skip to first unread message
Message has been deleted

Ian Collins

unread,
Sep 27, 2019, 10:43:55 PM9/27/19
to

On 28/09/2019 14:37, Mark wrote:
>
> [code]
>
>
> # ifndef XXX_YYY
> # define XXX_YYY
>
> //# pragma once //this is what you should do today and beyond (all things being equal .. compiler support)
> # include <cstddef>
> # include <iostream>
>
> namespace foo
> {
> enum kFavoriteWine { kMoscato, XXX_YYY } ;
> }
>
>
> # endif
>
> auto main() -> int

Horrid style..

> {
> using namespace foo ;
> kFavoriteWine xx = XXX_YYY ;
>
> }
> Why does the upper case enumerator collided with the preprocessor
> macro even though the macro is wrapped in a namespace? Can someone
> point me to some standard verbiage saying why that's wrong

A macro is a simple text substitution performed by the preprocessor, so
your code is changed to something like

namespace foo
{
enum kFavoriteWine { kMoscato, } ;
}

auto main() -> int
{
using namespace foo ;
kFavoriteWine xx = ;

}

before it is compiled.

--
Ian.

Louis Krupp

unread,
Sep 28, 2019, 1:49:55 AM9/28/19
to
On Fri, 27 Sep 2019 19:37:29 -0700 (PDT), Mark <ma74...@gmail.com>
wrote:

>
>[code]
>
>
># ifndef XXX_YYY
># define XXX_YYY
>
>//# pragma once //this is what you should do today and beyond (all things being equal .. compiler support)
># include <cstddef>
># include <iostream>
>
> namespace foo
> {
> enum kFavoriteWine { kMoscato, XXX_YYY } ;
> }
>
>
># endif
>
>auto main() -> int
>{
> using namespace foo ;
> kFavoriteWine xx = XXX_YYY ;
>
>}
>Why does the upper case enumerator collided with the preprocessor macro even though the macro is wrapped in a namespace? Can someone point me to some standard verbiage saying why that's wrong
>
>[/code]

To expand on Ian's post, it doesn't collide. I don't know if this is
in the standard, but if you're using the preprocessor that comes with
gcc and g++, "#define <macro>" with no text gets you an empty
definition:

https://stackoverflow.com/questions/13892191/are-empty-macro-definitions-allowed-in-c-how-do-they-behave

Louis

Bo Persson

unread,
Sep 28, 2019, 4:07:09 AM9/28/19
to
On 2019-09-28 at 04:37, Mark wrote:
>
> [code]
>
>
> # ifndef XXX_YYY
> # define XXX_YYY
>
> //# pragma once //this is what you should do today and beyond (all things being equal .. compiler support)
> # include <cstddef>
> # include <iostream>
>
> namespace foo
> {
> enum kFavoriteWine { kMoscato, XXX_YYY } ;
> }
>
>
> # endif
>
> auto main() -> int
> {
> using namespace foo ;
> kFavoriteWine xx = XXX_YYY ;
>
> }
> Why does the upper case enumerator collided with the preprocessor macro even though the macro is wrapped in a namespace? Can someone point me to some standard verbiage saying why that's wrong
>
> [/code]
>

The preprocessor doesn't care about namespaces, it just replaces
everything, everywhere.

One common way to avoid this problem is to reserve all-uppercase
identifiers for the preprocessor, and not use those for anything else.


Bo Persson

Ben Bacarisse

unread,
Sep 28, 2019, 4:58:23 PM9/28/19
to
Mark <ma74...@gmail.com> writes:

> # define XXX_YYY
<cut>
> namespace foo
> {
> enum kFavoriteWine { kMoscato, XXX_YYY } ;
> }

<cut>
> using namespace foo ;
> kFavoriteWine xx = XXX_YYY ;

> Why does the upper case enumerator collided with the preprocessor
> macro even though the macro is wrapped in a namespace? Can someone
> point me to some standard verbiage saying why that's wrong

To expand yet again on the other answers...

The verbiage is section 2.2 Phases of Translation. It explains the
logical sequence in which source files are processed. Macros are
expanded in phase 4, whereas what we usually think of a parsing happens
in phase 7. By phase 7 there is no identifier 'XXX_YYY' -- they all
vanished in phase 4.

--
Ben.

Öö Tiib

unread,
Sep 28, 2019, 8:11:09 PM9/28/19
to
On Saturday, 28 September 2019 05:37:42 UTC+3, Mark wrote:
>
> # ifndef XXX_YYY
> # define XXX_YYY

Be more explicit in include guard name about what it is.
Use XXX_YYY_HPP_INCLUDED and the trouble disappears.

Vir Campestris

unread,
Sep 29, 2019, 4:45:36 PM9/29/19
to
Our coding standard says to use a sensible name - and then stick a
random 8-digit hex value after it. It even tells you how to derive the 8
digits if like most of us you are on Linux.

Andy

Manfred

unread,
Sep 29, 2019, 5:29:50 PM9/29/19
to
Just to remind a very common habit, the "sensible name" is often some
reformat (often uppercase) of the filename, which has the nice feature
of being unique at least within a directory (modulo perverse naming
habits of source files).

Ian Collins

unread,
Sep 29, 2019, 11:36:31 PM9/29/19
to
Are there any mainstream compilers that don't support #pragma once? It
makes life much simpler.

--
Ian.

James Kuyper

unread,
Sep 30, 2019, 1:11:19 AM9/30/19
to
On 9/27/19 10:37 PM, Mark wrote:
>
> [code]
>
>
> # ifndef XXX_YYY
> # define XXX_YYY
>
> //# pragma once //this is what you should do today and beyond (all things being equal .. compiler support)
> # include <cstddef>
> # include <iostream>
>
> namespace foo
> {
> enum kFavoriteWine { kMoscato, XXX_YYY } ;
> }
>
>
> # endif
>
> auto main() -> int
> {
> using namespace foo ;
> kFavoriteWine xx = XXX_YYY ;
>
> }
> Why does the upper case enumerator collided with the preprocessor macro even though the macro is wrapped in a namespace? Can someone point me to some standard verbiage saying why that's wrong

The key point is that preprocessing (including the expansion of macros)
occurs during translation phase 4 (5.2p4). Namespaces aren't recognized
as such until translation phase 8 (5.2p8), and therefore have no effect
on preprocessing.

Frederick Gotham

unread,
Sep 30, 2019, 4:34:50 AM9/30/19
to
On Saturday, September 28, 2019 at 3:37:42 AM UTC+1, Mark wrote:
>
> # ifndef XXX_YYY
> # define XXX_YYY
>
> //# pragma once //this is what you should do today and beyond (all things being equal .. compiler support)
> # include <cstddef>
> # include <iostream>
>
> namespace foo
> {
> enum kFavoriteWine { kMoscato, XXX_YYY } ;
> }
>
>
> # endif
>
> auto main() -> int
> {
> using namespace foo ;
> kFavoriteWine xx = XXX_YYY ;
>
> }
> Why does the upper case enumerator collided with the preprocessor macro even though the macro is wrapped in a namespace? Can someone point me to some standard verbiage saying why that's wrong
>


Every source code file (.c, .cpp) in your project gets all of its header files added into it, and the preprocessor performs substitutions. What you're left with is called a translation unit.

source file (and it's headers) ------> PREPROCESSOR -------------> translation unit

It is the translation units that are then fed into the compiler:

translation unit -----------------> COMPILER -------------------> object file

And then it is the object files that are fed into the linker:

object files -----------------> LINKER --------------------> executable file

Jorgen Grahn

unread,
Sep 30, 2019, 8:25:23 AM9/30/19
to
Life is already simple; I think this thread exaggerates the problem.
In a header foo/bar.h in project someproj:

#ifndef SOMEPROJ_FOO_BAR_H

The include guard will be unique (as an include guard) and very
unlikely to clash with anything else.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Ben Bacarisse

unread,
Sep 30, 2019, 9:55:36 AM9/30/19
to
Jorgen Grahn <grahn...@snipabacken.se> writes:

> On Mon, 2019-09-30, Ian Collins wrote:
>> On 30/09/2019 09:45, Vir Campestris wrote:
>>> On 29/09/2019 01:10, 嘱 Tiib wrote:
>>>> On Saturday, 28 September 2019 05:37:42 UTC+3, Mark wrote:
>>>>>
>>>>> # ifndef XXX_YYY
>>>>> # define XXX_YYY
>>>>
>>>> Be more explicit in include guard name about what it is.
>>>> Use XXX_YYY_HPP_INCLUDED and the trouble disappears.
>>>>
>>> Our coding standard says to use a sensible name - and then stick a
>>> random 8-digit hex value after it. It even tells you how to derive the 8
>>> digits if like most of us you are on Linux.
>>
>> Are there any mainstream compilers that don't support #pragma once? It
>> makes life much simpler.
>
> Life is already simple; I think this thread exaggerates the problem.
> In a header foo/bar.h in project someproj:
>
> #ifndef SOMEPROJ_FOO_BAR_H
>
> The include guard will be unique (as an include guard) and very
> unlikely to clash with anything else.

A handy tip is to start with the H_:

#ifndef H_SOMEPROJ_FOO_BAR

because SOMEPROJ might begin with E and, at least in C, macro names
beginning with E are reserved for future library versions.

--
Ben.
0 new messages