全局常量对静态数据成员的初始化是否会导致未定义的行为?
Does initialization of static data member by a global constant lead to undefined behavior?
我遇到了 (edit: which I now consider wrong) and have a follow-up question. Please consider a code where I use constantly initialized 在全局命名空间范围内声明的整型常量变量,要么不断地初始化常量静态数据成员,要么声明我的 类 的数组数据成员。更好说明的示例:
const int internal_linkage_constant = 1;
class ExternalLinkageClass
{
static const int constexpr_value = internal_linkage_constant; // #1
int arr[internal_linkage_constant]; // #2
};
所有这些 类 的定义都在头文件中,并且可能在多个翻译单元之间共享。全局常量必须在这些定义之前定义,并且本质上不能有外部链接才能在 constant expressions 中使用。
现在我的问题是:这样的初始化是否会由于违反 ODR 而导致未定义的行为?
没有例外。 C++98 标准在第 3.2 章中指出:
There can be more than one definition of a class type, (…) in a
program provided that each definition appears in a different
translation unit, and provided the definitions satisfy the following
requirements:
- each definition of D shall consist of the same sequence of tokens; and
- in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D,
or shall refer to the same entity, after overload resolution (13.3)
and after matching of partial template specialization (14.8.3), except
that a name can refer to a const object with internal or no linkage if
the object has the same integral or enumeration type in all
definitions of D, and the object is initialized with a constant
expression (5.19), and the value (but not the address) of the object
is used, and the object has the same value in all definitions of D;
- (…)
我遇到了
const int internal_linkage_constant = 1;
class ExternalLinkageClass
{
static const int constexpr_value = internal_linkage_constant; // #1
int arr[internal_linkage_constant]; // #2
};
所有这些 类 的定义都在头文件中,并且可能在多个翻译单元之间共享。全局常量必须在这些定义之前定义,并且本质上不能有外部链接才能在 constant expressions 中使用。 现在我的问题是:这样的初始化是否会由于违反 ODR 而导致未定义的行为?
没有例外。 C++98 标准在第 3.2 章中指出:
There can be more than one definition of a class type, (…) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements:
- each definition of D shall consist of the same sequence of tokens; and
- in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), except that a name can refer to a const object with internal or no linkage if the object has the same integral or enumeration type in all definitions of D, and the object is initialized with a constant expression (5.19), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D;
- (…)