什么是可移植的方式在C ++中实现no-op语句? [英] What's a portable way to implement no-op statement in C++?

查看:211
本文介绍了什么是可移植的方式在C ++中实现no-op语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一点需要在C ++中使用no-op语句。例如,当实现在非调试配置中禁用的 assert()(另见 this question ):

  #ifdef _DEBUG 
#define assert(x)if ){\
ThrowExcepion(__ FILE__,__LINE __); \
} else {\
// noop here \
}
#else
#define assert(x)// noop here
#endif

m下的正确的方式是使用(void)0; 为无操作:

 (void)0; 

但是我怀疑它可能会触发一些编译器上的警告 - 像 C4555 :表达式没有效果;带有副作用的预期表达式 Visual C ++警告,对于此特定情况不发出,但在没有转换为 void 时发出。 >

它是普遍可移植的吗?有没有更好的方法?

解决方案


我怀疑它可能会触发警告一些编译器


不太可能,因为((void)0) $ c> assert 宏将扩展为定义 NDEBUG 时。因此任何发出警告的编译器都会在编译包含断言的代码时发出警告。



我想编译器可以通过警告你的建议来避免这个问题(void)0 ,而只处理((void)0)。所以你最好使用((void)0),但我怀疑。



铸造一些无效,有或没有额外的封闭的括号,惯用意思是忽略这。例如,在C代码中,为了抑制对未使用的变量的警告,将函数参数强制转换为 void 。因此,在那个分数上,一个警告的编译器会相当不受欢迎,因为抑制一个警告只会给你另一个警告。



请注意,在C ++中,以包括彼此。因此,如果您使用任何标准标题, assert 可能已由此定义。因此,您的代码是不可移植的帐户。如果你说的是通用可移植,通常应该将任何标准头中定义的宏作为保留标识符。您可以取消定义它,但对您自己的断言使用不同的名称将更加明智。我知道这只是一个例子,但我不明白为什么你会想要定义 assert 在一个通用可移植的方式,因为所有的C ++实现已经有它,它不会做你在这里定义它做的。


One in a while there's a need for a no-op statement in C++. For example when implementing assert() which is disabled in non-debug configuration (also see this question):

#ifdef _DEBUG
#define assert(x) if( !x ) { \
                     ThrowExcepion(__FILE__, __LINE__);\
                  } else {\
                     //noop here \
                  }
#else
#define assert(x) //noop here
#endif

So far I'm under impression that the right way is to use (void)0; for a no-op:

(void)0;

however I suspect that it might trigger warnings on some compilers - something like C4555: expression has no effect; expected expression with side-effect Visual C++ warning that is not emitted for this particular case but is emitted when there's no cast to void.

Is it universally portable? Is there a better way?

解决方案

I suspect that it might trigger warnings on some compilers

Unlikely, since ((void)0) is what the standard assert macro expands to when NDEBUG is defined. So any compiler that issues warnings for it will issue warnings whenever code that contains asserts is compiled for release. I expect that would be considered a bug by the users.

I suppose a compiler could avoid that problem by warning for your proposal (void)0 while treating only ((void)0) specially. So you might be better off using ((void)0), but I doubt it.

In general, casting something to void, with or without the extra enclosing parens, idiomatically means "ignore this". For example in C code that casts function parameters to void in order to suppress warnings for unused variables. So on that score too, a compiler that warned would be rather unpopular, since suppressing one warning would just give you another one.

Note that in C++, standard headers are permitted to include each other. Therefore, if you are using any standard header, assert might have been defined by that. So your code is non-portable on that account. If you're talking "universally portable", you normally should treat any macro defined in any standard header as a reserved identifier. You could undefine it, but using a different name for your own assertions would be more sensible. I know it's only an example, but I don't see why you'd ever want to define assert in a "universally portable" way, since all C++ implementations already have it, and it doesn't do what you're defining it to do here.

这篇关于什么是可移植的方式在C ++中实现no-op语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆