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

时间:2011-07-27 00:03:44

标签: c++

根据C ++标准,以下是否合法? (如果答案从标准到标准不同,我也想知道。)

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

目标是定义一个我可以在顶层调用的宏,然后使用分号,这样它就没有效果了。我很确定不允许在顶层使用偏移分号(无论如何,GCC会抱怨它们),所以简单地定义一个空宏是行不通的。

声明一个空的匿名结构不起作用,因为它需要一个名字,我不想污染命名空间。

匿名空枚举声明(enum { })是否有效?它适用于我尝试过的所有编译器,但当然这与规范允许的不同。

欢迎任何其他想法/评论。好吧,除了“扔掉那个编译器”之外的任何东西。相信我,我很乐意。

7 个答案:

答案 0 :(得分:6)

查看最新的公共C ++ 0x草案,似乎允许并忽略顶层的分号。

语法将translation-unit视为declaration s的序列,在各种声明中,有empty-declaration只是一个简单的分号。

务实的解决方案:考虑到你的VERY_OLD_COMPILER常量表明整个事情是成为旧编译器的变通方法的一部分,我只选择一个可以使用的解决方案这个编译器,无论是标准化还是非标准化。

答案 1 :(得分:4)

#define USING_NAMESPACE_STD static int dummy##__LINE__

答案 2 :(得分:4)

根据C ++ 03,空枚举实际上是非法的:

7/3声明:

在一个简单声明中,只有在声明一个类(第9节)或枚举(7.2)时,也就是说,当decl-specifier-seq包含一个类说明符时,可以省略可选的init-declarator-list。 ,一个详细的类型说明符,带有类键(9.1)或枚举说明符。在这些情况下,只要在decl-specifier-seq中存在类说明符或枚举说明符,这些说明符中的标识符就是声明声明的名称(作为类名,枚举名或枚举符,取决于语法)。在这种情况下,除了声明未命名的位域(9.6)之外,decl-specifier-seq 应在程序中引入一个或多个名称,或者重新声明由a引入的名称。先前的声明。

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

所以我同意MSN's answer声明一个虚拟enumstruct前向声明或typedef声明,其名称显然不会与任何内容发生冲突(在那里抛出一个GUID以获得良好的衡量标准)。关于这些事情的好处是你可以不止一次地出现声明,只要它与以前一样没有问题。

答案 3 :(得分:2)

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

您可以使用

#define USING_NAMESPACE_STD struct very_long_name_that_i_hope_doesnt_collide_because_if_it_does_oh_noes

答案 4 :(得分:0)

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

编辑: 这应该也有效:

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

答案 5 :(得分:0)

抱歉,我忘了你需要在顶层做这件事。

怎么样

extern int _;

?我不知道这会产生什么不良副作用,但我想不出任何副作用。

答案 6 :(得分:0)

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