6

今天,我遇到了一個包含這樣#ifdef來子句一些C++代碼:#ifdef帶有多個標記,這是合法的嗎?

#ifdef DISABLE_UNTIL OTHER_CODE_IS_READY 
    foo(); 
#endif 

注「DISABLE_UNTIL」和「OTHER_CODE_IS_READY」之間的空間。基本上在#ifdef行中指定了兩個標記。

我的問題是,這是合法的C++代碼? (g ++編譯它時沒有任何錯誤,顯然它只是忽略了第二個標記)。如果它是合法的,第二個標記是否有效?

+1

克每++版本我試圖警告這一點,從2.8.1到4.8.1,警告:「警告:'#ifdef'參數結尾的垃圾','警告:#ifdef指令結尾處的額外標記'或'警告:#ifdef指令結尾處的額外標記[默認情況下啓用]」 。你怎麼沒有得到診斷? –

+0

@Keith:'g ++ myprogram.cpp -o myprogram | grep!警告' –

+0

@LightnessRacesinOrbit:這不會過濾掉警告('grep'語法錯誤,gcc將診斷寫入'stderr')。無論如何,我認爲你在猜測;我想知道OP如何未收到警告。 OP:你有意禁用警告嗎? –

回答

6

[C++11 16.1],[C++11 16.5]和順便說一句,[C99 6.10.1/4]都說這是無效的。

如果組
# if常數表達式新行選擇
# ifdef標識符新行選擇
# ifndef標識新線選擇

只有一個標識符是合法的。

GCC自己的文檔agrees

My own tests表明只接受第一個標識符,第二個標識符被丟棄;這可能是爲了緩解實施,但標準確實需要在這裏進行診斷,所以當你使用-pedantic標誌至少&dagger時應該看到這個;

#include <iostream> 
using namespace std; 

#define A 
#define B 

int main() { 
    #ifdef A 
    std::cout << "a "; 
    #endif 

    #ifdef B 
    std::cout << "b "; 
    #endif 

    #ifdef C 
    std::cout << "c "; 
    #endif 

    #ifdef B C 
    std::cout << "bc "; 
    #endif 

    #ifdef C B 
    std::cout << "cb "; 
    #endif 

    return 0; 
} 

// Output: "a b bc" 
// Note: "cb" *not* output 

&匕首; Coliru安裝的GCC發出它with or without -pedantic

+0

「*,當然這個標準在這裏不需要診斷*' - 標準要求診斷任何違反語法規則的錯誤 –

+0

@Keith:哦,是的,你是對的''[C++ 11:1.4/2]')。我一直認爲診斷作爲標準規則的「默認」選擇,而事實上恰恰相反,謝謝。 –

10

您發佈的語法不合法,其含義尚不清楚。

根據你希望完成什麼,你可以使用||&&來組合它們嗎?
(當然,如果這是別人的代碼,我只是拒絕爲不適當/不可用)

#if defined(DISABLE_UNTIL) || defined(OTHER_CODE_IS_READY) 
    foo(); 
#endif 
+2

您回答了其他一些問題很好。 –

+1

這是怎麼回事回答「這是否合法」這個問題_? – P0W

+0

我不確定代碼的作者希望完成什麼......我懷疑這只是一個錯字(他意外地鍵入了空格而不是下劃線)。 –