Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining a top-level no-op in C++?

Tags:

c++

Is the following legal according to the C++ standard? (If the answer differs from standard to standard, I would like to know that, too.)

#define VERY_OLD_COMPILER 1

#ifdef VERY_OLD_COMPILER
#define USING_NAMESPACE_STD enum { }
#else
#define USING_NAMESPACE_STD using namespace std
#endif

USING_NAMESPACE_STD;

int main(int argc, char *argv[]) {
// etc.

The goal is to define a macro that I can invoke at the top-level and follow with a semicolon, such that it has no effect. I am pretty sure stray semicolons at the top-level are not allowed (GCC complains about them, anyway), so simply defining an empty macro does not work.

Declaring an empty anonymous struct does not work because it needs a name, and I do not want to pollute the namespace.

Does an anonymous empty enum declaration (enum { }) do the trick? It works on all of the compilers I have tried, but of course that is not the same thing as being permitted by the spec.

Any other ideas/comments welcome. Well, anything other than "throw out that compiler". Believe me, I would love to.

like image 366
Nemo Avatar asked Jul 27 '11 00:07

Nemo


4 Answers

Looking at the latest public C++0x draft, it seems semicolons at top-level are allowed and ignored.

The grammar treats a translation-unit as a sequence of declarations, and amongst the various kinds of declarations there is an empty-declaration that is just a simple semicolon.

Pragmatic solution: considering that your VERY_OLD_COMPILER constant suggests that the whole thing is to be a part of a workaround for an older compiler, I'd just pick a solution that works with this compiler, be it standardised or not.

like image 76
Alexander Gessler Avatar answered Oct 20 '22 12:10

Alexander Gessler


#define USING_NAMESPACE_STD static int dummy##__LINE__
like image 26
Ben Voigt Avatar answered Oct 20 '22 14:10

Ben Voigt


An empty enum is in fact illegal according to C++03:

7/3 Declarations:

In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (clause 9) or enumeration (7.2), that is, when the decl-specifier-seq contains either a class-specifier, an elaboratedtype-specifier with a class-key (9.1), or an enum-specifier. In these cases and whenever a class-specifier or enum-specifier is present in the decl-specifier-seq, the identifiers in these specifiers are among the names eing declared by the declaration (as class-names, enum-names, or enumerators, depending on the syntax). In such cases, and except for the declaration of an unnamed bit-field (9.6), the decl-specifier-seq shall introduce one or more names into the program, or shall redeclare a name introduced by a previous declaration.

[Example:
enum { }; // ill-formed
typedef class { }; // ill-formed
—end example]

So I would agree with MSN's answer to declare a dummy enum, struct forward declaration, or typedef declaration with a name that is obviously not going to conflict with anything (throw a GUID in there for good measure). The nice thing about these things is that you can have the declaration show up more than once, and as long as it's the same as before there's no problem.

like image 42
Michael Burr Avatar answered Oct 20 '22 13:10

Michael Burr


Comeau says no:

> Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for
> ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing.  All
> rights reserved. MODE:strict errors C++ C++0x_extensions
> 
> "ComeauTest.c", line 1: error: declaration does not declare anything  
> enum { };   ^
> 
> 1 error detected in the compilation of "ComeauTest.c".

You can use

#define USING_NAMESPACE_STD struct very_long_name_that_i_hope_doesnt_collide_because_if_it_does_oh_noes
like image 2
MSN Avatar answered Oct 20 '22 13:10

MSN