Логічне значення в ifdef: чи є "#ifdef A&& B" таким самим, як "#if визначено (A) && визначено (B)"?


83

У С ++ це:

#ifdef A && B

такий же як і:

#if defined(A) && defined(B)

?

Я думав, що це не так, але я не зміг знайти різниці зі своїм компілятором (VS2005).


1
можливо дублікат: stackoverflow.com/questions/965700 / ... я бачу , що вони є C і C ++, але препроцесори в основному ті ж: stackoverflow.com/questions/5085533 / ...
Чіро Сантіллі郝海东冠状病六四事件法轮功

Хтось цитуватиме та інтерпретуватиме стандарт, щоб вирішити, законний він чи ні (він точно не повинен працювати, але повинен його складати)? Я не можу після 15 хвилин читання розділу "16 директив з попередньої обробки".
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Відповіді:


91

Вони не однакові. Перший не працює (я тестував у gcc 4.4.1). Повідомлення про помилку було:

test.cc:1:15: попередження: зайві маркери в кінці директиви #ifdef

Якщо ви хочете перевірити, чи визначено кілька речей, використовуйте другу.


Дякуємо за перевірку. Я використовую компілятор Microsoft, і це, здається, це дозволяє, але мені це просто не здавалося правильним.
criddell

2
Ви не можете довести речі за допомогою одного компілятора. Зверніться до стандарту, де зазначено, що це недійсне значення.
Гонки легкості на орбіті

@LightnessRacesinOrbit Однак деякі компілятори розширюють стандарт. Висловлювання "це працює в певному компіляторі" не є спробою довести свою дійсність; слід зазначити, що певний компілятор певним чином розширює стандарт.
Позов Моніки до Фонду

@QPaysTaxes: Погоджено, але ця відповідь цього не робить. Він відповідає на запитання, яке починається "з С ++ ....", загальним фактом про С ++. На перший погляд, Еван перевірив свою теорію одним компілятором, а потім припустив, що це правда для всіх, гарантуючи саму мову. Якби він визначив, що така поведінка є розширенням GCC і сказав "це розширення GCC" (із посиланням на довідковий матеріал), це було б нормально! (хоч і не насправді відповідь на це конкретне питання)
Гонки легкості на орбіті

1
Хоча ні кількість позитивних тестів не може «довести» , що він є дійсним, один негативний досить , щоб довести , що це не так , або що це , по крайней мере , не рекомендується використовувати. Хоча посилання на стандарт було б непоганим, доведення того, що він не працює хоча б в одному великому компіляторі, є достатнім підтвердженням того, що "це не працює" для цілей цього обговорення.
zeel

48

Умовна компіляція

Ви можете використовувати визначений оператор у директиві #if для використання виразів, які мають значення 0 або 1 у рядку препроцесора. Це позбавляє вас від використання вкладених директив попередньої обробки. Дужки навколо ідентифікатора необов’язкові. Наприклад:

#if defined (MAX) && ! defined (MIN)  

Без використання визначеного оператора вам доведеться включити наступні дві директиви, щоб виконати наведений вище приклад:

#ifdef max 
#ifndef min

2
Хоча те, що ви кажете, є правильним, це взагалі не відповідає на питання, він запитав, чи є вони однаковими ... вони не є.
Еван Теран,

1
Я думаю, що там сказано "вони не однакові", ви бачите, що це пояснює, як зробити еквівалент #if defined (COND_A) && defined (COND_B), який відрізняється від #ifdef COND_A && COND_B
Ангелов

У будь-якому випадку, це корисна примітка.
Пол Масрі-Стоун

2

Наступні результати однакові:

1.

#define A
#define B
#if(defined A && defined B)
printf("define test");
#endif

2.

#ifdef A
#ifdef B
printf("define test");
#endif
#endif

1
Чи можете ви, будь ласка, додати коментар, щоб описати, як це відповідає на запитання, це не зрозуміло з вашої відповіді.
James Wood

Ця відповідь, хоча є технічно правильною, не дає точної відповіді на запитання і означає неправильне використання. Хоча два блоки будуть робити одне і те ж, вкладання двох ifs - це не те саме, що використання &&. Інші умови, такі як #else, можуть спричинити проблему. Тільки перший варіант насправді означає саме те, про що просив запитувач.
zeel

1

Для тих, хто може шукати наприклад (UNIX / g ++), який трохи відрізняється від OP, це може допомогти:

`

#if(defined A && defined B && defined C)
    const string foo = "xyz";
#else
#if(defined A && defined B)
    const string foo = "xy";
#else
#if(defined A && defined C)
    const string foo = "xz";
#else
#ifdef A
    const string foo = "x";
#endif
#endif
#endif
#endif

Чому б просто не використовувати #elif замість #else #if та мільярд # endif в кінці ...?
Еліот

-3

Станом на VS2015 жодне з вищезазначених не працює. Правильна директива:

#if (MAX && !MIN)

дивіться більше тут


2
Ви зв’язали документацію C #, а не C ++.
Revolver_Ocelot
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.