10 Declarations [dcl.dcl]

10.6 Attributes [dcl.attr]

10.6.3 Carries dependency attribute [dcl.attr.depend]

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]