この質問は、最新のC ++ 20ドラフトへのP0593の追加に言及しています。
これが私の例です:
#include <cstdlib>
#include <cstdio>
void foo(void *p)
{
if ( std::getchar() == 'i' )
{
*(int *)p = 2;
std::printf("%d\n", *(int *)p);
}
else
{
*(float *)p = 2;
std::printf("%f\n", *(float *)p);
}
}
int main()
{
void *a = std::malloc( sizeof(int) + sizeof(float) );
if ( !a ) return EXIT_FAILURE;
foo(a);
// foo(a); [2]
}
このコードは、最新のドラフトのすべての入力に対して明確に定義されていますか?
P0593で表現されている根拠により[2]
、2つのユーザー入力項目が異なる場合、コメントを解除すると厳密なエイリアス違反により未定義の動作が発生することがかなり明確になります。暗黙的なオブジェクトの作成は、の時点で一度だけ行われることになっていmalloc
ます。の割り当てステートメントではトリガーされませんfoo
。
プログラムの実際の実行では、プログラムを明確に定義する暗黙のオブジェクトの未指定のセットのメンバーが存在します。しかし、[intro.object] / 10で言及されている暗黙のオブジェクト作成を選択する必要があるかどうかは、私には明らかではありませんmalloc
。または、決定が「タイムトラベル」できるかどうか。
バイナリblobをバッファーに読み込んで、それへのアクセス方法を実行時に決定するプログラム(たとえば、逆シリアル化、およびヘッダーがfloatまたはintが起動するかどうかを通知するプログラム)でも同じ問題が発生する可能性があります。