Meghatározatlan viselkedés

Meghatározatlan viselkedés ( eng.  unspecified behavior ) és implementáció által definiált viselkedés ( angol  implementáció által definiált viselkedés ) - egy számítógépes program viselkedése , amely a különböző platformokon és fordítókonként változhat, mivel a programozási nyelv specifikációja számos érvényes lehetőséget kínál egy bizonyos nyelvi konstrukció. A nem meghatározott viselkedéssel ellentétben a nem meghatározott viselkedésű program nem tekinthető hibásnak a nyelvi specifikációnak való megfelelés szempontjából; meghatározatlan viselkedés esetén a specifikáció általában korlátozza a lehetséges viselkedéseket, bár nem redukálja azokat egyetlen elfogadhatóra.

A kettő között az a különbség, hogy a viselkedés implementáció által meghatározott, dokumentált és konzisztens egy adott processzoron, környezetben, rendszerverzión stb., vészhelyzeti módban.

A programozónak kerülnie kell a meghatározatlan viselkedést olyan helyeken, ahol ez kritikus a program eredménye szempontjából – például ha két függvényt nem meghatározott sorrendben hívnak meg, és megosztják a hibakeresési kódot, ez látható lesz a hibakeresési naplóban , de előfordulhat, hogy nem legyen kritikus az eredmény szempontjából. Egy platformra író programozó kötődhet saját megvalósításához. És ha platformokon átívelő programot ír, akkor figyelembe kell vennie az implementáció által meghatározott ésszerű viselkedési eseteket.

Terminológia

A C99 nyelvi szabvány szerint

Eredeti szöveg  (angol)[ showelrejt] 3.4.1 megvalósítás által meghatározott viselkedés

meghatározatlan viselkedés, ahol az egyes megvalósítások dokumentálják a választás módját

[…]

3.4.3 meghatározatlan viselkedés

meghatározatlan érték használata, vagy más viselkedés, ahol ez a nemzetközi szabvány két vagy több lehetőséget biztosít, és nem támaszt további követelményeket, amelyekre semmilyen esetben választják – ISO/IEC 9899:201x [1]

A C++ nyelvi szabvány szerint

Eredeti szöveg  (angol)[ showelrejt] 1.3.5 megvalósítás által meghatározott viselkedés

viselkedés, jól formált programkonstrukció és helyes adatok esetén, amely a megvalósítástól függ, és amelyet minden implementációnak dokumentálnia kell.

[…]

1.3.13 meghatározatlan viselkedés

viselkedés, jól formázott programkonstrukció és helyes adatok esetén, ami a megvalósítástól függ. A megvalósításnak nem szükséges dokumentálnia, hogy melyik viselkedés történik. [Megjegyzés: általában ez a nemzetközi szabvány határozza meg a lehetséges viselkedési formákat. ]

– ISO/IEC 14882:2003(E)

Példák

C és C++ nyelven (a Java nyelvtől eltérően ) a függvényparaméterek kiértékelési sorrendje nincs meghatározva; ezért az alábbi programban az "F" és "G" karakterláncok nyomtatási sorrendje a fordítótól függ.

#include <iostream> int f () { std :: cout << "F" << std :: endl ; visszatérés 3 ; } intg ( ) { std :: cout << "G" << std :: endl ; visszatérés 4 ; } int h ( int i , int j ) { return i + j ; } int main () { visszatér h ( f (), g ()); }

A megvalósítás által meghatározott viselkedés klasszikus példája (meghatározatlan viselkedés, amelyet az implementációknak dokumentálniuk kell) az adattípusok mérete; például a long különböző fordítóprogramokban és operációs rendszerekben 32 vagy 64 bit hosszú lehet. Egy olyan program, amely azt feltételezi, hogy egyetlen hosszú mindig elfér egy mutató , nem fog megfelelően működni bizonyos platformokon (például Windows x64 rendszeren ) [2] .

Íme a gyors inverz négyzetgyök két megvalósítása : a Carmack  - Abrash implementáció ( Quake III ) és a C++20 implementáció az angol Wikipédiából:

float Q_rsqrt ( lebegő szám ) { hosszú i ; úszó x2 , y ; const float threehalfs = 1,5F ; x2 = szám * 0,5F ; y = szám ; i = * ( hosszú * ) & y ; // gonosz lebegőpontos bitszintű hackelés i = 0x5f3759df - ( i >> 1 ); // mi a fasz? y = * ( lebegő * ) & i ; y = y * ( háromfél - ( x2 * y * y ) ); // 1. iteráció // y = y * ( threehalfs - ( x2 * y * y ) ); // 2. iteráció, ez eltávolítható vissza y ; } constexpr float Q_rsqrt ( float number ) nokivéve { static_assert ( std :: numeric_limits < float >:: is_iec559 ); float const y = std :: bit_cast < float > ( 0x5f3759df - ( std :: bit_cast < std :: uint32_t > ( szám ) >> 1 )); return y * ( 1.5f - ( szám * 0.5f * y * y )); }

Az első Windowsra és 32 bites Linuxra készült, a második univerzálisabb: fordítási hibát ad, ha a gép nem szabványos tört típusokkal rendelkezik; nem igényel sokáig, hogy 32 bites legyen.

Lásd még

Jegyzetek

  1. ISO/IEC 9899:201x bizottsági tervezet –  2008. augusztus 11 . Letöltve: 2009. december 1. Az eredetiből archiválva : 2012. április 11..
  2. ↑ hosszú egész típus mérete különböző architektúrán és operációs rendszeren  . Intel szoftverhálózat. Letöltve: 2009. december 1. Az eredetiből archiválva : 2012. április 11..

Linkek