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

C++ define a static variable in if condition using g++

本文关键字:一个 变量 静态 定义 g++ 使用 if 条件 C++      更新时间:2023-10-16

以下宏在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用于通过通道区分日志,例如通道1、通道2
  2. 上面的宏在Visual Studio中工作
  3. 我使用宏来减少函数调用的次数
  4. 如果可以的话,我会毫不犹豫地避开宏。但我不得不使用宏

问题:

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

错误:decl说明符在条件中无效

这是因为g++不允许在if条件中声明静态变量。我之所以将变量"channel_settings"设置为静态,是因为我认为它会导致每个ChannelID有一个副本。不过,我对此并不确定。

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

g++不允许这样做。

g++编译器有什么问题吗?

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

这不是宏的工作方式。当您有一个宏时,它会直接替换行的文本-宏与宏的内容一起使用。如果在多个位置调用宏,则将重新定义变量。

在C++中,这通常可以使用一个函数来解决,并声明一个函数的局部静态变量。

这没有任何意义。即使宏以这种方式工作(它们不会,但即使它们会),代码也不会有任何用途。

if()条件中声明一个变量的目的是使该变量可以在下面访问。例如,

if (int rc = function())
    std::cout << "Function failed, rcode = " << rc << "n"

将允许只需要知道非0时的函数结果代码的人防止rc污染作用域。但在你的情况下,你说你不需要这个变量。由于按照问题中所述对检查进行编码也是没有意义的(if (x = 5)总是正确的),我假设您实际上想要测试函数的结果。

综合来看,您只需要执行if (func())...

回答我的问题,我使用的是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条件之内。如果有人知道,请告诉我!

您可以通过语句表达式实现这一点

至少在gcc 上

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