reprezentacja trap

  1. Co to jest reprezentacja pułapki w C (niektóre przykłady mogą pomóc)? Czy dotyczy to C++?

    float f=3.5;
    int *pi = (int*)&f;
    
  2. Edit: wiem ,że ' pi ' narusza zasadę aliasingu i jest to UB zgodnie ze standardem C. Przynajmniej na GCC nie generuje błędów, ale Ostrzeżenia. W tej implementacji (tj. GCC), zakładając, że sizeof(int) == sizeof(float) Czy f i *pi mają tę samą binarną reprezentację/wzór? Co z MSVC?
Author: John Odom, 2011-07-17

3 answers

  1. Reprezentacja pułapki jest terminem catch-all używanym przez C99 (IIRC nie przez C89) do opisywania wzorców bitowych, które pasują do przestrzeni zajmowanej przez typ, ale wywołują niezdefiniowane zachowanie, jeśli są używane jako wartość tego typu. Definicja jest w sekcji 6.2.6. 1p5 (z mackami we wszystkich 6.2.6) i nie będę jej tutaj cytował, ponieważ jest długa i myląca. Typ, dla którego istnieją takie wzorce bitowe, mówi się, że "mają" reprezentacje pułapek. Żaden typ nie jest wymagany do posiadania pułapki reprezentacje, ale jedynym typem, w którym standardowe gwarancje Nie mają reprezentacje pułapek, jest unsigned char (6.2.6. 1P5, 6.2.6.2P1).

    Standard podaje dwa hipotetyczne przykłady reprezentacji pułapek, z których żaden nie odpowiada niczym, co jakikolwiek prawdziwy procesor robił przez wiele lat, więc nie będę was z nimi mylić. A dobry przykład reprezentacji pułapki (również tylko , która kwalifikuje się jako reprezentacja pułapki na poziomie sprzętowym na dowolnym procesorze prawdopodobnie napotkasz) jest sygnalizacyjnym NaN typu zmiennoprzecinkowego. C99 Załącznik F (sekcja 2.1) wyraźnie pozostawia zachowanie sygnalizujących Nan niezdefiniowanych, mimo że IEC 60559 szczegółowo określa ich zachowanie.

    Warto wspomnieć, że podczas gdy typy wskaźników mogą mieć reprezentacje pułapek, wskaźniki null nie są reprezentacjami pułapek. Wskaźniki Null powodują nieokreślone zachowanie tylko wtedy, gdy są dereferenced lub offset; inne operacje na nich (większość co ważne, porównania i kopie) są dobrze zdefiniowane. Reprezentacje pułapek powodują nieokreślone zachowanie, jeśli tylko odczytuje się je przy użyciu typu, który ma reprezentację pułapki. (Czy invalid ale wskaźniki inne niż null są lub powinny być uważane za reprezentacje pułapek jest przedmiotem dyskusji. Procesor nie traktuje ich w ten sposób, ale kompilator może.)

  2. Wyświetlany kod Ma nieokreślone zachowanie, ale jest to spowodowane regułami aliasingu wskaźnika, a nie z powodu pułapek. Oto jak przekonwertować float na int z tą samą reprezentacją (zakładając, jak mówisz, sizeof(float) == sizeof(int))

    int extract_int(float f)
    {
        union { int i; float f; } u;
        u.f = f;
        return u.i;
    }
    

    Ten kod ma nieokreślone (nie niezdefiniowane) zachowanie w C99, co w zasadzie oznacza, że standard nie definiuje jaka wartość całkowita jest wytwarzana, ale otrzymujesz jakąś poprawną wartość całkowitą, nie jest to reprezentacja pułapki, a kompilator nie może zoptymalizować przy założeniu, że tego nie zrobiłeś. (Sekcja 6.2.6.1, pkt 7. Moja kopia C99 może zawierać techniczne sprostowania - przypominam sobie, że ta była niezdefiniowana w oryginalnej publikacji, ale została zmieniona na nieokreśloną w TC.)

 83
Author: zwol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-06 12:45:16

Undefined behavior to alias a float with a pointer-to-int.

 8
Author: Puppy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-17 18:25:15

Ogólnie rzecz biorąc, każda wartość zmiennoprzecinkowa IEEE-754, która nie jest pułapką, może być reprezentowana jako liczba całkowita na niektórych platformach bez żadnego problemu. Jednak istnieją wartości zmiennoprzecinkowe, które mogą spowodować nieoczekiwane zachowanie, jeśli założysz, że Wszystkie wartości zmiennoprzecinkowemają unikalną reprezentację całkowitą i zmusisz FPU do załadowania tej wartości.

(przykład zaczerpnięty z http://www.dmh2000.com/cpp/dswap.shtml )

Na przykład podczas pracy z FP dane, które trzeba miedzy procesorami o różnej endianess, można by pomyśleć o wykonaniu następujących czynności:

double swap(double)

Niestety, jeśli kompilator ładuje dane wejściowe do rejestru FPU i jest to reprezentacja pułapki, FPU może zapisać je z powrotem z równoważną reprezentacją pułapki, która jest inną reprezentacją bitową.

Innymi słowy, istnieją pewne wartości FP, które nie mają odpowiedniej reprezentacji bitowej, jeśli nie konwertujesz poprawnie (przez poprawne mam na myśli przez union, memcpy poprzez char * lub inny standardowy mechanizm).

 2
Author: MSN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-18 19:48:03