使用constexpr静态成员变量的奇怪行为 [英] Strange behavior with constexpr static member variable

查看:142
本文介绍了使用constexpr静态成员变量的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是针对静态constexpr的未定义引用的后续问题char [] []

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

The following program builds and runs fine.

#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;
}


$ b )到:

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



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

I get the following linker error in 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[];

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

However, it's not clear to me why using one of the members of the array does not cause a linker error while using the array causes a linker error.

推荐答案

标准不需要任何诊断,无法提供需要定义的定义。

The standard does not require any diagnostics for a failure to provide a definition where one is required.


3.2一个定义规则[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。

This means implementations are allowed to optimise away accesses to such variables, and that's what's happening in your first case with GCC.

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

Both GCC and clang have decided that they prefer a consistent user experience, where error messages about missing definitions do not depend on the optimisation level. Usually, that means that any missing definition causes an error message. However, in this case, GCC is doing some minimal optimisation even at -O0, avoiding the error.

但是程序是一种错误的方式,因为即使 A :: dict [0] 是一个ODR使用:

But the program is an error either way, because even A::dict[0] is an ODR-use:


3.2一个定义规则[basic.def.odr]

3一个变量 ex 使用作为潜在评估表达式的除非将 x 的左值到右值转换(4.1)应用到不调用任何非平凡函数的常量表达式(5.19),如果 x 是一个对象, ex 是表达式 e ,其中左值到右值转换(4.1)应用于 e e 是一个废值表达式(第5条)。 [...]

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 t涉及到左值到右值的转换,它涉及数组到指针的转换,因此该异常不适用。

The use of A::dict doesn't involve lvalue-to-rvalue conversion, it involves the array-to-pointer conversion, so the exception doesn't apply.

这篇关于使用constexpr静态成员变量的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆