コード:
#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;
は未定義の動作ですか?警告には、それがUBであるとは記載されていません。使用のコンテキスト、つまりsizeof
が副作用(new
の場合はメモリを割り当てている)を引き起こさないと単に述べています。
[expr.sizeof] sizeof演算子は、オペランドのタイプの潜在的に重複しないオブジェクトが占有するバイト数を生成します。オペランドは、未評価のオペランド([expr.prop])である式、または括弧で囲まれたtype-idです。
この規格はまた、それが何を意味するのかを説明しています。
[expr.context](...)未評価のオペランドは評価されません。
sizeof(int*)
を記述する奇妙な方法ですが、それでも結構です。
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