What does the carries_dependency attribute mean?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
[[carries_dependency]] is a C++ attribute intended for highly specialized lock-free code that relies on dependency ordering. It tells the compiler that a dependency chain should be preserved across a function boundary for memory-order reasoning. Most modern C++ code never needs it, and many projects should avoid it for clarity.
Background: Dependency Ordering
In atomic programming, one thread may publish data and another thread may consume a pointer or index to that data. Some architectures preserve certain data-dependent ordering without a full acquire barrier. Historically, memory_order_consume attempted to model this, but practical compiler support has been weak and complicated.
[[carries_dependency]] was introduced to help propagate dependency information through function calls.
Where the Attribute Can Appear
You may apply it to function parameters or return values in declarations to indicate dependency transfer intent.
In theory, this signals that dependency from read_head result is carried into read_value argument usage.
Why It Is Rare in Production Code
In practice, many compilers map memory_order_consume to memory_order_acquire or otherwise do not provide robust dependency-based optimization. As a result, codebases often prefer explicit acquire semantics and avoid fragile dependency assumptions.
Safer mainstream approach:
This is clearer to reviewers and tools, and behavior is more portable.
Relationship to std::kill_dependency
C++ also provides std::kill_dependency, used to intentionally break dependency chains when needed for optimization. Both features target advanced use cases and are uncommon in everyday application code.
Most teams should treat this as expert-level tuning territory.
Guidance for Real Projects
Use [[carries_dependency]] only when all conditions are true.
- You are writing lock-free low-level components.
- You have measured architecture-specific performance impact.
- Toolchain behavior is validated on your supported compilers.
- Team reviewers are comfortable maintaining this memory-model complexity.
If any condition is missing, use acquire-release semantics for maintainability.
Testing and Verification Strategy
For low-level concurrency code, combine correctness and performance validation.
- Stress tests with high thread counts and randomized schedules.
- Sanitizers such as ThreadSanitizer for race detection.
- Cross-compiler CI to detect divergent behavior.
- Microbenchmarks tied to target architecture.
Without this discipline, dependency-order tricks are more risk than value.
Function Boundary Example and Intent
The attribute primarily exists for cases where dependency should survive helper function layers. Without annotation, compiler reasoning may drop that dependency information.
Even with this form, many teams still choose memory_order_acquire because intent is clearer and tooling support is stronger. Treat dependency attributes as low-level optimization hints, not correctness foundations.
Portability and Maintenance Tradeoff
Concurrency bugs are expensive to diagnose, so readability often beats theoretical micro-optimizations. If you adopt dependency-oriented code, document assumptions in comments and architecture notes, and keep focused regression tests for each supported compiler toolchain.
Common Pitfalls
- Assuming
[[carries_dependency]]provides universal speedups. - Using it in business-logic code where readability is more important.
- Relying on
memory_order_consumebehavior without compiler-specific validation. - Mixing dependency-based and acquire-release models inconsistently.
- Introducing subtle ordering bugs that only appear on specific CPU architectures.
Summary
[[carries_dependency]]is a specialized hint for dependency-chain propagation.- It is related to lock-free optimization and
memory_order_consumesemantics. - Real-world compiler support and portability concerns limit practical use.
- Most projects should prefer explicit acquire-release ordering.
- Use dependency attributes only in carefully measured, low-level concurrency code.
Related reading
- What does the property Nonatomic mean?
- What does the thread_local mean in C11?
- What does this thread join code mean?
- What does this thread join code mean?
- What exactly is stdatomic?
- What happens to a detached thread when main exits?
- What does threadsafe mean?
- What does use_lockingTrue do in TensorFlow optimizers?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.