:
struct foo { int* a; int* b; };
std::atomic<struct foo *> foo_head[10];
int foo_array[10][10];
[[carries_dependency]] struct foo* f(int i) {
return foo_head[i].load(memory_order::consume);
}
int g(int* x, int* y [[carries_dependency]]) {
return kill_dependency(foo_array[*x][*y]);
}
[[carries_dependency]] struct foo* f(int i);
int g(int* x, int* y [[carries_dependency]]);
int c = 3;
void h(int i) {
struct foo* p;
p = f(i);
do_something_with(g(&c, p->a));
do_something_with(g(p->a, &c));
}
The
carries_dependency attribute on function
f means that the
return value carries a dependency out of
f, so that the implementation
need not constrain ordering upon return from
f. Implementations of
f and its caller may choose to preserve dependencies instead of emitting
hardware memory ordering instructions (a.k.a. fences)
. Function
g's second parameter has a
carries_dependency attribute,
but its first parameter does not
. Therefore, function
h's first call to
g carries a dependency into
g, but its second call does not
. The
implementation might need to insert a fence prior to the second call to
g. —
end example