From Jason Turner

[dcl.attr.depend]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp9nf39g87/{from.md → to.md} +0 -74
tmp/tmp9nf39g87/{from.md → to.md} RENAMED
@@ -1,74 +0,0 @@
1
- ### Carries dependency attribute <a id="dcl.attr.depend">[[dcl.attr.depend]]</a>
2
-
3
- The *attribute-token* `carries_dependency` specifies dependency
4
- propagation into and out of functions. No *attribute-argument-clause*
5
- shall be present. The attribute may be applied to a parameter of a
6
- function or lambda, in which case it specifies that the initialization
7
- of the parameter carries a dependency to [[intro.multithread]] each
8
- lvalue-to-rvalue conversion [[conv.lval]] of that object. The attribute
9
- may also be applied to a function or a lambda call operator, in which
10
- case it specifies that the return value, if any, carries a dependency to
11
- the evaluation of the function call expression.
12
-
13
- The first declaration of a function shall specify the
14
- `carries_dependency` attribute for its *declarator-id* if any
15
- declaration of the function specifies the `carries_dependency`
16
- attribute. Furthermore, the first declaration of a function shall
17
- specify the `carries_dependency` attribute for a parameter if any
18
- declaration of that function specifies the `carries_dependency`
19
- attribute for that parameter. If a function or one of its parameters is
20
- declared with the `carries_dependency` attribute in its first
21
- declaration in one translation unit and the same function or one of its
22
- parameters is declared without the `carries_dependency` attribute in its
23
- first declaration in another translation unit, the program is
24
- ill-formed, no diagnostic required.
25
-
26
- [*Note 1*: The `carries_dependency` attribute does not change the
27
- meaning of the program, but might result in generation of more efficient
28
- code. — *end note*]
29
-
30
- [*Example 1*:
31
-
32
- ``` cpp
33
- /* Translation unit A. */
34
-
35
- struct foo { int* a; int* b; };
36
- std::atomic<struct foo *> foo_head[10];
37
- int foo_array[10][10];
38
-
39
- [[carries_dependency]] struct foo* f(int i) {
40
- return foo_head[i].load(memory_order::consume);
41
- }
42
-
43
- int g(int* x, int* y [[carries_dependency]]) {
44
- return kill_dependency(foo_array[*x][*y]);
45
- }
46
-
47
- /* Translation unit B. */
48
-
49
- [[carries_dependency]] struct foo* f(int i);
50
- int g(int* x, int* y [[carries_dependency]]);
51
-
52
- int c = 3;
53
-
54
- void h(int i) {
55
- struct foo* p;
56
-
57
- p = f(i);
58
- do_something_with(g(&c, p->a));
59
- do_something_with(g(p->a, &c));
60
- }
61
- ```
62
-
63
- The `carries_dependency` attribute on function `f` means that the return
64
- value carries a dependency out of `f`, so that the implementation need
65
- not constrain ordering upon return from `f`. Implementations of `f` and
66
- its caller may choose to preserve dependencies instead of emitting
67
- hardware memory ordering instructions (a.k.a. fences). Function `g`’s
68
- second parameter has a `carries_dependency` attribute, but its first
69
- parameter does not. Therefore, function `h`’s first call to `g` carries
70
- a dependency into `g`, but its second call does not. The implementation
71
- might need to insert a fence prior to the second call to `g`.
72
-
73
- — *end example*]
74
-