それは行動が明確に定義されていることは事実ですが- ありませんコンパイラは意味で「constのための最適化は、」あなたが意味することができていることというのは本当。
つまり、コンパイラーは、パラメーターがであるという理由だけで、が指すメモリーが別のポインターを通じて変更されないことを前提として許可const T* ptr
されてptr
いません。ポインタは等しくなくてもかまいません。const
そのポインタを通じて変更を行うことはないあなたによって義務(=機能) -義務ではなく、保証されています。
実際にその保証を得るには、ポインタをrestrict
キーワードでマークする必要があります。したがって、次の2つの関数をコンパイルすると、
int foo(const int* x, int* y) {
int result = *x;
(*y)++;
return result + *x;
}
int bar(const int* x, int* restrict y) {
int result = *x;
(*y)++;
return result + *x;
}
foo()
この関数は二回から読まなければならないx
一方で、bar()
一度だけそれを読む必要があります:
foo:
mov eax, DWORD PTR [rdi]
add DWORD PTR [rsi], 1
add eax, DWORD PTR [rdi] # second read
ret
bar:
mov eax, DWORD PTR [rdi]
add DWORD PTR [rsi], 1
add eax, eax # no second read
ret
このライブをご覧くださいGodBolt。
restrict
Cの唯一のキーワードです(C99以降)。残念ながら、これはこれまでC ++に導入されていません(C ++に導入するのがより複雑であるという悪い理由から)。ただし、多くのコンパイラは、それをのようにサポートしてい__restrict
ます。
結論:コンパイラは、コンパイル時に「難解な」ユースケースをサポートする必要f()
があり、問題は発生しません。
の使用例については、この投稿を参照してくださいrestrict
。
const
「そのポインタを介して変更を行わないこと(つまり機能)による義務」ではありません。C標準では、関数がconst
キャストを介して削除し、その結果を介してオブジェクトを変更することを許可しています。本質的にconst
は、プログラマーがオブジェクトを誤って変更しないようにするための助言であり便利です。