GCC4.3.3:标记为未使用的宏中使用的变量

GCC4.3.3: variable used in a macro marked as unused

本文关键字:变量 未使用 记为 GCC4      更新时间:2023-10-16

我正在使用 4.3.3 编译遗留代码,目前正在使用-Werror。出于某种原因,即使在宏中读取变量,gcc也认为它未使用——我不明白为什么。

以下是片段:

void MyClass::processEvent ()
{
i32 event = getEvent();
i32 handle = getHandle();
DEBUG_ENTRY( __OBSV_KEY__, __LINE__,  
"MyClass::processEvent() event=%d", event,
" (handle=%d)", handle);
}

调试条目宏(当前代码中仅使用 ENTRY2,ENTRY 是旧版):

#define DEBUG_ENTRY( MOD, NR, STR1, DAT1, STR2, DAT2 ) 
ENTRY(MOD,NR,DAT1,DAT2)                     
ENTRY2(MOD, NR, STR1, DAT1, STR2, DAT2 )

入口宏代码(仅剥离为相关函数调用):

#define ENTRY2(MOD, NR, STR1, DAT1, STR2, DAT2 )         
{                                                
Observer::setEntry( (int) DAT1, (int) DAT2 ); 
}

最后是函数本身:

int Observer::setEntry (int  a_nInt1, int  a_nInt2)
{
// relevant part only: member variables set to a_nInt1 and a_nInt2
p_NewEntry->m_nInt1 = a_nInt1;
p_NewEntry->m_nInt2 = a_nInt2; 
return ERR_NONE;
}

总而言之,eventhandle都沿着宏链传递到实际函数,其中通过将值保存到该对象的成员变量来读取它们的值

为什么 GCC 认为在使用宏时未使用eventhandle?如果我避免使用宏并粘贴相同的代码,则不会发出警告。我可以以某种方式让它看到灯光而不必求助于UNUSED宏来静音警告吗?

我挖得更深,似乎我对Visual Studio报告一个NDEBUG定义为未设置感到困惑,当它确实被设置时 - 有几个模块,NDEBUG定义可以为每个模块设置。所以正如@molbdnilo猜的那样:该特定模块的宏解析为无,导致未设置的变量警告 - 感谢您的提示。

#ifndef NDEBUG // this was set for the affected module, but appeared unset in visual studio
// en/disable old observer
//#define OBSERVER_1_ON
// en/disable new observer
#define OBSERVER_2_ON
#endif  
#include obsv2Func.h // this is where the ENTRY2 macro is defined
// class functions here
void MyClass::processEvent ()
{
i32 event = getEvent();
i32 handle = getHandle();
// expands to nothing, because ENTRY2 is not defined
DEBUG_ENTRY( __OBSV_KEY__, __LINE__,  
"MyClass::processEvent() event=%d", event,
" (handle=%d)", handle);
}

obsv2Func.h

#ifdef OBSERVER_2_ON
#define ENTRY2(MOD, NR, STR1, DAT1, STR2, DAT2 )         
{                                                
Observer::setEntry( (int) DAT1, (int) DAT2 ); 
}
#else
#define ENTRY2(MOD, NR, STR1, DAT1, STR2, DAT2 )
#endif

所以我的 GCC 版本(我被迫使用)中没有错误,只是我端的不干净代码。它还解释了为什么用宏背后的实际代码替换宏会隐藏警告 - 这使得代码不受#ifdef NDEBUG的影响,因此读取了变量。

我的解决方案是将MyClass::processEvent()函数中未使用的变量放入#ifndef NDEBUG块中,如果该模块中对DEBUG_ENTRY宏有很多调用

void MyClass::processEvent ()
{
i32 event = getEvent();
#ifndef NDEBUG
i32 handle = getHandle();
#endif
switch (event)
{
case 0:
DEBUG_ENTRY( __OBSV_KEY__, __LINE__,  
"MyClass::processEvent() event=%d", event,
" (handle=%d)", handle);
// some other code not affected by NDEBUG here
break;
//some more cases
default:
DEBUG_ENTRY( __OBSV_KEY__, __LINE__,  
"MyClass::processEvent() event=%d", event,
" (handle=%d)", handle);
// some other code not affected by NDEBUG here
break;
}
}

或者,如果函数中只有一次对DEBUG_ENTRY宏的调用,则直接在宏调用中使用getEvent()getHandle

DEBUG_ENTRY( __OBSV_KEY__, __LINE__,  
"MyClass::processEvent() event=%d", getEvent(),
" (handle=%d)", getHandle());

很抱歉没有在问题中提供完整的示例,下次我会确保这样做。