If-direktifi makro karşılaştırması


25

#ifAşağıdaki koddaki koşul neden yerine getirildi:

#include <iostream>
#define VALUE foo    

int main() {    
#if VALUE == bar
    std::cout << "WORKS!" << std::endl;
#endif // VALUE
}

Yanıtlar:


26

Cppreference.com sayfa devletler:

Tanımlanmış ve __has_include (C ++ 17'den beri) ifadelerinin tüm makro genişlemesi ve değerlendirmelerinden sonra, boole değişmezi olmayan herhangi bir tanımlayıcı 0 sayısıyla değiştirilir (bu, sözcük olarak anahtar kelimeler olan, ancak ).

Yani her ikisi de foove bar0 ile değiştirilir.


C ++ 98, C ++ 03, C ++ 11 ve C ++ 14 ne olacak?
kelalaka

1
@kelalaka Hepsi aynı. C89'dan beri böyle oldu.
SS Anne

1
@kelalaka "C ++ 17'den beri" yalnızca "ve __has_include" bölümünü ifade eder. C ++ 17'den önce aynıydı, sadece bu kısım atlanmıştı.
BessieTheCow

15

Bir #ififadede, makro ikamesinden sonra ( trueve hariç false) kalan tüm tanımlayıcılar sabit ile değiştirilir 0. Böylece direktifiniz

#if 0 == 0

hangisi doğru.


Açıklığa kavuşturmak için, '#define VALUE foo', 'foo' sembolü ile aynı değere çözmek için 'VALUE' sembolünü tanımlar, ancak 'foo' sembolünün bir anlamı yoktur, bu nedenle 0 olarak yorumlanacaktır.
ManicDee

14

Bunun nedeni, ne tanım ne foode bardeğer verilmemiş olmasıdır - bu yüzden aynıdırlar (yani "0" değeriyle değiştirilmiştir). Derleyiciler bu konuda uyarı verecektir.

MSVC(2019 Studio Görsel) derleyici aşağıdaki verir:

uyarı C4668: 'foo' bir önişlemci makrosu olarak tanımlanmadı, '# if / # elif' için '0' ile değiştirildi
uyarı C4668: 'bar', '#if' yerine '0' ile değiştirildi / # elif'

Bu yüzden VALUE'0' değeri verilir (varsayılan değer foo) ve barayrıca '0' vardır, bu nedenle VALUE == bar"TRUE" olarak değerlendirilir.

Benzer şekilde, clang-claşağıdakileri verir:

uyarı: 'foo' tanımlanmamış, 0 olarak değerlendirilir [-Wundef]
uyarı: 'bar' tanımlanmamış, 0 olarak değerlendirilir [-Wundef]


Uyarı zorunlu mu yoksa derleyicilerin bir özelliği mi?
kelalaka

1
@kelalaka Bildiğim kadarıyla, hiçbir derleyici 'uyarısı' zorunlu değildir! MSVCVe clang-clderleyicileriyle bile , bu uyarı devre dışı bırakılabilir (özel olarak veya uygun bir uyarı 'seviye' ayarlanarak).
Adrian Mole

0

Neyin peşinde olduğunuzu gerçekleştirmek için şunu deneyin:

#include <iostream>
#define DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

Bu durumda, "define" ifadesini "undef" olarak değiştirerek hata ayıklama deyimlerini kapatabilirsiniz.

#include <iostream>
#undef DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

Derleyicinizin DEBUG'u kodun dışında tanımlamanıza izin verdiğini görebilirsiniz, bu noktada kodu

#include <iostream>

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

Ve sonra derleyiciyi -DDEBUG = 0 gibi bir seçenekle çağırır.

Steve Code, "Kod Tamamlandı" bölümündeki Savunma Programcılığı bölümüne bakın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.