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 违规