Title
Linkage and deduced return types
Status
cd5
Section
9.2.9.6 [dcl.spec.auto]
Submitter
Richard Smith

Created on 2014-12-15.00:00:00 last changed 2 months ago

Messages

Date: 2017-11-15.00:00:00

Proposed resolution (November, 2017)

Change 6.6 [basic.link] paragraph 8 as follows:

...A type without linkage shall not be used as the type of a variable or function with external linkage unless

  • the entity has C language linkage (9.11 [dcl.link]), or

  • the entity is declared within an unnamed namespace (9.8.2 [namespace.def]), or

  • the entity is not odr-used (6.3 [basic.def.odr]) or is defined in the same translation unit.

[Note: In other words, a type without linkage contains a class or enumeration that cannot be named outside its translation unit. An entity with external linkage declared using such a type could not correspond to any other entity in another translation unit of the program and thus must be defined in the translation unit if it is odr-used. Also note that classes Classes with linkage may contain members whose types do not have linkage, and that typedef. Typedef names are ignored in the determination of whether a type has linkage. —end note] [Example:

  template <class T> struct B {
    void g(T) { }
    void h(T);
    friend void i(B, T) { }
  };

  void f() {
    struct A { int x; };  // no linkage
    A a = { 1 };
    B<A> ba;              // declares B<A>::g(A) and B<A>::h(A)
    ba.g(a);              // OK
    ba.h(a);              // error: B<A>::h(A) not defined; A cannot be named in the another translation unit
    i(ba, a);             // OK
  }

end example]

Date: 2016-02-15.00:00:00

Notes from the February, 2016 meeting:

CWG agreed that the current rule in 6.6 [basic.link] paragraph 8 is unneeded; the ODR already prohibits use of an entity that is not defined in the current translation unit and cannot be defined in a different translation unit.

Date: 2018-03-15.00:00:00

[Accepted as a DR at the March, 2018 (Jacksonville) meeting.]

Use of function return type deduction makes it possible to define functions whose return type is a type without linkage. Although 6.6 [basic.link] paragraph 8 permits such a usage if the function is defined in the same translation unit as it is used, it may be helpful to consider changing the overall rules regarding the use of types with internal or no linkage. As an example, the following example permits access to a local static variable that has not been initialized:

  auto f() {
    static int n = 123;
    struct X { int &f() { return n; } };
    return X();
  }
  int &r = decltype(f())().f();
History
Date User Action Args
2020-12-15 00:00:00adminsetstatus: dr -> cd5
2018-04-11 00:00:00adminsetstatus: tentatively ready -> dr
2018-02-27 00:00:00adminsetmessages: + msg5857
2018-02-27 00:00:00adminsetstatus: drafting -> tentatively ready
2017-02-06 00:00:00adminsetmessages: + msg5754
2017-02-06 00:00:00adminsetstatus: open -> drafting
2014-12-15 00:00:00admincreate