2016-07-05 27 views
6

Natknąłem się na wiele komentarzy na różne pytania dotyczące bitfieldów, twierdząc, że bitfieldy są nieprzenośne, ale nigdy nie udało mi się znaleźć źródła wyjaśniającego dokładnie dlaczego.Dlaczego i w jaki sposób bitfieldy C++ są nieprzenośne?

Przy wartości nominalnej, przypuszczałem, że wszystkie bitfieldy jedynie kompilują się do wariacji tego samego kodu przenoszenia bitów, ale widocznie musi być ich więcej, inaczej nie byłoby dla nich tak gwałtownej niechęci.

Moje pytanie brzmi: co sprawia, że ​​bitfields nie jest przenośny?

+1

W jakim kontekście zostały one nazwane "niebezpieczne"? Dodaj link? – anatolyg

+6

Myślę, że głównie w ten sposób ludzie nadużywają bitfieldów do wydobywania fragmentów reprezentacji innych typów danych na poziomach pod-bajtów, co jest całkowicie nieprzenośne. – user2357112

+0

@anatolyg [Komentarz Lundina] (http://stackoverflow.com/questions/35934375/bitfields-in-c-programming-language/35935493#comment59526628_35934375) na [to pytanie] (http://stackoverflow.com/questions/ 35934375/bitfields-in-c-język programowania/35935493). To oczywiste, że nie widziałem, by oskarżano ich o bycie "niebezpiecznymi" tak samo jak "nieprzenośnych", ale nadal. – Pharap

Odpowiedz

2

Pola bitowe są nieprzenośne w tym sensie, że kolejność bitów jest nieokreślona. Tak więc bit w indeksie 0 z kompilatorem może równie dobrze być ostatnim bitem z innym kompilatorem.

Zapobiega to użyciu pól bitowych w aplikacjach, takich jak przełączanie bitów w rejestrach sprzętowych odwzorowanych w pamięci.

Ale zobaczysz, że dostawca sprzętu używa bitfieldów w wydanym kodzie (na przykład mikroczip). Zwykle dzieje się tak, ponieważ zwalniają one również kompilator lub atakują jeden kompilator. Na przykład w przypadku mikroczipów licencja na ich kod źródłowy upoważnia do korzystania z własnego kompilatora (dla 8-bitowych urządzeń low-end)

Łącze wskazane przez @Pharap zawiera wyciąg (C++ 14) Norma związana z tym nieokreślonym zamówieniem: is-there-a-portable-alternative-to-c-bitfields

+2

Ten układ pól bitowych jest definiowany przez implementację, robi * nie * powoduje, że pola bitowe są nieprzenośne. Jest to kod przyjmujący określony układ, który nie jest przenośny. – 4386427

+0

@ 4386427: Ogólnym * powodem * używania pól bitowych jest uzyskanie pożądanego układu, np. bity opcji w argumencie do funkcji systemu operacyjnego OS. Problem polega na tym, że nie wszystkie kompilatory mogą dawać taki sam wynik (lub inaczej mówiąc, że standard nie oferuje rozsądnych gwarancji dla najczęstszego przypadku użycia). Na koniec ktoś jest przykuty, ale niekoniecznie oryginalny programista. –

+0

@ 4386427 Konstrukcja językowa nie jest przenośna lub przenośna. Jest obsługiwany lub nie przez kompilator. Mówiąc o przenośności zawsze mówimy o * użyciu * tych konstrukcji. Nie sądziłem, że trzeba to sprecyzować. – fjardon

8

Pola bitowe są nieprzenośne w takim samym znaczeniu, jak liczby całkowite są nieprzenośne. Możesz używać liczb całkowitych do napisania programu przenośnego, ale nie możesz oczekiwać, że wyślesz binarną reprezentację int jak do zdalnego komputera i spodziewasz się, że poprawnie zinterpretuje dane.

Dzieje się tak dlatego, że 1. długości słowa procesorów są różne, a przez to różnią się rozmiarami typów całkowitych (długość 1,1 bajtów również może być różna, ale obecnie jest to rzadkość na zewnątrz systemów wbudowanych). A ponieważ 2. endianness bajt różni się w procesorach.

Problemy te są łatwe do przezwyciężenia. Rodzimy endianness może być łatwo przekonwertowany do uzgodnionej endianness (duży endian jest de facto standardem dla komunikacji sieciowej), a rozmiar może być kontrolowany w czasie kompilacji, a liczba stałych typów całkowitych jest dostępna w tych dniach. Dlatego można używać liczb całkowitych do komunikowania się w sieci, o ile te szczegóły są zadbane.

Pola bitów opierają się na zwykłych typach całkowitych, więc mają takie same problemy z endianness i liczbami całkowitymi. Ale mają one określone zachowanie implementacji even more.

  • Wszystko o rzeczywistych szczegółów alokacji pól bitowych wewnątrz obiektu klasy

    • Na przykład, na niektórych platformach, pola bitowe nie STRADDLE bajtach na innych robią
    • Ponadto na niektórych platformach pola bitowe są zapakowane od lewej do prawej, a inne od prawej do lewej:
  • Niezależnie od tego, czy r, krótkie, długie, długie i długie długie pola bitów, które nie są jawnie podpisane lub niepodpisane, są podpisane lub niepodpisane.

przeciwieństwie endianness, to nie jest trywialny do konwersji „wszystko o rzeczywistych szczegółów rozdziału” do postaci kanonicznej.

Ponadto, podczas gdy endianness jest specyfikacją architektury procesora, szczegóły pola bitowego są specyficzne dla implementatora kompilatora. Tak więc pola bitowe nie są przenośne do komunikacji nawet pomiędzy oddzielnymi procesami w obrębie tego samego komputera, chyba że możemy zagwarantować, że zostały skompilowane przy użyciu tego samego (wersji) kompilatora.


Pola bitowe TL nie są przenośnym sposobem komunikacji między komputerami. Liczby całkowite też nie są, ale ich nieprzenośność jest łatwa do obejścia.