When I write the following code:
#include <iostream>
struct gg
{
gg() {}
int a, b, c;
};
int main()
{
std::cout << sizeof(gg()) << std::endl;
}
the result is 1
.
But when I use a non-default constructor, like so:
#include <iostream>
struct gg
{
gg(int x) {}
int a, b, c;
};
int main()
{
std::cout << sizeof(gg(10)) << std::endl;
}
the output is 12.
Since both examples have the same data members in gg
, I expect them both to result in the same output.
Why did sizeof(gg())
result in 1
?
There are two versions of sizeof
. One expects a unary-expression , and the other expects a parenthesized type-id . The first version leaves its operand unevaluated. The following is perfectly legal and outputs 12
:
std::cout << sizeof gg();
On the other hand, sizeof(gg())
is illegal. It's trying to apply sizeof
to a function type. 1 The second code snippet is legal and has expected behavior.
§5.3.3:
1
... Thesizeof
operator shall not be applied to an expression that has function or incomplete type, ...
3
Thesizeof
operator can be applied to a pointer to a function, but shall not be applied directly to a function.
4
The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are not applied to the operand ofsizeof
.
The first code snippet fails in Clang ( live example ), and is documented as an extension in the GCC manual :
6.23 Arithmetic on void- and Function-Pointers
In GNU C, addition and subtraction operations are supported on pointers to void and on pointers to functions. This is done by treating the size of a void or of a function as 1.
A consequence of this is that sizeof is also allowed on void and on function types, and returns 1.
The option -Wpointer-arith requests a warning if these extensions are used.
(emphasis mine)
It appears that this extension exists in C++ mode as well, considering that I receive a warning . In order to reject this code, use -Wpedantic-errors
. For the code snippet which fails, simply use sizeof(gg)
or sizeof(gg{})
. The latter and sizeof gg()
are needless obfuscation and sizeof gg
is illegal since parentheses are required around the typename.
sizeof(int(int, char))
, sizeof(gg(int, char))
, what have you. On the other hand, sizeof int(45)
returns 4
and sizeof gg(45)
(for where gg
has a converting constructor) returns 12, etc.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.