C++ 此代码是否违反一条定义规则?

C++ 此代码是否违反一条定义规则?,c++,one-definition-rule,C++,One Definition Rule,AOSP10中的某些代码似乎违反了ODR: 资料来源1: struct ExtentsParam { void init (const OT::cff1::accelerator_t *_cff) { path_open = false; cff = _cff; bounds.init (); } void start_path () { path_open = true; } void end_path () {

AOSP10中的某些代码似乎违反了ODR:

资料来源1:

struct ExtentsParam
{
  void init (const OT::cff1::accelerator_t *_cff)
  {
    path_open = false;
    cff = _cff;
    bounds.init ();
  }
  void start_path ()         { path_open = true; }
  void end_path ()           { path_open = false; }
  bool is_path_open () const { return path_open; }
  bool    path_open;
  Bounds  bounds;
  const OT::cff1::accelerator_t *cff;
};
发件人:

资料来源2:

struct ExtentsParam
{
  void init ()
  {
    path_open = false;
    min_x.set_int (0x7FFFFFFF);
    min_y.set_int (0x7FFFFFFF);
    max_x.set_int (-0x80000000);
    max_y.set_int (-0x80000000);
  }
  void start_path ()         { path_open = true; }
  void end_path ()           { path_open = false; }
  bool is_path_open () const { return path_open; }
  void update_bounds (const Point &pt)
  {
    if (pt.x < min_x) min_x = pt.x;
    if (pt.x > max_x) max_x = pt.x;
    if (pt.y < min_y) min_y = pt.y;
    if (pt.y > max_y) max_y = pt.y;
  }
  bool  path_open;
  Number min_x;
  Number min_y;
  Number max_x;
  Number max_y;
};

这些资源也构建在同一个共享库中。这两个源文件都有“struct ExtentsParam”的定义,内容完全不同。这两个结构似乎只在本地使用

这两个源具有相似的名称,因此不连续的名称重复的可能性很低。谷歌违反ODR的可能性很低


是吗?

:由于它们都在全局名称空间中,这绝对违反了ODR

仅在定义类类型的翻译单元中使用的类类型没有豁免;一个程序只能包含一个具有任何给定名称的类类型

它属于满足本规则豁免标准的第一个要求:

[…]类类型[…]可以有多个定义 在程序中,如果每个定义出现在不同的翻译单元中,并且定义满足以下要求。[……]鉴于在多个翻译单位中定义了名为
D
的实体,应满足以下所有要求。[…]每个
D
的定义应包含相同的令牌序列[…]()

开发人员只是“走运”了,链接器没有尝试做任何导致违规症状的滑稽动作


这就是名称空间的用途。例如,如果类类型仅在定义它的转换单元中使用,则它可以在匿名名称空间中定义。

:因为它们都在全局名称空间中,这绝对违反了ODR

仅在定义类类型的翻译单元中使用的类类型没有豁免;一个程序只能包含一个具有任何给定名称的类类型

它属于满足本规则豁免标准的第一个要求:

[…]类类型[…]可以有多个定义 在程序中,如果每个定义出现在不同的翻译单元中,并且定义满足以下要求。[……]鉴于在多个翻译单位中定义了名为
D
的实体,应满足以下所有要求。[…]每个
D
的定义应包含相同的令牌序列[…]()

开发人员只是“走运”了,链接器没有尝试做任何导致违规症状的滑稽动作


这就是名称空间的用途。例如,如果类类型仅在定义它的转换单元中使用,则它可能在匿名命名空间中定义。

键入问题中的代码,而不是提供引用。与其他格式错误的程序NDR(以及UB)一样,ODR可以“按预期工作”。所以在这些情况下,bug很容易被忽略。@Jarod42它有可能不违反ODR吗?如果ODR可以存在于谷歌的代码中,那么为什么构建系统很久以前就开始检查这些潜在的模式,而这些模式不会占用太多时间?从您提供的部分信息来看,这是不可能确定的。假设两个源文件都被编译并链接到同一个程序中,并且
struct ExtentsParam
在相同的范围内(例如,在相同的名称空间中),那么行为是未定义的,因为
struct
定义不包含相同的标记集。如果与此不同(例如,两个
struct
定义在不同的名称空间中),那么行为可能定义得很好。@jw_u这是个好问题。老实说,我希望静态分析器能够捕捉到这一点。在问题中键入代码,而不是提供引用。与其他格式错误的程序NDR(以及UB)一样,使用ODR,事情可以“按预期工作”。所以在这些情况下,bug很容易被忽略。@Jarod42它有可能不违反ODR吗?如果ODR可以存在于谷歌的代码中,那么为什么构建系统很久以前就开始检查这些潜在的模式,而这些模式不会占用太多时间?从您提供的部分信息来看,这是不可能确定的。假设两个源文件都被编译并链接到同一个程序中,并且
struct ExtentsParam
在相同的范围内(例如,在相同的名称空间中),那么行为是未定义的,因为
struct
定义不包含相同的标记集。如果与此不同(例如,两个
struct
定义在不同的名称空间中),那么行为可能定义得很好。@jw_u这是个好问题。老实说,我希望静态分析器能够捕捉到这一点。
...
srcs: [
    ...
    "src/hb-ot-cff1-table.cc",
    "src/hb-ot-cff2-table.cc",
],
...