2016-06-07 7 views
0

Ich kompiliere Legacy-Code mit 4.3.3 und verwende im Moment -Werror. Aus irgendeinem Grund, obwohl eine Variable in einem Makro gelesen wird, denkt gcc, dass es nicht verwendet wird - ich verstehe nicht warum.GCC4.3.3: Variable in einem Makro verwendet als unbenutzt markiert

Hier werden die Schnipsel sind:

void MyClass::processEvent() 
{ 
    i32 event = getEvent(); 
    i32 handle = getHandle(); 

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

Die Debug-Eintrag Makro (nur entry2 in aktuellen Code verwendet wird, der Eintritt ist legacy):

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

Eintrag Makrocode (auf relevante Funktionsaufruf gestrippt only):

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

Und schließlich die Funktion selbst:

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; 
} 

So zusammenzufassen, beide event und handle sind die Makro-Kette an die eigentliche Funktion weitergegeben, wo ihren Wert durch das Speichern der Werte dieses Objekts Membervariablen lesen ist.

Warum denkt der GCC, dass event und handle nicht verwendet werden, wenn das Makro verwendet wird? Wenn ich das Makro vermeide und stattdessen denselben Code einfüge, wird die Warnung nicht ausgegeben. Kann ich das Licht irgendwie sehen, ohne auf das Makro UNUSED zurückgreifen zu müssen, um die Warnung zum Schweigen zu bringen?

+2

Können Sie eine [MCVE] angeben, die die Warnung reproduziert. –

+0

Sie würden nicht zufällig zwei alternative Definitionen von einem oder mehreren dieser Makros haben, und eines davon erweitert sich zu nichts? – molbdnilo

+0

@molbdnilo - wenn er '-Werror' verwendet, sollte er einen Fehler für das neu definierte Makro bekommen (oder sonst nur eine Warnung) ... ohne das ganze Beispiel raten wir nur: ( –

Antwort

0

Ich grub tiefer und es scheint, dass ich durch visuelle Studio-Berichterstattung eine NDEBUG verwechselt definiert als unset, wenn es tatsächlich festgelegt wurde - gibt es mehrere Module und die NDEBUG definieren kann pro Modul festgelegt werden. So ist es @molbdnilo erraten: das Makro für dieses spezielle Modul zu nichts aufgelöst, was zu einer nicht gesetzten Variablen Warnung - Danke für den Hinweis.

#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 

So gibt es keine Fehler in meiner Version von GCC (was ich bin gezwungen zu), um nur unsauber Code an meinem Ende. Es erklärt auch, warum das Ersetzen des Makros mit dem tatsächlichen dahinter liegenden Code die Warnung ausblendet, die den Code von #ifdef NDEBUG unberührt ließ, so dass die Variable gelesen wurde.

Meine Lösung ist entweder die nicht verwendete Variable in der MyClass::processEvent() Funktion in einen #ifndef NDEBUG Block als auch zu setzen, wenn es viele Anrufe an den DEBUG_ENTRY Makro in diesem Modul

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; 
    } 
} 

oder nur getEvent() und getHandle direkt verwenden in Das Makro ruft auf, wenn nur ein Aufruf an das Makro DEBUG_ENTRY in der Funktion erfolgt.

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

Sorry für das nicht ein vollständiges Beispiel in der Frage bietet, werde ich sicherstellen, so dass beim nächsten Mal zu tun.