此代码是否违反了一个定义规则?
Does this code violate 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 () { 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;
};
构建脚本:
...
srcs: [
...
"src/hb-ot-cff1-table.cc",
"src/hb-ot-cff2-table.cc",
],
...
https://android.googlesource.com/platform/external/harfbuzz_ng/+/refs/heads/android10-gsi/Android.bp
这些资源也内置在同一个共享库中。两个来源都有"struct ExtentsParam"的定义,内容完全不同。这两个结构似乎都只在本地使用。
这两个来源的名称相似,因此无意中重复名称的可能性很小。 Google 中违反 ODR 的可能性可能很低。
是吗?
是:因为它们都在全局命名空间中,这绝对违反了 ODR。
仅在定义它们的翻译单元中使用的 class 类型没有豁免;程序只能包含 one class 具有任何给定名称的类型。
它符合豁免此规则的条件的第一个要求:
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. [..] Given such an entity named D
defined in more than one translation unit, all of the following requirements shall be satisfied. [..] Each definition of D
shall consist of the same sequence of tokens [..] (ref)
开发人员只是 "getting lucky" 链接器没有尝试执行任何导致此违规症状的滑稽动作。
这就是命名空间的用途。例如,如果 class 类型仅在定义它的翻译单元中使用,则可以在匿名命名空间中定义它。
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;
};
构建脚本:
...
srcs: [
...
"src/hb-ot-cff1-table.cc",
"src/hb-ot-cff2-table.cc",
],
...
https://android.googlesource.com/platform/external/harfbuzz_ng/+/refs/heads/android10-gsi/Android.bp
这些资源也内置在同一个共享库中。两个来源都有"struct ExtentsParam"的定义,内容完全不同。这两个结构似乎都只在本地使用。
这两个来源的名称相似,因此无意中重复名称的可能性很小。 Google 中违反 ODR 的可能性可能很低。
是吗?
是:因为它们都在全局命名空间中,这绝对违反了 ODR。
仅在定义它们的翻译单元中使用的 class 类型没有豁免;程序只能包含 one class 具有任何给定名称的类型。
它符合豁免此规则的条件的第一个要求:
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. [..] Given such an entity named
D
defined in more than one translation unit, all of the following requirements shall be satisfied. [..] Each definition ofD
shall consist of the same sequence of tokens [..] (ref)
开发人员只是 "getting lucky" 链接器没有尝试执行任何导致此违规症状的滑稽动作。
这就是命名空间的用途。例如,如果 class 类型仅在定义它的翻译单元中使用,则可以在匿名命名空间中定义它。