2012-10-18 9 views
5

biorąc pod uwagę następujący kod:gcc vs Visual Studio makro ekspansja

void doSomething(int one, int two, int three) 
{ 
    //something here 
} 

#define ONE 1,2,3 

#define TWO(arg) doSomething(arg); 

#define THREE(arg) TWO(arg) 

void doSomethingElse() 
{ 
    TWO(ONE) 

    THREE(ONE) 
} 

Visual Studio 2010 ma następujący wynik preprocesora (pomijając niektóre puste wiersze):

void doSomething(int one, int two, int three) 
{ 

}  

void doSomethingElse() 
{ 
    doSomething(1,2,3); 

    doSomething(1,2,3);  
} 

podczas gcc 4.2 wydaje następujący :

void doSomething(int one, int two, int three) 
{ 

}  

void doSomethingElse() 
{ 
    doSomething(1,2,3); 

myFile.cpp:17:13: error: macro "TWO" passed 3 arguments, but takes just 1 
    TWO 
} 

Nie jestem pewien, który jest standardowy, ale chciałbym, żeby działał jak stud io działa. Czy istnieje sposób na refakturowanie kodu, aby działał w ten sposób w obu kompilatorach?

+1

Zwykle, gdy VS i gcc różnią się, jest to poprawna wartość gcc. –

+0

Jest to znany błąd w preprocesorze Visual C++: nie rozwija makr przed ponownym skanowaniem. zachowanie gcc jest poprawne. –

+0

Dziękuję za wszystkie odpowiedzi ... jeśli chodzi o przedstawione rozwiązania, myślę, że za bardzo uprościłem mój przykład i nie mogłem ich zmusić do działania. Znalazłem inne obejście, ale nie jest ono ilustracją tego ogólnego problemu, więc pomijam go tutaj. – user109078

Odpowiedz

1

Przecinki wymagają specjalnej obsługi, gdy używasz ich w innym makrze.

To powinno działać:

#define ONE() 1,2,3 
#define TWO(ARG) doSomething(ARG()); 
#define THR(ARG) TWO(ARG) 

opóźnić ONE zastąpione są natychmiast, obracając ją w funkcję jak samo makro.

Możesz zobaczyć więcej przykładów unikania tego z BOOST_PP_COMMA_IF na boost documentation site.

3

Inną możliwością parenthesizing argument tak, aby nie stało się 3 argumenty na zastąpieniu:

#define ONE 1,2,3                                                                
#define TWO_PARENS(arg) doSomething arg;                                                          
#define TWO(arg) TWO_PARENS((arg));                                                           
#define THREE(arg) TWO_PARENS((arg)) 
THREE(ONE)   

okazji GCC prawo według spec.

Powiązane problemy