Почему нельзя сравнить строку в выражении #if в c++

Я хочу написать такой код, но не могу:

#define COLOR "red" 
#define RED "red"
#define BLUE "blue"

int main()
{

// following code can't be compiled
#if (COLOR==RED)
    cout<<"red"<<endl;
#endif

// following code can work
if (COLOR==RED)
    cout<<"red"<<endl;
else 
    cout<<"notred"<<endl;

}

Итак, как я могу реализовать сравнение строк в выражении #if? или может это не возможно?

Кстати, я знаю, что могу реализовать другими способами, например:

#define COLOR 1
#define RED 1
#define BLUE 2

// can be compiled and word correctly
#if (COLOR==RED)
    cout<<"red"<<endl;
#endif

Есть ли причина, по которой вы хотите использовать препроцессор для этого?

Etienne de Martel 06.05.2022 05:40

Даже if (COLOR==RED) не обязательно должно быть правдой. «Являются ли все строковые литералы разными (то есть хранятся в непересекающихся объектах) и дают ли последовательные оценки строкового литерала тот же или другой объект не указано».

Raymond Chen 06.05.2022 06:51

@EtiennedeMartel: 1 надеюсь, что выражения имеют значение, насколько это возможно, для меня число 1 2 3 не имеет никакого значения. другими словами, я хочу лучшего опыта чтения. 2 в некоторых случаях я хочу, чтобы макрос, например COLOR, вводил мое имя файла с содержимым «красный», например.

Aerterliusi 06.05.2022 08:41

добавить проблему: как я могу напечатать макрос в виде строки в имя файла? как мы знаем, макрос будет заменен пропроцессором. Есть ли какие-то хитрости?

Aerterliusi 06.05.2022 09:37

Чтобы расширить то, что сказал @RaymondChen: "red" == "red" не обязательно должно быть правдой; два литерала можно хранить отдельно, или их можно рассматривать как один литерал.

Pete Becker 06.05.2022 15:20

Да, конечно, но зачем использовать препроцессор, а не константы? Вы пишете C++, а не C, у вас есть настоящие константы.

Etienne de Martel 06.05.2022 16:41
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
100
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Потому что #if работает только с целыми числами

expression is a C expression of integer type, subject to stringent restrictions. It may contain...

см. https://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_4.html#SEC38

#include <iostream>

// internal functions, can be put into included header
#define TRUE 1
#define XEQUAL(a, b) a##_##b
#define EQUAL(a, b) XEQUAL(a, b)
#define XCUSTOMSTR(a) color_##a
#define CUSTOMSTR(a) XCUSTOMSTR(a)
#define XSTR(a) #a
#define STR(a) XSTR(a)

// define available colors
#define red_red TRUE
#define blue_blue TRUE
#define green_green TRUE

// optional custom names
#define color_green "grün"

#define COLOR red
#define COLOR2 green

int main() {

#if EQUAL(COLOR, red)
    std::cout << "my_"STR(COLOR)"_file.txt";
#endif

#if EQUAL(COLOR, COLOR2)
    char filename[] = "my_"STR(COLOR2)"_file.txt";
    std::cout << filename;
#endif

    std::cout << CUSTOMSTR(green);

    return 0;
}

Хитрость заключается в том, чтобы сравнить до, сделав из него строку.

Препроцессор не может обрабатывать строки (кроме их генерации), но может обрабатывать текстовые токены!

не может работать, ошибка: токен не является допустимым бинарным оператором в подвыражении препроцессора

Aerterliusi 06.05.2022 09:18

Сравнение @Aerterliusi теперь работает, и вы можете использовать текст макроса в именах файлов.

Sebastian 06.05.2022 14:27

Другие вопросы по теме