attribute-token carries_dependency Распространения определяет зависимость в и из функций. Он должен появляться не более одного раза в каждом attribute-listи не attribute-argument-clauseдолжен присутствовать. Атрибут может быть применен к declarator-ida parameter-declarationв объявлении функции или лямбда-выражении, и в этом случае он указывает инициализацию параметра carries a dependency для каждого lvalue-to-rvalue conversion из этих объектов. Атрибут также может применяться к declarator-idобъявлению функции, и в этом случае он указывает, что возвращаемое значение, если оно есть, несет зависимость от оценки выражения вызова функции.
Первое объявление функции должно указывать carries_dependency атрибут для ее, declarator-idесли какое-либо объявление функции указывает carries_dependency атрибут. Кроме того, первое объявление функции должно указывать carries_dependency атрибут для параметра, если какое-либо объявление этой функции указывает carries_dependency атрибут для этого параметра. Если функция или один из ее параметров объявлен с carries_dependency атрибутом в своем первом объявлении в одной единице трансляции, а та же функция или один из ее параметров объявлен без carries_dependency атрибута в своем первом объявлении в другой единице трансляции, программа имеет неправильный формат. , диагностика не требуется.
[ Атрибут не изменяет значение программы, но может привести к образованию более эффективного кода. ] Note: carries_dependency — end note
[ Example:
/* Translation unit A. */ 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]); } /* Translation unit B. */ [[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)); }
carries_dependency Атрибут функция f означает , что возвращаемое значение несет в себе зависимость из f, так что необходимость осуществления не ограничивает порядок после возвращения из f. Реализации f и вызывающая сторона могут выбрать сохранение зависимостей вместо выдачи инструкций по упорядочиванию аппаратной памяти (также известных как заборы).
Функция gвторой параметр «s имеет carries_dependency атрибут, но его первый параметр не делает. Следовательно, hпервый вызов функции g несет зависимость g, а ее второй вызов - нет. Реализации может потребоваться вставить забор перед вторым вызовом g.
— end example ]