[英]Can const data members have different values between translation units?
I'm wondering if it is permitted to declare the same class multiple times using different values for a const member, or if this would be an ODR violation?我想知道是否允许使用 const 成员的不同值多次声明相同的 class ,或者这是否会违反 ODR? Consider this example with two independent translation units that are going to be linked into some libx
library:考虑这个带有两个独立翻译单元的示例,它们将链接到某个libx
库中:
// x.h
#pragma once
class X {
const int x = VALUE;
};
// x1.cpp
#define VALUE 1
#include "x.h"
int fn1() {
X x;
return x.x;
}
// x2.cpp
#define VALUE 2
#include "x.h"
int fn2() {
X x;
return x.x;
}
Also, in case this is not legal, does it make a difference whether x
is declared const
or not?此外,如果这不合法,是否将x
声明为const
是否会有所不同?
From One Definition Rule's documentation :从一个定义规则的文档中:
There can be more than one definition in a program of each of the following: class type , enumeration type, inline function, inline variable (since C++17), templated entity (template or member of template, but not full template specialization), as long as all of the following is true:一个程序中可以有多个以下定义: class 类型、枚举类型、内联 function、内联变量(C++17 起)、模板化实体(模板或模板成员,但不是完整的模板特化) ,只要满足以下所有条件:
- each definition consists of the same sequence of tokens (typically, appears in the same header file)每个定义由相同的标记序列组成(通常出现在同一个 header 文件中)
So you have ODR violation in your program.因此,您的程序中存在 ODR 违规。 Also this is independent of whether the data member is const
or not.这也与数据成员是否为const
无关。
No.不。
Each such definition shall consist of the same sequence of tokens每个这样的定义都应由相同的令牌序列组成
You can can find the legalese in §6.3 [basic.def.odr]您可以在 §6.3 [basic.def.odr] 中找到法律术语
Yes, different objects can have different const
data members.是的,不同的对象可以有不同的const
数据成员。 The issue that the comments are focussing on is in the way that the data member gets initialized, which doesn't really address the issue.评论关注的问题是数据成员的初始化方式,这并没有真正解决问题。
struct s {
const int x;
s(int xx) : x(xx) {}
};
s s1(1);
s s2(2);
What you can't do is define the same name in multiple translation units with a different definition:您不能做的是在具有不同定义的多个翻译单元中定义相同的名称:
// a1.cpp
s s1(1);
// a2.cpp
s s1(2);
that's a violation of the one definition rule.这违反了单一定义规则。 But it has nothing to do with the const
data member;但它与const
数据成员无关; the same problem would occur if s::x
was not const
.如果s::x
不是const
,也会出现同样的问题。 And you'd have an ODR violation in your original example if x
was plain int
, not const
.如果x
是普通的int
而不是const
,那么您在原始示例中就会违反 ODR。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.