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

时间:2016-06-07 08:25:26

标签: c++ gcc macros warnings

我正在使用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都会在宏链中向下传递到实际函数,通过将值保存到该对象来读取其值 #39;成员变量。

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

1 个答案:

答案 0 :(得分:0)

我挖得更深,似乎我被视觉工作室报告了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;
   }
}
如果系统中只有一次调用getEvent()宏,请直接在宏调用中使用getHandleDEBUG_ENTRY

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

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