6

私は GNU Scientific Library のソース コードを調べていて、次のタイプの宣言を見続けています。

double cblas_ddot (const int N, const double * x, const int incx, const double * y, const int incy)

C99 では、値で渡される引数を宣言することの (最適化) 利点はありますか (たとえば、Nまたはincy上記の例で) const? いずれにせよ、それらは値渡しされるため、それらのコピーが作成されますね。

どうも!コーネル

4

3 に答える 3

11

おそらく呼び出し元にはメリットはありませんが、呼び出し先にはメリットがあります。関数パラメーターconstを宣言すると、他のローカル変数を宣言するのと同じ効果がありconst、これを変更しようとするたびに (関数のプログラマーとして) 自分自身にエラーが発生します。

それほどスマートではない実装では、そのような宣言は、関数がインライン化されているかどうかの決定にも影響を与える可能性があります。しかし、今日のコンパイラは、関数の定義から直接何を推測するかについて、そのような決定を下すと思います。

実装のこの仕様がそのインターフェースで表現されることは、確かに言語の制限と見なすことができます。

于 2011-01-13T13:13:43.757 に答える
3

他の人が述べているように、関数はこのように宣言されているため、関数のスコープ内でその変数は変更できず、そうすることでコンパイラが警告する必要があります。

なぜこれを行う必要があるのか​​ については、ポインターを渡すことで何ができるかを考えてください。つまり、渡したポインターを逆参照し、ポインターが指すデータの値を編集できます。const を使用すると、呼び出し元が変更されていないと考えている値を誤って編集してしまうのを防ぐことができます。

例として、次のことを考慮してください。

#include <stdio.h>

void add(int* result, const int* x, int* y)
{
    *result = *x + *y;
    (*y)++; /* <-- the caller won't expect this! */

}

int main(int argc, char** argv)
{
    int a = 7;
    int b = 10;
    int c = 0;

    add(&c, &a, &b);

    printf("%d + %d = %d\n", a, b, c);
    return 0;
}

これは吐き出し7+11=17ます。これはささいな、深刻ではないケースですが、何か重要なものに頼っていれば、あらゆる種類のことが起こる可能性があります...

y 変数に対して const を固執すると、次のようになります。

constexample.c: 関数 'add' 内: constexample.c:7:5: エラー: 読み取り専用の場所 '*y' のインクリメント</p>

さらに明確にするために編集します。

非ポインター変数の型を宣言する正当な理由の 1 つconstは、何かのサイズを表す変数、または配列の最大値を保持する任意の変数のためです。検討:

int editstring(char* result, ..., const char* source, const size_t source_len);

さて、あなたは自分自身に言いますが、私は決して編集しませんsource_len. さて、アルゴリズムで何らかの理由で行うとしましょう。変更によって source_len の値が増加すると、割り当てたメモリを超えてメモリにアクセスするリスクが生じます。constそこに設定すると、その値を変更しようとするとコンパイラ エラーが発生します。

const は、「これを編集しないことを約束します」とコンパイラーに伝える方法にすぎないことを二重下線で指摘しておく必要があります。メモリが読み取り専用であることを保証するものではありませんが、エラーをトラップするように意図をマークする方法です。変更する必要がない場合は、const として宣言します。

ご質問のとおり、2 つのバージョンで生成されたアセンブリは同一です。

于 2011-01-13T13:15:44.930 に答える
3

はい。オプション "const" は通常、この関数に渡されるものは何でも変更されないことを示すために使用されます。コンパイルに関しては、違いはありません。それはまだ値によって渡されます。

于 2011-01-13T12:46:20.360 に答える