架构x86_64的未定义符号链接constexpr std :: array

Undefined symbols for architecture x86_64 linking constexpr std::array

本文关键字:constexpr std 符号链接 array 未定义 x86 架构      更新时间:2023-10-16

我在链接对象文件时会遇到错误:

#include <cstdint>
#include <array>
enum SystemType : uint8_t { AC, DC, HCP, EFF };
template<SystemType TYPE> struct System;
template<> 
struct System<AC> { 
public:     
static constexpr size_t number_of_sockets = 2;  
static constexpr std::array<size_t, number_of_sockets> object_per_socket { { 12, 6 } }; 
};

我正在将其如下所示将数据分配为向量。

terminal->no_obj_per_system.assign(
            Sytem<AC>::object_per_socket.begin(),
            Sytem<AC>::object_per_socket.end());

我在Mac OS上使用clang。

在C 14和更早之前,静态数据成员如果它们是 odr-使用的,则必须在一个翻译单元中具有一个隔离的定义;此规则仍然适用于constexpr成员。

这个问题包含一个示例,其中包含来自C 14标准的参考。

如果没有提供课外定义,并且该变量是 odr使用的,则不需要诊断,这解释了为什么有些人没有得到汇编错误。为了安全起见,您应该提供一个定义,即使在变量不使用 odr使用的情况下,也没有损害。

定义看起来像(不在标题文件中(:

constexpr std::array<size_t, System<AC>::number_of_sockets>  System<AC>::object_per_socket;

在C 17中,有一个新功能"内联变量",它允许在具有与内联函数相似的语义的标题文件中定义变量,即,您可以在翻译单元中具有多个匹配的定义,并且编译器/链接器将根据需要选择一个。constexpr变量将是隐式inline,因此您的原始代码在C 17中是正确的。GCC和Clang的最新版本应使用-std=c++1z标志接受代码。