Эмуляция, если __name__ == __main__ в c ++ вызывает ошибку «функционально-подобный макрос не определен» - PullRequest
0 голосов
/ 29 апреля 2018

Я пишу простой файл компоновки с помощью bash, что позволяет мне легко переключать точки входа, эмулируя Python

.
if __name__ == __main__:
    main()

Моя идея заключалась в том, чтобы включить макрос, передав -D __MAIN__=\"$MAIN_FILE\" в clang ++, где MAIN_FILE - это файл, который вы указываете при запуске скрипта сборки. Тогда мне просто нужно сравнить макрос __MAIN__ с предопределенным стандартным макросом __FILE__ для каждого исходного файла. Примерно так:

#if equals(__FILE__, __MAIN__)
    int main()
    {
        /* code */
        return 0;
    }
#endif

Проблема, с которой я сталкиваюсь, - заставить функцию equals работать во время компиляции. Читая об этом, кажется, что должна быть возможность определить функцию constexpr, которая сравнивает строки во время компиляции (по крайней мере, согласно this и this answer).

Однако всякий раз, когда я пытаюсь создать такую ​​функцию (или копировать код из здесь или здесь ), я получаю следующую ошибку:

ошибка: функциональный макрос «равно» не определен

Что мне кажется странным, поскольку это ни макрос, ни неопределенное значение. Не удалось найти решение при поиске сообщения об ошибке.

Вот полный код для справки:

#include <iostream>

constexpr bool equals(const char* a, const char* b)
{
    return *a == *b && (*a == '\0' || equals(a + 1, b + 1));
}

#if equals(__FILE__, __MAIN__)
    int main()
    {
        std::cout << "Running " << __MAIN__ << std::endl;
        return 0;
    }
#endif

Скомпилировано с:

clang++ main.cpp -std=c++14 -D __MAIN__="fullpath/main.cpp"

В чем причина этой ошибки и как я могу решить мою проблему?

1 Ответ

0 голосов
/ 29 апреля 2018

#if и #endif являются директивами препроцессора - препроцессор выполняется как часть шага компиляции, но он не знает о C ++ как о языке.

Вы не можете смешивать и сопоставлять препроцессор с функциями C ++, такими как constexpr функции.

Если вы хотите, чтобы это работало, вам нужно реализовать собственный макрос #define EQUALS, который полностью проверяет равенство строк на этапе предварительной обработки. Я не уверен, возможно ли это (и стоит ли это).

...