Does this code violate One Definition Rule?

1

Some code in AOSP10 seems to violate ODR:

source 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;
};

from: https://android.googlesource.com/platform/external/harfbuzz_ng/+/refs/heads/android10-gsi/src/hb-ot-cff1-table.cc

source 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;
};

from: https://android.googlesource.com/platform/external/harfbuzz_ng/+/refs/heads/android10-gsi/src/hb-ot-cff2-table.cc

build script:

...
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

These too sourses are built into the same shared library. Both sources have the definition of "struct ExtentsParam" and the content are absolutely different. Both struct seems to be used only locally.

The two source have similiar names so the chance of unintentinal name duplication is low. And the chance of ODR violation in Google could be low.

Does it?

c++
one-definition-rule
asked on Stack Overflow Feb 24, 2020 by jw_ • edited Feb 24, 2020 by jw_

1 Answer

5

Yes: as these are both in the global namespace, this absolutely violates the ODR.

There is no exemption for class types used only within the translation unit in which they're defined; a program may only contain one class type with any given name.

It falls at the very first requirement for meeting criteria for exemption from this rule:

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)

The developers are just "getting lucky" that the linker didn't try to do any antics that result in symptoms for this violation.

This is what namespaces are for. For example, if the class type is only used within the translation unit in which it's defined, it could have been defined inside an anonymous namespace.


User contributions licensed under CC BY-SA 3.0