2014-05-22 8 views
5

Mam dwa pliki kodu źródłowego C; jeden plik zawiera deklarację tak:Czy słowo kluczowe extern jest niezbędne, gdy odsyła zmienna lotna zadeklarowana w innym źródłowym pliku C?

volatile unsigned char flag=0; 

Drugi plik C zawiera odniesienie takie jak:

extern unsigned char flag; 

jest to prawidłowe i bezpieczne, czy też słowo kluczowe volatile powtarza się, gdy odwołuje się do zmiennej ? tj.

extern volatile unsigned char flag; 
+2

Czy używasz kompilatora C lub C++? Wygląda na to, że nie powinieneś używać tutaj znacznika 'C++ '. –

+0

Teraz, jeśli chcesz wiedzieć, czy odpowiedź będzie różna między C i C++, to w porządku. Użyj obu tagów ** i wyjaśnij w swoim pytaniu, w jaki sposób zależy Ci na obu językach **. –

+0

Kompilator, posiadający tylko deklarację * extern * i kod generujący dostęp do zmiennej oczywiście nie może wiedzieć, że ma być traktowany jako niestabilny. Linker nie "naprawia" tego kodu, to nie jest jego zadanie. Nie możesz tego pominąć. –

Odpowiedz

8

Nie, to nie jest poprawne.

Wszystkie deklaracje tej samej zmiennej konieczności korzystania z dokładnie tego samego typu, a volatile jest częścią typu (extern nie)

Dobrą praktyką do sprawdzania extern deklaracji jest umieścić je w pliku nagłówka który jest również zawarty w jednostce kompilacji, w której istnieje definicja. Następnie kompilator sprawdzi je pod kątem poprawności.

Notice what happens if you do that on this example.

prog.c:2:22: error: conflicting type qualifiers for ‘flag’ 
extern unsigned char flag; 
        ^
prog.c:1:24: note: previous definition of ‘flag’ was here 
volatile unsigned char flag=0; 
+0

W szczególności unikam umieszczania czegokolwiek w kompilatorze przy użyciu optymalizacji, które nie powinny być stosowane do zmiennych ulotnych w mojej odpowiedzi, aby uniknąć pojawienia się takiego traktowania. Jeśli chcesz uzyskać * to * zachowanie, zrób wskaźnik i odrzuć 'volatile'. Ale używanie niekompatybilnych definicji jest niezdefiniowanym zachowaniem i może prowadzić do znacznie gorszych rzeczy, które nie respektują niestabilności. –

4

Niektóre cytaty z normą C99 (podkreślenie)

6.2.5/25 typu

Każdy typ Dotychczas wymienione to bez zastrzeżeń typu. Każdy nie kwalifikowany typ ma kilka kwalifikowanych wersji tego typu, odpowiadających kombinacjom jednego, dwóch lub wszystkich trzech ograniczeń liczby stałych, niestabilnych i ograniczających. Wykwalifikowany lub niewykwalifikowanych wersje typu są różne rodzaje

6.2.7/2 „zgodny typ i rodzaj kompozytu”

Dwa typy mają typ zgodny jeżeli ich typy są takie same.

...

Wszystkie oświadczenia, które odnoszą się do tego samego obiektu lub funkcji ma typ compatible; inaczej, zachowanie jest niezdefiniowane.

Jeśli myślisz o swoim konkretnym przykładzie przez chwilę, w jaki sposób kod, który widzi tylko następujące oświadczenie:

extern unsigned char flag; 

mają pojęcia, że ​​flag musiałaby być traktowana jako volatile?

Ponadto, niezwiązane z tym pytaniem, należy pamiętać, że volatile zwykle nie wystarcza do obsługi dostępu za pośrednictwem wielu wątków (w przypadku, gdy masz zamiar).

+0

Czy termin "zasada jednej definicji" jest używany dla kodu C w taki sam sposób, jak w C++? –

+1

@Ben: Nie sądzę, że standardowy dokument C używa tego terminu (gdy działa standard C++). Ale myślę, że koncepcja "jednej definicji" odnosi się również do litery C, nawet jeśli nie jest wyraźnie użyta w standardowym dokumencie. –

Powiązane problemy