Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does `sizeof` *really* evaluate to a `std::size_t`? Can it?

Take the following standard passage:

[C++11: 5.3.3/6]: The result of sizeof and sizeof... is a constant of type std::size_t. [ Note: std::size_t is defined in the standard header <cstddef> (18.2). —end note ]

Now:

[C++11: 18.2/6]: The type size_t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object.

Granted, the passage doesn't require that size_t is a type alias defined with typedef, but since it's explicitly stated to be made available by the standard header <cstddef>, I think we can take as read that failing to include <cstddef> should remove any guarantee that size_t shall be available to a program.

However, according to that first quote, we can regardless obtain an expression of type std::size_t.

We can actually demonstrate both of these facts:

int main() {     typedef decltype(sizeof(0)) my_size_t;      my_size_t x   = 0;  // OK     std::size_t y = 1;  // error: 'size_t' is not a member of 'std' } 

std::size_t is not visible to the program, but sizeof(0) still gives us one? Really?

Is it therefore not correct to say that 5.3.3/6 is flawed, and that it actually has "the same type as whatever std::size_t resolves to", but not std::size_t itself?

Sure, the two are one and the same if std::size_t is a type alias but, again, nowhere is this actually required.

like image 886
Lightness Races in Orbit Avatar asked Dec 27 '13 22:12

Lightness Races in Orbit


People also ask

Does sizeof return Size_t?

size_t is an unsigned integer type, which is defined in the stddef. h header. It can hold any value returned by the sizeof operator, and has a min value of 0 , and a max value of the largest value, that can be returned by the sizeof operator.

What is the size of std :: Size_t?

std::size_t is the unsigned integer type of the result of the sizeof operator as well as the sizeof... operator and the alignof operator (since C++11). The bit width of std::size_t is not less than 16.

Is Size_t the same as std :: Size_t?

So yeah, both are same; the only difference is that C++ defines size_t in std namespace.

How big is a Size_t C++?

size_t type is a base unsigned integer type of C/C++ language. It is the type of the result returned by sizeof operator. The type's size is chosen so that it can store the maximum size of a theoretically possible array of any type. On a 32-bit system size_t will take 32 bits, on a 64-bit one 64 bits.


2 Answers

The standard just mandates that the type of sizeof(expr) is the same type as std::size_t. There is no mandate that using sizeof(expr) makes the name std::size_t available and since std::size_t just names one of the the built-in integral types there isn't really a problem.

like image 170
Dietmar Kühl Avatar answered Sep 22 '22 08:09

Dietmar Kühl


Do not confuse the map for the territory.

Types can be named by typenames. These typenames can be built-in, they can be user-defined types, or they could even be template parameters and refer to multiple different types depending on the instantiation.

But the names are not the types. Clearly standard does not mandate that all types have names -- the classic struct {} is a type without a name.

std::size_t is a typename. It names the type that sizeof(expression) returns.

The compiler could have a canonical name for the type -- __size_t would be one way for it to have a unique built-in canonical typename.

The standard guarantees in that clause that whatever the type of sizeof(expression) is, once you #include <cstddef>, the name std::size_t now refers to that type.

In the standard, they refer to types by names. They do not say "the type that this typename refers to", but simply say "the type $NAME$". The compiler could decide that int is another name for __int_32_fast if it wanted to, and the standard would have no objection either.

This same thing happens with std::nullptr_t and std::initializer_list<Ts> and std::type_info: use of variables of those types does not always require that the header that provides you with a name for those types be included in your program.

The traditional C/C++ built-in types all had canonical names that did not require a header. The downside is that this breaks existing code, as new typenames in the global scope collide with other identifiers.

By having "nameless types", where you can get a name for them via including a header file, we avoid that problem.

like image 20
Yakk - Adam Nevraumont Avatar answered Sep 21 '22 08:09

Yakk - Adam Nevraumont