Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are local class rules aligned to c++14 return type deduction?

While reading this part of C++14 (a free draft N4141, closest to C++14):

9.8 Local class declarations [class.local]

[..] The name of a local class is local to its enclosing scope. [..]

Declarations in a local class shall not odr-use (3.2) a variable with automatic storage duration from an enclosing scope. [ Example:

//[..]
void f() 
{ 
    static int s ; 
    int x; 
    // [..]
    struct local { 
       int g() { return x; } // error: odr-use of automatic variable x 
       int h() { return s; } // OK 
       // [..]
   };
}
local* p = 0; // error: local not in scope

—end example ]

I noticed, that, first - I can define p with return value auto deduction:

auto f()
{
  static int s;
  int x;
  struct local
  {
     int h() { return s; }
  };
  return local{};
}
decltype(f())* p = 0; // OK - ignored, that local is not in scope!

Maybe it seems ok, why not to use local type by deducing it from function return value, but - it seems in this way I can access local s variable before it is constructed:

struct TalkativeInt
{
    TalkativeInt() : value() 
    {
        std::cout << "TalkativeInt()\n";
    }
    TalkativeInt(int value) : value(value) 
    {
        std::cout << "TalkativeInt(" << value << ")\n";
    }

    int value;
};

auto f()
{
  static TalkativeInt s = 7;
  int x;
  struct local
  {
     auto h() { return s.value; }
  };
  return local{};
}
decltype(f())* p = 0;

int main() {
    decltype(f()) l;
    std::cout << l.h();
}

Output is just::

0

But one might expect:

TalkativeInt(7)
7

Both clang and gcc do not protest in any way, see demo.

I wonder, maybe such case should be mentioned somehow either in

9.8 Local class declarations [class.local]

or in

7.1.6.4 auto specifier [dcl.spec.auto]

?

Of course, I feel that reading (and writing) from variable before it is constructed is bad thing, but I have not found anything about that in standard - probably, it was not possible before C++14? Or there are some basic rules I just overlooked?

like image 393
PiotrNycz Avatar asked Jan 18 '17 16:01

PiotrNycz


People also ask

Can auto be used as return type in C++?

In C++14, you can just use auto as a return type.

Which C++ added feature of Auto for return type of function?

The “auto” keyword used to say the compiler: “The return type of this function is declared at the end”. In C++14, the compiler deduces the return type of the methods that have “auto” as return type.

Should you use this in C++?

You must use the this pointer when: Returning the current object. Setting up relations between objects (passing this into a constructor or setter) Checking for self reference: this !=

What does Decltype auto do?

Use auto and decltype to declare a function template whose return type depends on the types of its template arguments. Or, use auto and decltype to declare a function template that wraps a call to another function, and then returns the return type of the wrapped function.


1 Answers

The rule for static local variables is plain and simple:

Dynamic initialization of a block-scope variable with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization.

And accessing an object's members before its construction is disallowed by [basic.life]/(7.1).

like image 50
Columbo Avatar answered Nov 15 '22 08:11

Columbo