60

What is the return type of sizeof operator? cppreference.com & msdn says sizeof returns size_t. Does it really return a size_t? I'm using VS2010 Professional, and targeting for x64.

int main()
{
    int size   = sizeof(int);     // No warning
    int length = strlen("Expo");  //warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
    return 0;
}

I have this question because first line is not issuing any warning, whereas the second does. Even if I change it to char size, I don't get any warnings.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Coder777
  • 985
  • 2
  • 9
  • 15
  • 4
    How about `decltype(sizeof(int))`... – K-ballo Nov 08 '13 at 23:15
  • 15
    It might not be warning because sizeof's result is statically known to the compiler; it is a constant so there's no worry of truncation like in the case of strlen. – Adam D. Ruppe Nov 08 '13 at 23:16
  • 3
    Note that a cleverer compiler (`gcc` for instance) also determines `length` at compile time and thus doesn't warn for that conversion either. – Marc Glisse Nov 08 '13 at 23:29
  • @AdamD.Rupee char name[ CHAR_MAX + 5]; char size = sizeof(name); -> size is set as -124, compiler should find this, right? – Coder777 Nov 08 '13 at 23:30
  • @MarcGlisse, I'm aware of integer promotion. According to Adam's reply ("it is a constant so there's no worry of truncation like in the case of strlen") , I wrote code which leads to truncation and compiler doesn't seem to be warning about that. – Coder777 Nov 08 '13 at 23:39
  • @NoviceCoder777 Ah yes, sorry for reading too quickly. It should notice and warn (`gcc` doesn't, that's a bug). Note that in C++11 you can write `char size { sizeof(name) };` to help convince the compiler that narrowing is bad. – Marc Glisse Nov 08 '13 at 23:44
  • A cleverer-er compiler that conforms to the C++ standard can not treat `strlen` as `constexpr`, so it is not allowed to evaluate it at compile time. `gcc` is not adhering to the C++ standard if it is treating it as `constexpr`. https://reviews.llvm.org/D23692 – Mark Lakata May 22 '20 at 19:06

3 Answers3

35

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 (18.2). — end note ]

You can also do a quick check:

#include <iostream>
#include <typeinfo>
#include <cstdlib>

int main()
{
    std::cout<<(typeid(sizeof(int))==typeid(std::size_t))<<std::endl;
    return 0;
}

which correctly outputs 1 on my machine.

As @Adam D. Ruppe said in the comment, probably the compiler does not complain because, since it already knows the result, it knows that such "conversion" is not dangerous

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 1
    +1 for your last paragraph, because Adam's remark is really the crux of the matter IMHO. Without static knowledge of the `size_t` value, the compiler should emit a warning. – syam Nov 08 '13 at 23:19
  • char name[ CHAR_MAX + 5]; char size = sizeof(name); -> size is set as -124. I dont think this is happening _"probably the compiler does not complain because, since it already knows the result, it knows that such "conversion" is not dangerous"_ – Coder777 Nov 08 '13 at 23:50
  • It is hard to imagine a call to `sizeof` that is not known at compile time. @syam – Yakk - Adam Nevraumont Nov 08 '13 at 23:54
  • @Yakk That was in opposition to `strlen` which is supposed to happen at runtime (even though it can be optimized at compile time). – syam Nov 08 '13 at 23:59
9

size_t is an alias of some implementation-defined unsigned integral type. In C++ opposite to C where sizeof operator may be applied to VLA arrays the operand of sizeof operator is not evaluated (at run time). It is a constant. If the value of sizeof operator can be fit into int type the compiler does not issue a warning. In the second example std::strlen is evaluated at run time so its result can do not fit into int so the compiler issues a warning. You could substitute std:;strlen with your own constexpr function (some recursive function). In this case if the result can fit into int I think that the compiler will not issue a warning.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
3

The sizeof operator is used to get the size of types or variable in bytes. Returns an unsigned integer type of at least 16 bit. It's used to get portability.

This warning is because of the unsigned integer where is defined the size_t.

dpossamai
  • 29
  • 1
  • 6