gpt4 book ai didi

c++ - constexpr 静态成员变量的奇怪行为

转载 作者:可可西里 更新时间:2023-11-01 15:22:26 24 4
gpt4 key购买 nike

这是对 Undefined reference to static constexpr char[][] 的后续问题.

以下程序构建并运行良好。

#include <iostream>

struct A {
constexpr static char dict[] = "test";

void print() {
std::cout << A::dict[0] << std::endl;
}
};

int main() {
A a;
a.print();
return 0;
}

但是,如果我将 A::print() 更改为:

   void print() {
std::cout << A::dict << std::endl;
}

我在 g++ 4.8.2 中收到以下链接器错误。

/tmp/cczmF84A.o: In function `A::print()':socc.cc:(.text._ZN1A5printEv[_ZN1A5printEv]+0xd): undefined reference to `A::dict'collect2: error: ld returned 1 exit status

The linker error can be resolved by adding a line:

constexpr char A::dict[];

在类定义之外。

但是,我不清楚为什么使用数组的其中一个成员不会导致链接器错误,而使用数组会导致链接器错误。

最佳答案

该标准不要求对故障进行任何诊断以提供需要的定义。

3.2 One definition rule [basic.def.odr]

4 Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. [...]

这意味着实现可以优化对此类变量的访问,这就是您使用 GCC 的第一个案例中发生的情况。

GCC 和 clang 都决定他们更喜欢一致的用户体验,其中有关缺少定义的错误消息不依赖于优化级别。通常,这意味着任何缺少的定义都会导致错误消息。但是,在这种情况下,GCC 即使在 -O0 也会进行一些最小的优化,从而避免错误。

但程序无论如何都是错误的,因为即使 A::dict[0] 也是 ODR 使用:

3.2 One definition rule [basic.def.odr]

3 A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.19) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression (Clause 5). [...]

A::dict 的使用不涉及左值到右值的转换,它涉及数组到指针的转换,所以异常(exception)不适用。

关于c++ - constexpr 静态成员变量的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28530583/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com