web-dev-qa-db-ja.com

「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;は未定義の動作ですか?
32
msc

警告には、それがUBであるとは記載されていません。使用のコンテキスト、つまりsizeofが副作用(newの場合はメモリを割り当てている)を引き起こさないと単に述べています。

[expr.sizeof] sizeof演算子は、オペランドのタイプの潜在的に重複しないオブジェクトが占有するバイト数を生成します。オペランドは、未評価のオペランド([expr.prop])である式、または括弧で囲まれたtype-idです。

この規格はまた、それが何を意味するのかを説明しています。

[expr.context](...)未評価のオペランドは評価されません。

sizeof(int*)を記述する奇妙な方法ですが、それでも結構です。

61

new演算子は、割り当てられたメモリへのポインタを返します。 new intはポインターを返すため、sizeof new int;はポインターのサイズを返します。これは有効なコードであり、ここではndefined behaviourはありません。

警告は正当であり、オペランドに対する副作用の影響についてのみ警告します。これは、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
19
haccks