32

code:

#include<iostream>

using namespace std;

int main() 
{
    size_t i = sizeof new int;

    cout<<i;
}

In GCC compiler, working fine without any warning or error and printed output 8.

But, in clang compiler, I got the following warning:

warning: expression with side effects has no effect in an unevaluated context [-Wunevaluated-expression]
    size_t i = sizeof new int;
  • Which one is true?
  • Is sizeof new int; undefined behavior?
doppelgreener
  • 4,809
  • 10
  • 46
  • 63
msc
  • 33,420
  • 29
  • 119
  • 214
  • 18
    I see nothing wrong. This warning is more of a reminder, everything is well defined here. – YSC Oct 03 '18 at 10:03
  • 3
    This question is related to the C counterpart [Why does sizeof(x++) not increment x?](https://stackoverflow.com/questions/8225776/why-does-sizeofx-not-increment-x?rq=1), but it is a bit clearer in C++. – Bartek Banachewicz Oct 03 '18 at 10:16
  • @BartekBanachewicz - a closer equivalent in C would be `sizeof malloc(some_value)` which would not call `malloc()` and, if performed after `#include `, would give a result equal to `sizeof(void *)`. – Peter Oct 03 '18 at 10:23
  • 23
    One could argue it's compiler caring about the WTF-factor. – luk32 Oct 03 '18 at 10:50
  • 1
    Also see [Does not evaluating the expression to which sizeof is applied make it legal to dereference a null or invalid pointer inside sizeof in C++?](https://stackoverflow.com/q/28714018/1708801) – Shafik Yaghmour Oct 03 '18 at 13:23

2 Answers2

61

The warning doesn't state that it's UB; it merely says that the context of use, namely sizeof, won't trigger the side effects (which in case of new is allocating memory).

[expr.sizeof] The sizeof operator yields the number of bytes occupied by a non-potentially-overlapping object of the type of its operand. The operand is either an expression, which is an unevaluated operand ([expr.prop]), or a parenthesized type-id.

The standard also helpfully explains what that means:

[expr.context] (...) An unevaluated operand is not evaluated.

It's a fine, although a weird way to write sizeof(int*).

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
  • It’s weird but it’s not *that* weird. The desire to use expressions rather than the type could be a case of DRY. In fact, in C it’s an established pattern for `malloc` and not doing so often leads to erroneous code. Literally writing `sizeof new T` by contrast is probably not sensible but it might come up in the context of a macro expansion. – Konrad Rudolph Oct 03 '18 at 15:56
  • 2
    *It's a fine, although a weird way to write `sizeof(int*)`.* I'd add it's a possibly confusing way to write `sizeof( int * )`, as it's likely to be viewed as `sizeof( int )`. – Andrew Henle Oct 04 '18 at 11:07
19

new operator returns pointer to the allocated memory. new int will return a pointer, therefore sizeof new int; will return size of a pointer. This is a valid code and there is no undefined behaviour here.

Warning is legit and only warns about the effect of side-effect on the operand and that's because operands of sizeof is not evaluated.

For example:

int i = 1;
std::cout << i << '\n';     // Prints 1
size_t size = sizeof(i++);  // i++ will not be evaluated
std::cout << i << '\n';     // Prints 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 4
    Curiously, it's easy to make `i++` be evaluated: cpp.sh/9774o – Dan M. Oct 03 '18 at 10:25
  • 6
    @DanM.; `int[i++]` will be evaluated at runtime, exception for variable length arrays. Note that c++ doesn't allow VLA but GCC and clang provide it as an extension. – haccks Oct 03 '18 at 10:38
  • yeah I know. Just a peculiar gotcha. Same with `int(*)[i++]` being either evaluated or not depending on the implementation. – Dan M. Oct 03 '18 at 10:45
  • @DanM. is that due to ambiguity in the spec, or compiler bugs? I'm inclined to suspect the latter. – Max Barraclough Oct 03 '18 at 10:52
  • 7
    @MaxBarraclough It's unspecified behavior. "Where a size expression is part of the operand of a `sizeof` operator and changing the value of the size expression would not affect the result of the operator, it is unspecified whether or not the size expression is evaluated." https://port70.net/~nsz/c/c11/n1570.html#6.7.6.2p5 – Dan M. Oct 03 '18 at 11:06
  • @DanM.; This rule is C specific. I do not remember if there is similar quote is there in C++ standard. – haccks Oct 04 '18 at 06:03
  • 1
    @haccks this rule concerns VLAs. There are no VLAs in C++ standard. – Dan M. Oct 04 '18 at 10:15
  • @DanM.; Yes, I already said in earlier comment. VLA is provided as an extension by GCC and Clang for C++. The question about C++, not C. So better not to involve VLA to this discussion. – haccks Oct 04 '18 at 10:24