简体   繁体   English

在C ++中定义顶级无操作?

[英]Defining a top-level no-op in C++?

Is the following legal according to the C++ standard? 根据C ++标准,以下是否合法? (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. 我很确定不允许在顶层使用偏移分号(无论如何,GCC会抱怨它们),所以简单地定义一个空宏是行不通的。

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? 匿名空枚举声明( enum { } )是否有效? 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. 相信我,我很乐意。

Looking at the latest public C++0x draft, it seems semicolons at top-level are allowed and ignored. 查看最新的公共C ++ 0x草案,似乎允许并忽略顶层的分号。

The grammar treats a translation-unit as a sequence of declaration s, and amongst the various kinds of declarations there is an empty-declaration that is just a simple semicolon. 语法将translation-unit视为一系列declaration ,在各种声明中,有一个empty-declaration只是一个简单的分号。

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. 实用的解决方案:考虑到您的VERY_OLD_COMPILER常量表明整个事情是旧编译器的变通方法的一部分,我只选择一个适用于此编译器的解决方案,无论是标准化还是非标准化。

#define USING_NAMESPACE_STD static int dummy##__LINE__

An empty enum is in fact illegal according to C++03: 根据C ++ 03,空枚举实际上是非法的:

7/3 Declarations: 7/3声明:

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. 在一个简单声明中,只有在声明一个类(第9节)或枚举(7.2)时,也就是说,当decl-specifier-seq包含一个类说明符,一个精心设计的类型时,可以省略可选的init-declarator-list。 -specifier with class-key(9.1)或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). 在这些情况下,只要在decl-specifier-seq中存在类说明符或枚举说明符,这些说明符中的标识符就是声明声明的名称(作为类名,枚举名或枚举符,取决于语法)。 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. 在这种情况下,除了声明未命名的位字段(9.6)之外,decl-specifier-seq 在程序中引入一个或多个名称 ,或者重新声明由先前声明引入的名称。

[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). 所以我同意MSN的声明一个虚拟enumstruct转发声明或typedef声明的答案 ,其名称显然不会与任何东西发生冲突(在那里抛出GUID以获得良好的衡量标准)。 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. 关于这些事情的好处是你可以让声明不止一次出现,只要它与以前一样没有问题。

Comeau says no: Comeau说不:

> 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
#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 work also: 编辑:这也应该工作:

#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;

Sorry, I forgot you needed to do it at the top level. 对不起,我忘了你需要在顶层做。

How about 怎么样

extern int _;

? I don't know what undesirable side effects this would have, though I can't think of any. 我不知道这会产生什么不良副作用,但我想不出任何副作用。

#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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM