简体   繁体   English

constexpr可在Ubuntu上使用,但不适用于MacOS

[英]constexpr works on Ubuntu, but not MacOS

I have this code which compiles fine on Ubuntu, but when I try to compile it on MacOS I get this error: 我有这段代码可以在Ubuntu上很好地编译,但是当我尝试在MacOS上编译时,出现此错误:

Constexpr variable 'HeuristicNames' must be initialized by a constant expression
#define LSHPair std::pair<const char *, LISTSCHED_HEURISTIC>
static constexpr LSHPair HeuristicNames[] = {
    LSHPair("CP", LSH_CP),    LSHPair("LUC", LSH_LUC),
    LSHPair("UC", LSH_UC),    LSHPair("NID", LSH_NID),
    LSHPair("CPR", LSH_CPR),  LSHPair("ISO", LSH_ISO),
    LSHPair("SC", LSH_SC),    LSHPair("LS", LSH_LS),
    LSHPair("LLVM", LSH_LLVM)};

LISTSCHED_HEURISTIC is an enum . LISTSCHED_HEURISTIC是一个enum

I take this error to mean that some part of the right hand side of the assignment is not a constexpr , so the resulting variable can't be a constexpr . 我认为这个错误意味着赋值右侧的某些部分不是constexpr ,因此结果变量不能是constexpr However I don't have a firm enough grasp of the rules around constexpr to understand why, or how to fix it. 但是,我对constexpr的规则了解不够深刻,无法理解其原因或解决方法。

I also don't get why this is different on MacOS than on Ubuntu. 我也不明白为什么MacOS和Ubuntu上的区别。 Can anyone shed some light on this? 谁能对此有所启发?

First of all you do not need macro. 首先,您不需要宏。 You could define type 您可以定义类型

using LSHPair =  std::pair<const char *, LISTSCHED_HEURISTIC>;

Or just use brace initialization, what is much more clean: 或者只是使用大括号初始化,更干净的是:

using LSHPair =  std::pair<const char *, LISTSCHED_HEURISTIC>;

static constexpr LSHPair HeuristicNames[] = {
    {"CP", LSH_CP},
    {"LUC", LSH_LUC},
    {"UC", LSH_UC},   
    {"NID", LSH_NID},
    {"CPR", LSH_CPR},
    {"ISO", LSH_ISO},
    {"SC", LSH_SC}, 
    {"LS", LSH_LS},
    {"LLVM", LSH_LLVM}
};

As @CuriouslyRecurringThoughts point out constructor of std::pair is a constexpr since c++14 . 正如@CuriouslyRecurringThoughts指出, c++14开始, std::pair构造函数是constexpr

I've test this on my Mac OS and apparently clang there works a bit differently then on Linux (as shown on compiler explorer ): 我已经在Mac OS上进行了测试,显然clang的工作原理与Linux有所不同(如编译器资源管理器所示 ):

Marek R$ g++ main.cpp -std=c++11
main.cpp:17:26: error: constexpr variable 'HeuristicNames' must be initialized by a constant expression
static constexpr LSHPair HeuristicNames[] = {
                         ^                  ~
main.cpp:18:5: note: non-constexpr constructor 'pair<char const (&)[3], LISTSCHED_HEURISTIC, false>' cannot be used in a constant expression
    {"CP", LSH_CP},
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/utility:446:5: note: declared here
    pair(_U1&& __u1, _U2&& __u2)
    ^
1 error generated.
Marek R$ g++ main.cpp -std=c++14
Marek R$ 

So MacOS clang is right. 因此,MacOS clang是正确的。

Problem must be on header files and versioning them depending on C++ standard. 问题必须出在头文件上,并根据C ++标准对其进行版本控制。 Most probably same header files of standard library are used for clang and gcc are used on Linux. 标准库的最可能相同的头文件用于clang,而gcc用于Linux。 On Mac std::pair constructor is prefixed by macro _LIBCPP_CONSTEXPR_AFTER_CXX11 which definition changes deeding on C++ standard enabled. 在Mac上, std::pair构造函数以_LIBCPP_CONSTEXPR_AFTER_CXX11宏作为前缀,该宏的定义更改了启用C ++标准时的行为。 On Linux you have to check by yourself how it is done. 在Linux上,您必须自己检查它是如何完成的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM