Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sizeof lambda

65 views
Skip to first unread message

AP

unread,
Sep 18, 2014, 4:40:49 PM9/18/14
to
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf

says that

"In addition, this rewrite adds the restriction that lambda expressions
cannot be used in the operand of a sizeof operator, alignof operator, or
decltype specifier. That restriction—
suggested by Doug Gregor and John Spicer—avoids severe implementation
difficulties with template argument deduction (e.g., this avoids the need to
encode arbitrary statement
sequences in mangled names)."

And yet this snippet compiles and runs just fine :

#include <iostream>
int main()
{
auto lambda=[](){ return nullptr;};
std::cout << sizeof lambda << std::endl;
return 0;
}

Is it wrong to read the open-std papers ?


---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com


--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Victor Bazarov

unread,
Sep 18, 2014, 7:20:55 PM9/18/14
to
On 9/18/2014 4:39 PM, AP wrote:
> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf
>
> says that
>
> "In addition, this rewrite adds the restriction that lambda expressions
> cannot be used in the operand of a sizeof operator, alignof operator, or
> decltype specifier. That restriction—
> suggested by Doug Gregor and John Spicer—avoids severe implementation
> difficulties with template argument deduction (e.g., this avoids the
> need to encode arbitrary statement
> sequences in mangled names)."
>
> And yet this snippet compiles and runs just fine :
>
> #include <iostream>
> int main()
> {
> auto lambda=[](){ return nullptr;};
> std::cout << sizeof lambda << std::endl;
> return 0;
> }
>
> Is it wrong to read the open-std papers ?

In your code 'lambda' is an object, the lambda-expression is the
expression between the '=' and the semicolon that ends the declaration
statement. What you're not supposed to do is to write

.... sizeof []() { return nullptr; }
^^^^^^^^^^^^^^^^^^^^^^^^^
That is a lambda-expression. It cannot appear as an argument of
'sizeof'. It's pretty much useless there, if you ask me...

V
--
I do not respond to top-posted replies, please don't ask

AP

unread,
Sep 18, 2014, 11:41:54 PM9/18/14
to
WARNING - pure hypotheticals, may be waste of time unless you're interested
in what's under the hood of various nifty C++11 implementations

You are right. But then, what's the meaning of sizeof lambda ? 1-byte ?
Here is a piece of nonsense code :

#include <iostream>
using namespace std;
int main()
{
auto lambda=[](){ return nullptr;};
auto next_lambda=[](){ return 1; };
cout << sizeof lambda << endl;
// auto lambda_size = sizeof [](){return nullptr;}; // Does not compile with
it's own error, as promised
auto plambda = &next_lambda;
void *pointer= plambda;
int *clambda ;
clambda = (int*)pointer;
cout << *clambda << endl;
return 0;
}
It compiles fine, when ran it either outputs 1\n0\n (Solaris Studio 12.4
Sparc, 32-bit target) or dumps core with Bus error (memory alignment) (gcc
and 64-bit SUNWspro 12.4) - IMGO more appropriate response - when
dereferencing clambda.
So basically, lambda is 1-byte memory location containing a zero (always a
zero, in practice). For some reason, I was expecting something resembling a
vtable. Does this mean that lambda semantics and implementation are
something purely compile-time and thin ?

"Victor Bazarov" wrote in message news:lvfpbr$a4j$1...@dont-email.me...

Paavo Helde

unread,
Sep 19, 2014, 1:34:14 AM9/19/14
to
"AP" <unixpr...@verizon.net> wrote in
news:lvg8la$2g2l$1...@adenine.netfront.net:

> You are right. But then, what's the meaning of sizeof lambda ? 1-byte

The meaning of sizeof is defined as the spacing of elements if you put them
in a (C-style) array. One must be able to tell different objects apart
(there is another rule that says that all objects of the same type must
have different addresses), so it cannot be never 0, even if the object is
something like an empty struct which does not contain any content.

> So basically, lambda is 1-byte memory location containing a zero
> (always a zero, in practice). For some reason, I was expecting
> something resembling a vtable. Does this mean that lambda semantics
> and implementation are something purely compile-time and thin ?

Yes, AFAIK lambdas are a compile-time thing. The function encapsulated in
lambda is fully known at compile time, so by the zero overhead principle of
C++ something like a vtable or a function pointer should not be needed.
Redirection through a function pointer would mean potentially large runtime
penalties when used in a tight loop.

hth
Paavo

Paavo Helde

unread,
Sep 19, 2014, 1:35:36 AM9/19/14
to
"AP" <unixpr...@verizon.net> wrote in
news:lvg8la$2g2l$1...@adenine.netfront.net:

> WARNING - pure hypotheticals, may be waste of time unless you're

PS. Please learn to quote. You will not receive a reply from Victor for
example, because you top-posted.

Cheers
Paavo

David Brown

unread,
Sep 19, 2014, 4:06:45 AM9/19/14
to
Basically, a lambda expression is just like a normal function with
restricted scope and some "magic" to handle captures (i.e., invisible
parameters are made and initialised to get data into and out of the lambda).

It makes no more sense to use "sizeof" on a lambda expression than it
would to apply it to the body of a function - but since the syntax first
allowed "sizeof [](){return nullptr;}", such meaningless expressions had
to be explicitly disallowed.

You can use "sizeof" on "lambda" or "next_lambda" above - but it won't
give you much useful information. It is up to the implementation to
decide what it encodes with the "lambda" object - it could be a pointer
to the compiled function, or an index in a table, or an internal number
used to track code generation. It is quite possible that it contains
nothing at all - but its "sizeof" is returned as 1 because that is the
minimum allowed (to ensure that every object can have a unique address).

With your construction above, you are trying to access this somewhat
artificial object as an integer - this is definitely undefined
behaviour, and will never give anything useful.
0 new messages