Skip to content

Case 78: task_arena::attach Tag Type Replaces Enum

Field Value
Verdict ๐Ÿ”ด BREAKING
Category Breaking
Platforms Linux, macOS, Windows
Flags ABI break, API break
Detected ChangeKinds func_removed, type_removed
Source files examples/case78_task_arena_attach_tag/

Category: Symbol API | Verdict: ๐Ÿ”ด BREAKING

Verdict and consumer impact

An attach_mode_t enum plus the task_arena(attach_mode_t) constructor are replaced by an empty tag struct task_arena::attach and a task_arena(attach) constructor. The old enum, its members, and the old constructor's mangled symbol are all removed. Consumer source that wrote task_arena ta(attach_to_current); no longer compiles against v2's headers, and a binary compiled against v1 can't even link against v2's .so โ€” the old constructor's mangled name is gone. Mirrors the real oneTBB 2021 task_arena::attach tag-type introduction.

Old/new diff

v1.h v2.h
enum attach_mode_t { no_attach=0, attach_to_current=1 }; (removed)
explicit task_arena(attach_mode_t mode); struct attach {}; explicit task_arena(attach tag);

abicheck command

g++ -std=c++17 -shared -fPIC -g v1.cpp -o libfoo_v1.so
g++ -std=c++17 -shared -fPIC -g v2.cpp -o libfoo_v2.so
abicheck compare libfoo_v1.so libfoo_v2.so

Expected abicheck finding

Verdict: BREAKING (exit 4)

- func_removed_elf_only: Elf_only function removed:
  mylib::task_arena::task_arena(mylib::attach_mode_t)
  > Exported function symbol removed from the binary; old binaries that
    link or dlsym() it can fail even without header evidence.

Additions:
- func_added: New public function:
  mylib::task_arena::task_arena(mylib::task_arena::attach)
- type_added: New type: mylib::task_arena::attach

Note: the CLI warns --scope-public-headers could not resolve the public surface here because no headers were passed (the L1 floor below is DWARF-only) โ€” it falls back to the full export table, which is what this case needs.

Minimum evidence

min_evidence: L1 โ€” the exported-symbol table plus DWARF is enough: the old constructor's mangled name (encoding attach_mode_t as a parameter type) is present in v1's .dynsym/DWARF and absent from v2's, so func_removed_elf_only fires without any header/AST evidence. Passing public headers (-H + --ast-frontend clang) sharpens this further โ€” the header-scoped run additionally reports type_removed: attach_mode_t and a cleaner func_removed: task_arena โ€” but that extra precision isn't required to reach the BREAKING verdict.

Why abicheck catches it

The removed constructor's mangled symbol (which itanium-encodes its attach_mode_t parameter type) simply isn't present in v2's dynamic symbol table โ€” DWARF/ELF evidence alone is sufficient; func_removed/ func_removed_elf_only is one of the BREAKING_KINDS under default policy, so no dedicated detector is needed for this case.

Runtime failure demonstration

Severity: CRITICAL โ€” both a source break and an ABI break

Scenario A โ€” source break: compiling existing consumer source against v2's header.

g++ -std=c++17 app.cpp -L. -lmylib -Wl,-rpath,. -o app
# โ†’ app.cpp:5:33: error: 'attach_to_current' is not a member of 'mylib'
#   mylib::task_arena ta(mylib::attach_to_current);

Scenario B โ€” ABI break: a binary already compiled against v1 fails to link/load against v2's library, because the old constructor's mangled symbol no longer exists โ€” the same failure mode as case01's plain symbol removal, just on a C++-mangled constructor name instead of a C function.

Safe redesign

Ship a deprecation cycle instead of a hard cutover: in release N-1, add the tag type and the tag-form constructor while keeping the enum and the old constructor, marking the enum and old constructor [[deprecated]]. Only remove the deprecated path in release N. Resist removing the old enum aggressively โ€” a tag-dispatch cleanup feels "purely additive" until measured against the downstream consumer fleet.

Real-world example: oneTBB 2021 introduced task_arena::attach as a tag type; the transition broke both source and ABI for consumers still using the enum-value form.

References

  • oneTBB 2021 release notes โ€” task_arena::attach tag introduction.

Source files

  • CMakeLists.txt
  • app.cpp
  • v1.cpp
  • v1.h
  • v2.cpp
  • v2.h

See also: Examples overview ยท All BREAKING cases ยท Category: Breaking.