Pytanie Lotna semantyka w C99


Mam problem z jakimś kodem niskopoziomowym, który piszę, potrzebuję użyć obiektów jako zmiennych, ale niekoniecznie chcę, aby typy były deklarowane jako zmienne (z powodów ponownego użycia). Mogę jednak zdefiniować wskaźnik do kwalifikowanego wariantu struktury, jak wyszczególniono w następnym segmencie.

struct x {
  int bar;
};

struct x foobar;
...
volatile struct x *foo = &foobar;

Teraz foo jest efektywnie wskaźnikiem do obiektu typu:

volatile struct x {
  volatile int x;
};

ponieważ lotny dotyczy wszystkich członków struktury. Teraz moje pytanie brzmi: kiedy obiekt zawiera wskaźnik do innego obiektu, w jaki sposób zastosowana jest zmienność?

struct x {
  struct y *bar;
};

Będzie wskaźnikiem na niestabilną instancję x, a następnie potraktuj to jako:

volatile struct x {
  struct y * volatile bar;
};

lub jako:

volatile struct x {
  volatile struct y * volatile bar;
};

Przeczytałem standard C, i nie jest to bardzo jasne w związku z tym i mogę z łatwością interpretować sformułowania na wiele sposobów.


12
2018-06-11 14:10


pochodzenie




Odpowiedzi:


W twoim przykładzie ty  uzyskać zmienny wskaźnik, to wszystko, zmienność nie jest rozszerzona na obiekt.

Rozszerzanie mojej odpowiedzi na lotność jest zrelaksowanym atomem, co oznacza, że ​​dostęp jest atomowy, ale instrukcje nie będą. Nie można więc modyfikować ani zmniejszać niestabilności, dlatego nie można używać niestabilnego wskaźnika do interakcji, a jedynie operacje przechowywania / ładowania (przypisania). To samo dotyczy liczby int lub innej, a zmienne również nie będą działać z zmiennymi, ponieważ są przetwarzane w potoku FPU, a nie w CPU. W sumie niestabilne nie są zbyt przydatne, ale kompilatory Microsoftu automatycznie umieszczają strażników instruktażowych wokół substancji lotnych, co czyni je prawdziwymi wartościami atomowymi, ale to nie jest część normy.


4
2018-06-11 14:26



netrino.com/node/80 Wydaje się wspierać ten pomysł. Nigdy nie czytałem o volitile. Dobry towar. - Kieveli
"lotne nie są zbyt użyteczne": nie znają oprogramowania komputerowego, ale w systemach wbudowanych są niezbędne do zadeklarowania rejestrów sprzętowych lub zmiennych, które można zmienić w przerwaniach. - Steve Melnikoff
Bardzo dobry punkt! Minęło kilka lat od mojego ostatniego projektu osadzonego, więc zapomniałem o tym. Tak czy inaczej, który działał, ponieważ był dla ładunków i sklepów. Na komputerze łatwo zapomnieć o większości przerwaniach, ponieważ są one usuwane przez interfejs API systemu operacyjnego. - Robert Gould
@SteveMelnikoff: w systemach wbudowanych często konieczne jest zagwarantowanie, że operacje na wszystkich obiektach, których adres został wystawiony na świat zewnętrzny, zostaną zsekwencjonowane pod kątem volatileoperacje, ale ponieważ nie wszystkie aplikacje wymagają takiej semantyki, standard C nie nakłada na nie wszystkich implementacji. Niestety, o ile mogę powiedzieć, jedyną opcją gcc i clang zapewnia ich działanie w ten sposób -o0, który wyłącza wszystko optymalizacje. - supercat


Czytanie przez standard tutaj, wydaje się, że wskaźnik jest niestabilny, ale nie faktyczna zawartość samej struktury. Zinterpretowałem to na podanym przykładzie, const t * volatile p (u dołu łącza). Sformułowanie jest jednak niejasne, ale sądzę, że byłby to podobny przykład:

struct foo {
    int bar;
};

struct foo *volatile x;

Zauważ, że nie próbowałem tego, więc mogę być szalenie niepoprawny ... to jest po prostu to, co zebrałem po pobieżnym przejrzeniu standardu.

Ponadto, cdecl usuwa część niejasności. Na przykład:

cdecl> wyjaśnij volatile struct x* foo
zadeklaruj foo jako wskaźnik do volatile struct x

Natomiast:

cdecl> wyjaśnij struct x* volatile foo
zadeklaruj foo jako zmienny wskaźnik do struct x

W jednym przypadku struktura jest niestabilna. W drugim - wskaźnik.


2
2018-06-11 14:28



więc nie możesz po prostu zrobić lotnego struct x * volatile foo; dla lotnego wskaźnika i struktury? - Earlz
@earlz: Tak. Dokładnie. volatile struct x * volatile foo jest lotnym wskaźnikiem dla lotnej struktury x. - FreeMemory