Back

ⓘ Недефинисано понашање




                                     

ⓘ Недефинисано понашање

У програмирању, недефинисано понашање је резултат извршавања кода рачунара написаног у неком програмском језику за који спецификација језика не прописује како се треба поступати са кодом. Недефинисано понашање је непредвидиво и често узрок софтверских грешака.

Понашање неких програмских језика-најпознатији С и С++ - је дефинисано у неким случајевима. У стандардима ових језика, семантике појединих операција су недефинисане. Имплементацији је дозвољено да претпостави да се такве операције никада не дешавају у стандарду-у складу програмског кода; имплементацијом ће се сматрати исправно све што ради у таквим случајевима, аналогно небитним вредностима у дигиталној логици. Ова претпоставка може да прави најразличитије програмске трансформације да важе или да поједностави своје доказе о исправности, дајући флексибилност у имплементацији. То је одговорност програмера за писање кода који никада не призива дефинисано понашање, иако су имплементације компајлера слободне да покрену дијагностику када се ово деси.

На пример, у С употреба било које аутоматске променљиве пре него што је инициализована има за исход недефинисано понашање, као што то чини дељење са нулом или индексирање низа изван дефинисаних граница види бафер преливања. У принципу, свака инстанца недефинисаног понашања оставља апстрактну машину за убијање у непознатом стању, а свако накнадно понашање је такође недефинисано. Ако није потребно да преводилац дијагностикује недефинисано понашање, програми позивајући се на недефинисано понашање могу саставити и покренути производњу исправних резултата, нетачних резултате, или имају било какво друго понашање. Због тога, недефинисано понашање могу створити грешке које је тешко открити.

Под одређеним околностима могу постојати посебна ограничења недефинисаног понашања. На пример, сет инструкција спецификације CPU може да напусти понашање неких облика која су упутством дефинисана, али ако CPU подржава заштиту меморије онда ће спецификација вероватно укључити бланко правило наводећи да ниједан корисник не може да приступи и да упутство може изазвати рупу у безбедности оперативног система; тако да ће стварном процесору бити дозвољено да корумпиране кориснике региструје као одговор на такву инструкцију, али неће му бити дозвољено да се, на пример, пребаци у режим супервизора.

У С и C++, имплементацијом дефинисано понашање се користи, где стандардни језик не одређује понашање, али примена мора изабрати понашање и документ и мора да поштује своја правила. Ови стандарди такође користе неодређено понашање да значи да је од датог скупа могућности није наведено које понашање имплементација мора да изабере, то не мора да документује избор или чак бити у складу, али мора да изабере једну могућност.

У С заједници, недефинисано понашање може бити духовито названо као назални демони пост о Usenet-у који је објаснио недефинисано понашање као понашање које дозвољава да компајлер не изабере ништа, чак и "да демони лете из носа ".

                                     

1. Примери у C и C++

Покушај да се измени буквални низ изазива недефинисано понашање:

Један од начина да се спречи ово је дефинисање као низ уместо показивача.

У C++, особа може употребити стандардни стринг као у наставку:

Целобројно дељење нулом резултује у недефинисано понашање:

Неки показивачи операција могу довести до недефинисаног понашања:

Постизање краја функције вредности повратка осим главног без повратне изјаве могу довести до недефинисаног понашања:

Оригинална књига С програмског језика наводи следеће примере кода који "могу и који то раде производе различите резултате на различитим машинама” што би се могло сматрати само неодређеним или имплементацијом дефинисаном понашањем у данашњим условима:

Касније ANSI C стандард је одлучио да напусти сличне конструкције недефинисаног, на пример, "Овај став чини недефинисану изјаву изразе као што су i = ++i + 1; док дозвољава i = i + 1; ”.

                                     

2. Ризици недефинисаног понашања

HTML верзије 4 и раније су напустиле грешку руковања недефинисаним. Временом су странице почеле да се ослањају на неодређено опоравка грешака спровођених у популарним претраживачима. Ово је изазвало проблеме за произвођаче мање популарних претраживача који су били приморани да преокрену-инжењеринг и имплементирају баг компатибилни опоравак грешке. То је довело до де факто стандарда који је био много компликованији него што је могао да буде да је такво понашање наведено од самог почетка.

Недефинисано понашање у сервер програмима може да изазове безбедносне проблеме. Када су GCC програмери променили компајлер у 2008. години тако да је изостављено одређено преливање провере које се ослањаlo на недефинисано понашање, CERT је издао упозорење против новијих верзија компајлера. Linux Weekly News је истакао да је исто понашање посматрано у PathScale C, Microsoft Visual C++ 2005 и неколико других компајлера ; упозорење је касније измењено да упозори о различитим компајлерима.