以下宏在Vistual Studio C ++中编译(不是如下所示):
#define LogMacro(ChannelID) \
if(static ChannelSettingStruct* channel_settings = SingletonClass()->Instance()->GetSettings(ChannelID))
... use channel_settings to determine the settings of a channel/component and log accordingly...
... for example if logging for a channel is enabled or disabled ...
... if all the conditions are true then write log to file using the macro below. Just like std::cout it uses << operator to pump char to stream ...
LogToFileMacro(channel ...)
以上宏的用法:
LogMacro("ExampleChannel") << "Some text to log" ;
问题:
但是,当我使用g ++编译器时,相同的宏会引发以下错误:
错误:条件
中的decl-specifier无效
这是因为g ++不允许在if条件中声明静态变量。我将变量“channel_settings”设为静态的原因是因为我认为每个ChannelID会导致一个副本。但是我不确定这一点。
我的目标是在宏中定义一个指针变量,这样当我再次调用同一个宏时,编译器不会因重新定义该变量而引发错误。就像在Visual Studio C ++中一样。
g ++不允许这样做。
g ++编译器有没有解决方法?
答案 0 :(得分:2)
我的目标是在宏中定义一个静态变量,这样当我再次调用同一个宏时,编译器不会因重新定义该变量而引发错误。
这不是宏的工作原理。当你有一个宏时,它会直接用文本替换宏与宏的内容一起使用的行。如果你在几个地方调用宏,那么你将重新定义变量。
在C ++中,这通常可以使用函数来解决,并声明一个函数局部静态变量。
答案 1 :(得分:0)
没有任何意义。即使宏会以这种方式工作(他们不会,但即使他们愿意),代码也不会用于任何目的。
在if()
条件中声明变量的目的是使下面的变量可访问。例如,
if (int rc = function())
std::cout << "Function failed, rcode = " << rc << "\n"
允许只需要知道函数结果代码的人,当它为非0时阻止rc污染范围。但在你的情况下,你说你不需要变量。因为根据你的问题(if (x = 5)
总是如此)对代码进行编码也是没有意义的。我假设你实际上想要测试函数的结果。
将它们放在一起,您只需要if (func())...
。
答案 2 :(得分:0)
回答我的问题,我使用的是g ++版本4.8.5,
如果在宏中声明变量,例如:
#define Macro1 \
if(int x = 5)
这个宏可以在同一范围内多次调用。
如果在相同范围内多次调用,则在没有if条件的情况下声明会因重新定义而引发错误,例如:
#define Macro2 \
int x = 5; (compile error due to redefinition)
与Visual Studio不同,g ++不允许在if条件中声明静态变量。现在考虑一下,我不确定以下几行是否有任何不同的含义:
if( int x = 5 ) compared to if( staitc int x = 5 )
我相信他们的范围恰好在If条件下。如果有人知道请告诉我!
答案 3 :(得分:0)
至少在gcc上
if( ( { static ChannelSettingStruct* channel_settings = SingletonClass()->Instance()->GetSettings(ChannelID)); channel_settings; } ) )
{
...
}