const 数据成员在翻译单元之间可以有不同的值吗?
Can const data members have different values between translation units?
我想知道是否允许对 const 成员使用不同的 值 多次声明相同的 class,或者这是否违反 ODR ?考虑这个例子,其中有两个独立的翻译单元将被链接到一些 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;
}
另外,如果这不合法,是否声明 x
const
有区别吗?
没有
Each such definition shall consist of the same sequence of tokens
您可以在 §6.3 中找到法律术语 [basic.def.odr]
来自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:
- each definition consists of the same sequence of tokens (typically, appears in the same header file)
所以你的程序中存在 ODR 违规。此外,这 与数据成员是否 const
无关。
是的,不同的对象可以有不同的 const
数据成员。评论关注的问题是数据成员初始化的方式,这并没有真正解决问题。
struct s {
const int x;
s(int xx) : x(xx) {}
};
s s1(1);
s s2(2);
您不能做的是在具有不同定义的多个翻译单元中定义相同的名称:
// a1.cpp
s s1(1);
// a2.cpp
s s1(2);
这违反了单一定义规则。但是与const
数据成员无关;如果 s::x
不是 const
,也会出现同样的问题。如果 x
是普通的 int
,而不是 const
.
,那么在您的原始示例中就会出现 ODR 违规
我想知道是否允许对 const 成员使用不同的 值 多次声明相同的 class,或者这是否违反 ODR ?考虑这个例子,其中有两个独立的翻译单元将被链接到一些 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;
}
另外,如果这不合法,是否声明 x
const
有区别吗?
没有
Each such definition shall consist of the same sequence of tokens
您可以在 §6.3 中找到法律术语 [basic.def.odr]
来自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:
- each definition consists of the same sequence of tokens (typically, appears in the same header file)
所以你的程序中存在 ODR 违规。此外,这 与数据成员是否 const
无关。
是的,不同的对象可以有不同的 const
数据成员。评论关注的问题是数据成员初始化的方式,这并没有真正解决问题。
struct s {
const int x;
s(int xx) : x(xx) {}
};
s s1(1);
s s2(2);
您不能做的是在具有不同定义的多个翻译单元中定义相同的名称:
// a1.cpp
s s1(1);
// a2.cpp
s s1(2);
这违反了单一定义规则。但是与const
数据成员无关;如果 s::x
不是 const
,也会出现同样的问题。如果 x
是普通的 int
,而不是 const
.