【问题标题】:Emulating if __name__ == __main__ in c++ causes error "function-like macro is not defined"在 C++ 中模拟 if __name__ == __main__ 会导致错误“未定义类似函数的宏”
【发布时间】:2018-04-29 12:37:30
【问题描述】:

我正在用 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 函数来比较编译时的字符串(至少根据thisthis的答案)。

但是,每当我尝试创建这样的函数(或从herehere 复制代码)时,我都会收到以下错误:

错误:未定义类似函数的宏“等于”

这对我来说似乎很奇怪,因为它既不是宏也不是未定义的。搜索错误信息时也找不到解决办法。

这是完整的代码供参考:

#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"

是什么导致了这个错误,我该如何解决我的问题?

【问题讨论】:

  • 标识符__MAIN__是实现保留的,你不能使用它。另外,你确定你真的想这样做吗?与单个 C++ 源文件相比,Python 模块与共享库相比更好;无论您实际尝试实现什么,都可能以更好的方式完成。
  • 既然您知道__MAIN__ 的值设置到哪个文件,为什么不为那个文件设置__MAIN__ 并使用简单的#ifdef __MAIN__ ... #endif?另外,macros with two underscores are reserved for the implementation.
  • 这不是正确的做法...只需在编译目标中的库文件中包含正确的主文件。不同的语言,不同的范式,这个范式应该留在python中。
  • @BaummitAugen 我不确定这是不是最好的方法,但我经常遇到我想更改入口点的情况,就像我在 python 中所做的那样,所以看起来喜欢一种自然的方式来做到这一点。不过,我确信有更好的选择,并且很高兴听到它们

标签: c++ macros constexpr clang++ entry-point


【解决方案1】:

#if#endifpreprocessor 指令 - 预处理器作为编译步骤的一部分运行,但它不知道 C++ 作为一种语言。

您不能将预处理器与 C++ 功能(例如 constexpr 函数)混合和匹配。

如果你想让它工作,你需要实现你自己的 #define EQUALS 宏,在预处理步骤中完全检查字符串是否相等。我不确定这是否可能(并且值得)。

【讨论】:

  • 虽然this 的回答似乎表明这是可能的。是错了还是我错过了什么?
  • 好的,谢谢您的回答!另外,感谢您在 CppCon 上关于实体组件系统的演讲! ^^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 2018-11-22
相关资源
最近更新 更多