【发布时间】:2020-02-24 12:57:15
【问题描述】:
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,与其他格式不正确的程序 NDR(以及 UB)一样,事情可以“按预期工作”。所以在这些情况下很容易被忽视。
-
@Jarod42 是否有可能不违反 ODR?如果 ODR 可以存在于 Google 的代码中,那为什么构建系统很久以前不开始检查这些潜在的模式,而这并没有花费太多时间?
-
根据您提供的部分信息,无法确定。假设两个源文件都被编译并链接到同一个程序中,并且
struct ExtentsParam在同一个范围内(例如在同一个命名空间中),那么行为是未定义的,因为struct定义不包含同一组令牌。如果与此有差异(例如,两个struct定义位于不同的命名空间中),则行为可能是明确定义的。 -
@jw_ 这是个好问题。老实说,我希望静态分析器能够捕捉到这一点。