C99 const передача по значению - PullRequest
6 голосов
/ 13 января 2011

Я изучал исходный код научной библиотеки GNU и постоянно вижу объявления следующих типов:

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

В C99 , есть ли (оптимизационное) преимущество объявления аргумента, который передается по значению (например, N или incy в примере выше) const? В любом случае, из них сделана копия, потому что они передаются по значению, не так ли?

Thx! Корнель

Ответы [ 3 ]

11 голосов
/ 13 января 2011

Вероятно, нет пользы для звонящего, но для звонящего.Объявление параметра функции const оказывает такое же благотворное влияние, как и объявление других локальных переменных const, когда вы налагаете на себя ошибку (как программиста функции) всякий раз, когда вы пытаетесь изменить это.

В не-такие умные реализации, такое объявление, вероятно, также может повлиять на решение, если функция встроена.Но я полагаю, что в настоящее время компиляторы принимают такое решение относительно того, что они выводят из определения функции напрямую.

Это, безусловно, можно рассматривать как ограничение языка, которое эта спецификация реализации выражает в своем интерфейсе..

3 голосов
/ 13 января 2011

Как уже заявляли другие, функции объявляются таким образом, чтобы в рамках функции эта переменная не была изменяемой, и при этом ваш компилятор должен предупреждать вас.

Относительно того, почему выВозможно, вы захотите сделать это, подумайте, что позволяет вам передать указатель, а именно вы можете разыменовать переданный вами указатель и отредактировать значения данных, на которые он указывает.Использование 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.Теперь это тривиальный, несерьезный случай, но могут произойти все виды вещей, если мы будем полагаться на что-то важное ...

Если вы добавите const к переменной y, вы должны получить:

constexample.c: В функции 'add': constexample.c: 7: 5: error: приращение местоположения только для чтения '* y'

Изменить, для дальнейшего пояснения:

Одной из веских причин для объявления типа const для переменной без указателя является переменная, представляющая размер чего-либо, или любая переменная, которая содержит максимальное значение массива.Подумайте:

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

Теперь вы говорите себе, но я бы никогда не отредактировал source_len.Ну, скажем, в вашем алгоритме вы делаете по любой причине.Если ваше изменение увеличивает значение source_len, вы рискуете получить доступ к памяти сверх того, что вы выделили. Установка const приведет к ошибке компилятора, если вы попытаетесь изменить это значение.

Я должен отметить в двух подчеркиваниях, что const - это только способ сказать компилятору: «Я обещаю не редактировать это».Это не гарантирует, что память является только для чтения, но это способ пометить ваше намерение так, чтобы вы перехватывали ошибки.Если вам не нужно изменять его, объявите его const.

И поскольку вы спросили, сборка, созданная двумя версиями, идентична.

3 голосов
/ 13 января 2011

Да. Опция "const" обычно используется для указания того, что все, что передано этой функции, не будет изменено По компиляции разницы нет. Он все еще передается по значению.

...