Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 lambdas can access my private members. Why?

Tags:

Consider this piece of code:

class shy { private:     int dont_touch;    // Private member  public:     static const shy object; };   const shy shy::object = []{     shy obj;     obj.dont_touch = 42;   // Accessing a private member; compiles; WHY?     return obj; }();   int main() { } 

Live code (Clang)

Live code (GCC)

It seems really unintuitive to me. What does the C++11/14 standard say about this? Is this a GCC/Clang bug?

like image 622
Mark Garcia Avatar asked Jun 16 '14 06:06

Mark Garcia


People also ask

Can private members be accessed by member functions?

Private: The class members declared as private can be accessed only by the member functions inside the class. They are not allowed to be accessed directly by any object or function outside the class.

Which function is used to access private members?

A friend function in C++ is defined as a function that can access private, protected and public members of a class. The friend function is declared using the friend keyword inside the body of the class.

When should I use lambdas C++?

50: Use a lambda when a function won't do (to capture local variables, or to write a local function) The difference in the usage of functions and lambda functions boils down to two points. You can not overload lambdas. A lambda function can capture local variables.

How are lambdas stored?

The Lambda service stores your function code in an internal S3 bucket that's private to your account. Each AWS account is allocated 75 GB of storage in each Region. Code storage includes the total storage used by both Lambda functions and layers.


1 Answers

As already answered in the comments @Tony D and @dyp:

§ 9.4.2/2 Static data members [class.static.data]:

The initializer expression in the definition of a static data member is in the scope of its class.

The above means that static data members and their initializers can access other private and protected members of their class.

Also consdering the standard § 5.1.2/2&3 Lambda expressions [expr.prim.lambda]:

2 The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called the closure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5). [ Note: A closure object behaves like a function object (20.9).-end note]

3 The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type - called the closure type - whose properties are described below. This class type is not an aggregate (8.5.1). The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.

Combining the above we end up to the conclusion that the prvalue temporary closure object of your lambda is declared and defined in the initializer of the static const data member shy::object and consequently the scope of the lambda's closure object is the scope of class shy. As such it can access private members of class shy.

like image 195
101010 Avatar answered Nov 07 '22 20:11

101010