C ++使用g ++在if条件下定义一个静态变量

时间:2016-01-08 18:37:23

标签: c++ macros

以下宏在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" ;
  1. 频道ID用于通过频道区分日志,例如Channel1,Channel2
  2. 上面的宏适用于Visual Studio。
  3. 我使用宏来减少函数调用次数。
  4. 如果可以,我肯定会避免使用宏。但我被迫使用宏。
  5. 问题:

    但是,当我使用g ++编译器时,相同的宏会引发以下错误:

      

    错误:条件

    中的decl-specifier无效

    这是因为g ++不允许在if条件中声明静态变量。我将变量“channel_settings”设为静态的原因是因为我认为每个ChannelID会导致一个副本。但是我不确定这一点。

    我的目标是在宏中定义一个指针变量,这样当我再次调用同一个宏时,编译器不会因重新定义该变量而引发错误。就像在Visual Studio C ++中一样。

    g ++不允许这样做。

    g ++编译器有没有解决方法?

4 个答案:

答案 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)

您可以使用statement expressions

至少在gcc上

if( ( { static ChannelSettingStruct* channel_settings = SingletonClass()->Instance()->GetSettings(ChannelID)); channel_settings; } ) )
{
    ...
}