This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-11-11


1475. Errors in [[carries_dependency]] example

Section: 9.12.4  [dcl.attr.depend]     Status: CD3     Submitter: Stephan Lavavej     Date: 2012-03-06

[Moved to DR at the April, 2013 meeting.]

The example in 9.12.4 [dcl.attr.depend] paragraph 4 reads,

  /* 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);
  }

  [[carries_dependency]] int g(int* x, int* y) {
    return kill_dependency(foo_array[*x][*y]);
  }

  /* Translation unit B. */

  [[carries_dependency]] struct foo* f(int i);
  [[carries_dependency]] int* g(int* x, int* y);

  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));
  }

There appear to be two errors in this example. First, g is declared as returning int in TU A but int* in TU B. Second, paragraph 6 says,

Function g's second argument has a carries_dependency attribute

but that is not reflected in the example.

Proposed resolution (August, 2012):

  1. Change the example in 9.12.4 [dcl.attr.depend] paragraph 4 as follows:

  2.   /* 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);
      }
    
      [[carries_dependency]] 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);
      [[carries_dependency]] int* 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));
      }
    
  3. Change 9.12.4 [dcl.attr.depend] paragraph 6 as follows:

  4. Function g's second argument parameter has a carries_dependency attribute, but its first argument 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.