Nespecifikované chování

Nespecifikované chování ( angl.  nespecifikované chování ) a implementací definované chování ( angl.  implementace-definované chování ) - chování počítačového programu , které se může lišit na různých platformách a kompilátorech, protože specifikace programovacího jazyka nabízí několik platných možností pro implementaci určitý jazykový konstrukt. Na rozdíl od nedefinovaného chování není program s nespecifikovaným chováním považován za chybný z hlediska souladu se specifikací jazyka; u nespecifikovaného chování specifikace obvykle omezuje možné chování, i když je nesnižuje na jediné přijatelné.

Rozdíl mezi těmito dvěma je v tom, že chování je implementováno, zdokumentováno a konzistentní v rámci daného procesoru, prostředí, verze systému atd. do nouzového režimu.

Programátor by se měl vyvarovat nespecifikovaného chování na místech, kde je to kritické pro výsledek programu – například pokud jsou dvě funkce volány v blíže nespecifikovaném pořadí a sdílejí ladicí kód, bude to viditelné v protokolu ladění , ale nemusí být kritický pro výsledek. Programátor píšící pro jednu platformu se může připojit ke své vlastní implementaci. A pokud píše multiplatformní program, musí vzít v úvahu všechny rozumné případy chování definované implementací.

Terminologie

Podle jazykového standardu C99 ,

Původní text  (anglicky)[ zobrazitskrýt] 3.4.1 chování definované implementací

nespecifikované chování, kde každá implementace dokumentuje, jak se výběr provádí

[…]

3.4.3 nespecifikované chování

použití blíže nespecifikované hodnoty nebo jiné chování, kdy tato mezinárodní norma poskytuje dvě nebo více možností a neklade žádné další požadavky, které se v žádném případě volí — ISO/IEC 9899:201x [1]

Podle jazykového standardu C++ ,

Původní text  (anglicky)[ zobrazitskrýt] 1.3.5 chování definované implementací

chování, pro dobře zformovanou konstrukci programu a správná data, která závisí na implementaci a která musí každá implementace dokumentovat.

[…]

1.3.13 nespecifikované chování

chování, pro dobře zformovanou konstrukci programu a správná data, které závisí na implementaci. Implementace není povinná dokumentovat, jaké chování se vyskytuje. [Poznámka: Obvykle je rozsah možného chování vymezen touto mezinárodní normou. ]

— ISO/IEC 14882:2003(E)

Příklady

V C a C++ (na rozdíl od jazyka Java ) není pořadí, ve kterém se vyhodnocují parametry funkcí, specifikováno; proto v programu níže závisí pořadí, ve kterém se budou řetězce "F" a "G" tisknout, na kompilátoru.

#include <iostream> int f () { std :: cout << "F" << std :: endl ; návrat 3 ; } intg ( ) { std :: cout << "G" << std :: endl ; návrat 4 ; } int h ( int i , int j ) { návrat i + j ; } int main () { návrat h ( f (), g ()); }

Klasickým příkladem chování definovaného implementací (nespecifikované chování, které musí být dokumentovány implementacemi) je velikost datových typů; například dlouhý v různých kompilátorech a operačních systémech může být dlouhý 32 nebo 64 bitů. Program, který předpokládá, že jeden dlouhý se vždy vejde na ukazatel , nebude na některých platformách fungovat správně (například na Windows x64 ) [2] .

Zde jsou dvě implementace rychlé inverzní odmocniny : implementace Carmack  - Abrash ( Quake III ) a implementace C++20 z anglické Wikipedie:

float Q_rsqrt ( float number ) { dlouhé i ; float x2 , y ; const float tři poloviny = 1,5F ; x2 = číslo * 0,5F ; y = číslo ; i = * ( dlouhé * ) & y ; // hacking na úrovni bitů s plovoucí desetinnou čárkou i = 0x5f3759df - ( i >> 1 ); // co to sakra? y = * ( float * ) & i ; y = y * ( tři poloviny - ( x2 * y * y ) ); // 1. iterace // y = y * ( tři poloviny - ( x2 * y * y ) ); // 2. iterace, toto lze odstranit vrátit y ; } constexpr float Q_rsqrt ( float number ) noexcept { static_assert ( std :: numeric_limits < float >:: is_iec559 ); float const y = std :: bit_cast < float > ( 0x5f3759df - ( std :: bit_cast < std :: uint32_t > ( číslo ) >> 1 )); návrat y * ( 1,5f - ( číslo * 0,5f * y * y )); }

První je vytvořen pro Windows a 32bitový Linux, druhý je univerzálnější: pokud má stroj nestandardní zlomkové typy, zobrazí chybu kompilace; nevyžaduje dlouhý, aby byl 32bitový.

Viz také

Poznámky

  1. ISO/IEC 9899:201x Návrh komise – 11. srpna  2008 . Získáno 1. prosince 2009. Archivováno z originálu 11. dubna 2012.
  2. ↑ velikost typu long integer na jiné architektuře a OS  . Softwarová síť Intel. Získáno 1. prosince 2009. Archivováno z originálu 11. dubna 2012.

Odkazy