Zagłosowano na ponowne otwarcie. „Duplikat” zadaje zupełnie inne pytanie, specyficzne dla wykorzystania pamięci. To pytanie dotyczy bardziej ogólnego pytania o różnicę.
Jeśli iobiekt nie jest używany poza jednostką tłumaczeniową, w której jest zdefiniowany, należy zadeklarować go ze staticspecyfikatorem.
Umożliwia to kompilatorowi (potencjalnie) wykonanie dalszych optymalizacji i informuje czytelnika, że obiekt nie jest używany poza jego jednostką tłumaczeniową.
+1 Byłoby wspaniale, gdybyś mógł również dodać, co to znaczy, jeśli te deklaracje znajdują się w funkcji.
Praetorian
Czy jesteś pewien, że const int i = 5;ma zewnętrzny link? W C ++ to nie ...
Kerrek SB
4
@KerrekSB w zakresie plików, tak. (C99, 6.2.2p5) „Jeśli deklaracja identyfikatora obiektu ma zasięg plikowy i nie ma specyfikatora klasy pamięci, jej powiązanie jest zewnętrzne”.
ouah
13
@KerrekSB: C i C ++ nie są tym samym językiem. W szczególności C constnie ma nic wspólnego z C ++ const.
R .. GitHub PRZESTAŃ POMÓC W LODZIE
Czy kompilatory naprawdę optymalizują w oparciu o statyczne? Wydaje się, że nie jest bezpieczne założenie, że obiekt statyczny nie jest używany poza swoją jednostką tłumaczeniową, ponieważ nadal może być przekazywany przez funkcję niestatyczną lub wskazywany przez niestatyczny wskaźnik globalny.
nw.
99
staticokreśla widoczność poza funkcją lub długość życia zmiennych wewnątrz. Więc nie ma to nic wspólnego z samym sobą const.
const oznacza, że nie zmieniasz wartości po jej zainicjowaniu.
static wewnątrz funkcji oznacza, że zmienna będzie istnieć przed i po zakończeniu funkcji.
staticpoza funkcją oznacza, że zakres zaznaczonego symbolu staticjest ograniczony do tego pliku .c i nie można go zobaczyć poza nim.
Z technicznego punktu widzenia (jeśli chcesz to sprawdzić) staticjest specyfikatorem magazynu i constkwalifikatorem typu.
const int i = 5;
wartość i, którą można modyfikować za pomocą wskaźnika, jeśli i jest zdefiniowane i zadeklarowane lokalnie, jeśli jest stałą statyczną int a = 5; lub const int i = 5; globalnie nie można modyfikować, ponieważ jest przechowywany w pamięci RO w segmencie danych.
#include<stdio.h>//const int a=10; /* can not modify */intmain(void){
// your code goes here//static const int const a=10; /* can not modify */constint a=10;
int *const ptr=&a;
*ptr=18;
printf("The val a is %d",a);
return0;
}
Zależy to od tego, czy te definicje znajdują się wewnątrz funkcji, czy nie. Odpowiedź na przypadek poza funkcją daje ouah powyżej. Wewnątrz funkcji efekt jest inny, co ilustruje poniższy przykład:
#include<stdlib.h>voidmy_function(){
constint foo = rand(); // Perfectly OK!staticconstint bar = rand(); // Compile time error.
}
Jeśli chcesz, aby zmienna lokalna była „naprawdę stała”, musisz ją zdefiniować nie tylko jako „stała”, ale „stała statyczna”.
Doskonale się kompiluje ... Ale wiem, że w tym przypadku statyczna zmienna const jest głupotą.
DrumM
1
@DrumM to nie jest głupie. W przypadku, foogdy zmienna jest ponownie inicjalizowana przy każdym my_function()wywołaniu, co skutkuje przypisaniem innej wartości losowej. W przypadku barzmiennej inicjowanej tylko raz, my_function()wywoływana jest po raz pierwszy, co skutkuje przypisaniem tej samej wartości przez cały czas życia programu. Stąd statyczny czas przechowywania.
jb
1
Właściwie, po dalszej refleksji, zależy to od tego, czy używamy C czy C ++. Pytanie jest oznaczone tagiem C, w którym to przypadku otrzymujemy błąd kompilacji dla przypisania, barponieważ rand()nie jest to stała czasu kompilacji.
jb
1
@nibot, czy możesz wyjaśnić, co rozumiesz przez „efekt jest inny” i „naprawdę stały” w odniesieniu do specyfikacji pamięci masowej i kwalifikacji typu?
Odpowiedzi:
Różnica polega na połączeniu.
// At file scope static const int a=5; // internal linkage const int i=5; // external linkage
Jeśli
i
obiekt nie jest używany poza jednostką tłumaczeniową, w której jest zdefiniowany, należy zadeklarować go zestatic
specyfikatorem.Umożliwia to kompilatorowi (potencjalnie) wykonanie dalszych optymalizacji i informuje czytelnika, że obiekt nie jest używany poza jego jednostką tłumaczeniową.
źródło
const int i = 5;
ma zewnętrzny link? W C ++ to nie ...const
nie ma nic wspólnego z C ++const
.static
określa widoczność poza funkcją lub długość życia zmiennych wewnątrz. Więc nie ma to nic wspólnego z samym sobąconst
.const
oznacza, że nie zmieniasz wartości po jej zainicjowaniu.static
wewnątrz funkcji oznacza, że zmienna będzie istnieć przed i po zakończeniu funkcji.static
poza funkcją oznacza, że zakres zaznaczonego symbolustatic
jest ograniczony do tego pliku .c i nie można go zobaczyć poza nim.Z technicznego punktu widzenia (jeśli chcesz to sprawdzić)
static
jest specyfikatorem magazynu iconst
kwalifikatorem typu.źródło
const int i = 5;
wartość i, którą można modyfikować za pomocą wskaźnika, jeśli i jest zdefiniowane i zadeklarowane lokalnie, jeśli jest stałą statyczną int a = 5; lub const int i = 5; globalnie nie można modyfikować, ponieważ jest przechowywany w pamięci RO w segmencie danych.
#include <stdio.h> //const int a=10; /* can not modify */ int main(void) { // your code goes here //static const int const a=10; /* can not modify */ const int a=10; int *const ptr=&a; *ptr=18; printf("The val a is %d",a); return 0; }
źródło
Zależy to od tego, czy te definicje znajdują się wewnątrz funkcji, czy nie. Odpowiedź na przypadek poza funkcją daje ouah powyżej. Wewnątrz funkcji efekt jest inny, co ilustruje poniższy przykład:
#include <stdlib.h> void my_function() { const int foo = rand(); // Perfectly OK! static const int bar = rand(); // Compile time error. }
Jeśli chcesz, aby zmienna lokalna była „naprawdę stała”, musisz ją zdefiniować nie tylko jako „stała”, ale „stała statyczna”.
źródło
foo
gdy zmienna jest ponownie inicjalizowana przy każdymmy_function()
wywołaniu, co skutkuje przypisaniem innej wartości losowej. W przypadkubar
zmiennej inicjowanej tylko raz,my_function()
wywoływana jest po raz pierwszy, co skutkuje przypisaniem tej samej wartości przez cały czas życia programu. Stąd statyczny czas przechowywania.bar
ponieważrand()
nie jest to stała czasu kompilacji.