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

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

#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 call at the top level and follow the semicolon so that it does not affect. I'm pretty sure stray semicolons are not allowed at the top level (GCC complains about them anyway), so just defining an empty macro doesn't work.

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

Does an anonymous empty enumeration declaration ( enum { } ) make? It works on all the compilers I tried, but of course this is not the same as allowed by the spec.

Any other ideas / comments are welcome. Well, nothing but throw this compiler. Believe me, I would love to.

+6
source share
7 answers

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

The grammar treats a translation-unit as a sequence of declaration s, and among the various kinds of declarations there is empty-declaration , which is just a semicolon.

A pragmatic solution: given that your constant VERY_OLD_COMPILER suggests that all this should be part of a workaround for an older compiler, I would just choose a solution that works with this compiler, whether standardized or not.

+6
source
 #define USING_NAMESPACE_STD static int dummy##__LINE__ 
+4
source

An empty enumeration is actually illegal according to C ++ 03:

7/3 Announcements:

In the simplest declaration, the optional init-declarator list can only be omitted when declaring a class (section 9) or listing (7.2), that is, when spec-specifier-seq contains either a class specifier, a specified type specifier with a class key (9.1), or an enumeration specifier . In these cases, and whenever a class specifier or an enumeration specifier is present in the description specifier-seq, the identifiers in these qualifiers refer to the names declared by the declaration (as class names, enumerated names or enumerations, depending on the syntax). In such cases, and with the exception of declaring an unnamed bit field (9.6), decl-specifier-seq enters one or more names into the program or should update the name entered by the previous declaration.

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

So, I agree with MSN's answer to declare a simple enum , struct , or typedef declaration with a name that is clearly not going to conflict with anything (throw a GUID in there for a good measure). The best part about these things is that an ad can appear more than once, and until it becomes a problem.

+4
source

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 
+2
source
 #define VERY_OLD_COMPILER 1 #ifdef VERY_OLD_COMPILER #define USING_NAMESPACE_STD typedef unsigned long uint32 #else #define USING_NAMESPACE_STD using namespace std #endif USING_NAMESPACE_STD; 

Edit: This should also work:

 #define VERY_OLD_COMPILER 1 #ifdef VERY_OLD_COMPILER #define USING_NAMESPACE_STD double fabs(double) #else #define USING_NAMESPACE_STD using namespace std #endif USING_NAMESPACE_STD; 
0
source

Sorry, I forgot that you need to do this at the top level.

What about

 extern int _; 

? I donโ€™t know what undesirable side effects you would have, although I canโ€™t think of anything.

0
source
 #define VERY_OLD_COMPILER 1 #ifdef VERY_OLD_COMPILER #define USING_NAMESPACE_STD ; #else #define USING_NAMESPACE_STD using namespace std #endif USING_NAMESPACE_STD; int main(int argc, char *argv[]) { // etc. 
0
source

Source: https://habr.com/ru/post/893651/


All Articles