Является "sizeof new int"; неопределенное поведение?

код:

#include<iostream>

using namespace std;

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

    cout<<i;
}

В компиляторе GCC работает нормально, без каких-либо предупреждений или ошибок и вывода на печать 8.

Но в компиляторе clang я получил следующее предупреждение:

warning: expression with side effects has no effect in an unevaluated context [-Wunevaluated-expression]
    size_t i = sizeof new int;
  • Какая из них истинна?
  • Является sizeof new int; неопределенное поведение?

Ответ 1

Предупреждение не указывает, что это UB; он просто говорит, что контекст использования, а именно sizeof, не будет вызывать побочные эффекты (которые в случае new выделяют память).

[expr.sizeof] Оператор sizeof дает количество байтов, занятых неперекрывающимся объектом типа его операнда. Операндом является либо выражение, которое является неоцененным операндом ([expr.prop]), либо идентификатором типа в скобках.

Стандарт также помогает объяснить, что это означает:

[expr.context] (...) Неопределенный операнд не оценивается.

Это прекрасный, хотя и странный способ написать sizeof(int*).

Ответ 2

new оператор возвращает указатель на выделенную память. new int вернет указатель, поэтому sizeof new int; вернет размер указателя. Это действительный код, и здесь нет неопределенного поведения.

Предупреждение является допустимым и только предупреждает о влиянии побочного эффекта на операнд и что, поскольку операнды sizeof не оцениваются.

Например:

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