私は、関数を書きたいというの入力データとポインタを使用して、データの別のアレイ出力の配列。
私は結果が、両方の場合は何か思ったんだけどsrc
とdst
、私は、コンパイラはconstのために最適化することができます知っているので、同じアドレスを指摘しました。それは行動を定義されていませんか?(答えはそれらの間で異なる可能性がある場合、私はわからないので、私は、CおよびC ++の両方をタグ付けし、私は両方について知りたいです。)
void f(const char *src, char *dst) {
dst[2] = src[0];
dst[1] = src[1];
dst[0] = src[2];
}
int main() {
char s[] = "123";
f(s,s);
printf("%s\n", s);
return 0;
}
上記の質問に加えて、私は削除した場合、これは明確に定義されているconst
元のコードでは?
それは行動が明確に定義されていることは事実ですが- ありませんコンパイラは意味で「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
(C99以降)C唯一のキーワードです。残念ながら、それは(より複雑にC ++でそれを導入することが悪い理由で)これまでにC ++に導入されていません。多くのコンパイラは、前述したように、しかし、それをちょっと-サポートしています__restrict
。
ボトムライン:コンパイラはコンパイル時に「難解な」ユースケースをサポートしている必要がありf()
、それに問題はありません。
参照この記事のためのユースケースについてをrestrict
。