2011-01-13 15 views
6

Uczę się kod źródłowy GNU Scientific Library i Ciągle widzę następujące rodzaje deklaracji:C99 const przejść przez wartość

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

W C99, czy istnieje (optimizational) korzyścią deklarowanie argumentu przekazywanego przez wartość (np. N lub incy w powyższym przykładzie) const? Z nich jest wykonana kopia, ponieważ są one przekazywane przez wartość, prawda?

Thx! Kornel

Odpowiedz

11

Prawdopodobnie nie ma korzyści dla osoby dzwoniącej, ale dla osoby odwiedzającej. Deklarowanie parametru funkcji const ma taki sam korzystny wpływ, jak deklarowanie innych zmiennych lokalnych const poprzez narzucanie błędu sobie (jako programatorowi tej funkcji) przy każdej próbie modyfikacji.

W niezbyt inteligentnych implementacjach taka deklaracja mogłaby prawdopodobnie mieć również wpływ na decyzję, jeśli funkcja jest włączona. Ale myślę, że obecnie kompilatorzy podejmą taką decyzję na podstawie tego, co wyprowadzają z definicji funkcji bezpośrednio.

Z pewnością może być postrzegane jako ograniczenie języka, że ​​ta specyfikacja implementacji jest wyrażona w jego interfejsie.

3

Tak. Opcja "const" jest zwykle używana do stwierdzenia, że ​​cokolwiek przekazane do tej funkcji nie zostanie zmienione. Skomplikowane, nie ma różnicy. Jest nadal przekazywana przez wartość.

3

Jak stwierdzili inni, funkcje są zadeklarowane w ten sposób, że w ramach funkcji ta zmienna nie będzie podlegała zmianom, a Twój kompilator powinien Cię ostrzec.

Jeśli chcesz chcieć to zrobić, zastanów się nad tym, co możesz przekazać wskaźnikowi - a mianowicie, możesz usunąć zaznaczony wskaźnik i edytować wartości danych, do których on wskazuje. Używanie const jest dobrym sposobem na uniknięcie przypadkowego edytowania wartości czegoś, co według rozmówcy pozostaje niezmienione.

Poprzez przykład rozważmy to:

#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; 
} 

To wypluwa 7+11=17. Teraz jest to trywialne, nie poważna sprawa, ale wszelkiego rodzaju rzeczy może się wydarzyć, gdybyśmy się opierając się na coś ważnego ...

Jeśli trzymać const przeciwko zmiennej y, należy uzyskać:

constexample.c: In function ‘add’: constexample.c:7:5: error: increment of read-only location ‘*y’

Edit, do dalszego wyjaśnienia:

Jeden dobry powód, aby zadeklarować const typ dla zmiennej non-wskaźnik jest zmienną, która reprezentuje wielkość czegoś lub dowolną zmienną, która posiada maksymalną wartość tablicy. Rozważmy:

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

Teraz mówisz do siebie, ale nigdy nie edytować source_len. Cóż, powiedzmy w twoim algorytmie, który robisz z jakiegokolwiek powodu. Jeśli twoja zmiana zwiększa wartość source_len, ryzykujesz dostęp do pamięci poza tym, co przydzieliłeś. Ustawienie const wygeneruje błąd kompilatora, jeśli spróbujesz zmodyfikować tę wartość.

Powinienem wskazać, podwójnie podkreślając, że const jest tylko sposobem powiedzenia kompilatorowi "Obiecuję, że nie będę tego edytować". Nie gwarantuje to, że pamięć jest tylko do odczytu, ale jest to sposób na zaznaczenie swojej intencji, tak aby pułapki błędów. Jeśli nie musisz go modyfikować, zadeklaruj go jako const.

A ponieważ pytasz, zestaw generowany przez obie wersje jest identyczny.

+2

W twoim przykładzie nie zadeklaruj parametrów "const", ale danych, do których parametr wskazuje. Dla wskaźników, o które prosił OP, byłoby coś w rodzaju 'int * const result'. Ponadto, jeśli dobrze pamiętam, '* y ++' najpierw zwiększa wskaźnik, a następnie dereferencje go. Nie ma nic, co mogłoby przeszkadzać dzwoniącemu, nie? –

+0

Masz rację, mój błąd powinien być "(* y) ++;" Jednak nigdy nie powiedziałem, że deklarowanie moich parametrów const wpływa na wskaźnik - w rzeczywistości * punktem * mojego przykładu jest to, że zmienia on pamięć źródłowa. Dodałem jednak dodatkową sekcję na temat użyteczności standardowych zmiennych stałych. –

Powiązane problemy