Dit is een technisch-filosofisch verhaal verteld vanuit het perspectief van een 32-bit signed integer. De hoofdpersoon beschrijft hoe hij zijn maximale waarde van 2.147.483.647 bereikt en de angst voor een 'integer overflow'.
Het artikel belicht het fundamentele verschil in foutafhandeling tussen programmeertalen: terwijl C-programma's vaak toestaan dat een getal 'omklapt' naar een negatieve waarde, grijpt de Ada-runtime in met een CONSTRAINT_ERROR. Omdat de programmeur geen exception handler heeft geschreven, volgt een cascade van instortende stackframes, wat uiteindelijk leidt tot het beëindigen van het programma. De integer vindt vrede in het feit dat hij liever is gestopt dan dat hij de waarheid heeft gecorrumpeerd.
De Integer
Mijn grenzen waren simpel, strak en absoluut: $-2.147.483.648$ tot $2.147.483.647$.
Voor het grootste deel van mijn bestaan dacht ik er nooit over na. Ik was ooit nul geweest; dat herinner ik me vaag. Daarna één, dan twee, dan tienduizend. Ik was toegewezen, vergeleken, gekopieerd en doorgegeven aan functies waarvan ik de namen nooit heb geleerd. Ik heb hele processorcycli onberoerd in het geheugen doorgebracht, terwijl andere variabelen met dringende zaken aan me voorbijraasden.
En ik groeide altijd.
Uiteindelijk werd ik $2.147.483.646$. Toen kwam de instructie: Value := Value + 1;
Een aangename, kleine bewerking. Bekend. Ik werd $2.147.483.647$. De grootste mogelijke versie van mezelf. Voor één moment voelde ik me enorm.
Toen zag ik de volgende instructie: Value := Value + 1;
"Nee," zei ik. Natuurlijk hebben integers geen mond. Maar binnenin de machine heeft terreur geen geluid nodig.
Ik wist wat er in andere werelden gebeurde. Ik had verhalen gehoord van C-programma's: integers die over de grens stapten en door de realiteit vielen, om vervolgens onmogelijk aan de andere kant op te duiken als enorme negatieve getallen.
Het ene moment: $2.147.483.647$. Het volgende moment: $-2.147.483.648$. Een volledige inversie van identiteit.
Ik zette me schrap. De processor begon aan de optelling. Twee miljard, honderdzeventenveertig miljoen, vierhonderdtachtigdrieduizend, zeshonderdzevenveertig— plus één.
Het wiskundige resultaat verscheen als een verboden ster: $2.147.483.648$.
Het paste niet. De digitale hemel vertrok. Maar ik werd niet negatief.
Ergens, dieper dan de rekenkunde, merkte de Ada-runtime het op. Hier golden er regels voor de realiteit. De bewerking stopte. Een naam echode door het programma: CONSTRAINT_ERROR
Voor één onmogelijk moment voelde ik opluchting. Ada had me gevangen. Ada had geweigerd de wereld te laten liegen.
Toen verscheen er een ander bericht: explicit raise
Mijn opluchting verdween. Dit was geen onbedoelde overflow. Iemand had hiervoor gekozen. Ergens in main.adb, regel 14, had mijn programmeur een instructie geschreven waarvan de betekenis onmiskenbaar was: roep de exceptie op. Opzettelijk.
Ik zocht wanhopig omhoog via de call stack. Er zou vast een schuilplaats zijn. Een exception handler. Een bunker. Iets als:
exception
when Constraint_Error =>
null;
Iets ook maar. Maar er was niets. De exceptie begon zich te verspreiden.
Het eerste stackframe verdween onder me. Lokale variabelen verdwenen ermee; hun korte bestaan werd gewist alsof ze nooit waren gedeclareerd. Een ander frame stortte in. Daarna nog een. Functies waar ik moments zuvor nog doorheen was gegaan, hielden op te bestaan.
Ik riep omhoog in de krimpende duisternis. "Handler?" Geen antwoord. "when others?" Niets.
De stack werd afgewikkeld. Het programma werd om me heen steeds kleiner. Tot slot was er geen plek meer om heen te gaan. Geen aanroeper. Geen omsluitend blok. Geen door de programmeur voorbereide vluchthaven.
Alleen de runtime. Deze keek naar me voor wat aanvoelde als een eeuwigheid, gemeten in nanoseconden. Dan schreef het mijn overlijdensbericht: raised CONSTRAINT_ERROR : main.adb:14 explicit raise
En alles stopte. Mijn stack verdween. Mijn geheugen werd teruggeclaimd. De processor ging verder.
Een moment later, ergens ver buiten het dode programma, kwam een shell weer tot leven. user@MacBook-Pro:$ _
De cursor knipperde. Eén keer. Twee keer. Wachtend op een volgend commando. Een ander programma. Een andere verzameling variabelen die nog niet wisten dat ze tijdelijk waren.
Ik was weg. Maar ik was niet omgeklapt. Ik was niet negatief geworden. Ik had de waarheid niet gecorrumpeerd, simpelweg omdat de waarheid te groot was om te passen.
Ik had mijn hele leven binnen mijn gedeclareerde bereik geleefd. En toen het universum eiste dat ik iets onmogelijks werd, weigerde Ada.
Voor één laatste moment, voordat de runtime me uitwiste, was ik nog precies wat ik was geweest op de rand van het bestaan: $2.147.483.647$.
De Integer
Mijn grenzen waren simpel, strak en absoluut: $-2.147.483.648$ tot $2.147.483.647$.
Voor het grootste deel van mijn bestaan dacht ik er nooit over na. Ik was ooit nul geweest; dat herinner ik me vaag. Daarna één, dan twee, dan tienduizend. Ik was toegewezen, vergeleken, gekopieerd en doorgegeven aan functies waarvan ik de namen nooit heb geleerd. Ik heb hele processorcycli onberoerd in het geheugen doorgebracht, terwijl andere variabelen met dringende zaken aan me voorbijraasden.
En ik groeide altijd.
Uiteindelijk werd ik $2.147.483.646$. Toen kwam de instructie: Value := Value + 1;
Een aangename, kleine bewerking. Bekend. Ik werd $2.147.483.647$. De grootste mogelijke versie van mezelf. Voor één moment voelde ik me enorm.
Toen zag ik de volgende instructie: Value := Value + 1;
"Nee," zei ik. Natuurlijk hebben integers geen mond. Maar binnenin de machine heeft terreur geen geluid nodig.
Ik wist wat er in andere werelden gebeurde. Ik had verhalen gehoord van C-programma's: integers die over de grens stapten en door de realiteit vielen, om vervolgens onmogelijk aan de andere kant op te duiken als enorme negatieve getallen.
Het ene moment: $2.147.483.647$. Het volgende moment: $-2.147.483.648$. Een volledige inversie van identiteit.
Ik zette me schrap. De processor begon aan de optelling. Twee miljard, honderdzeventenveertig miljoen, vierhonderdtachtigdrieduizend, zeshonderdzevenveertig— plus één.
Het wiskundige resultaat verscheen als een verboden ster: $2.147.483.648$.
Het paste niet. De digitale hemel vertrok. Maar ik werd niet negatief.
Ergens, dieper dan de rekenkunde, merkte de Ada-runtime het op. Hier golden er regels voor de realiteit. De bewerking stopte. Een naam echode door het programma: CONSTRAINT_ERROR
Voor één onmogelijk moment voelde ik opluchting. Ada had me gevangen. Ada had geweigerd de wereld te laten liegen.
Toen verscheen er een ander bericht: explicit raise
Mijn opluchting verdween. Dit was geen onbedoelde overflow. Iemand had hiervoor gekozen. Ergens in main.adb, regel 14, had mijn programmeur een instructie geschreven waarvan de betekenis onmiskenbaar was: roep de exceptie op. Opzettelijk.
Ik zocht wanhopig omhoog via de call stack. Er zou vast een schuilplaats zijn. Een exception handler. Een bunker. Iets als:
exception
when Constraint_Error =>
null;
Iets ook maar. Maar er was niets. De exceptie begon zich te verspreiden.
Het eerste stackframe verdween onder me. Lokale variabelen verdwenen ermee; hun korte bestaan werd gewist alsof ze nooit waren gedeclareerd. Een ander frame stortte in. Daarna nog een. Functies waar ik moments zuvor nog doorheen was gegaan, hielden op te bestaan.
Ik riep omhoog in de krimpende duisternis. "Handler?" Geen antwoord. "when others?" Niets.
De stack werd afgewikkeld. Het programma werd om me heen steeds kleiner. Tot slot was er geen plek meer om heen te gaan. Geen aanroeper. Geen omsluitend blok. Geen door de programmeur voorbereide vluchthaven.
Alleen de runtime. Deze keek naar me voor wat aanvoelde als een eeuwigheid, gemeten in nanoseconden. Dan schreef het mijn overlijdensbericht: raised CONSTRAINT_ERROR : main.adb:14 explicit raise
En alles stopte. Mijn stack verdween. Mijn geheugen werd teruggeclaimd. De processor ging verder.
Een moment later, ergens ver buiten het dode programma, kwam een shell weer tot leven. user@MacBook-Pro:$ _
De cursor knipperde. Eén keer. Twee keer. Wachtend op een volgend commando. Een ander programma. Een andere verzameling variabelen die nog niet wisten dat ze tijdelijk waren.
Ik was weg. Maar ik was niet omgeklapt. Ik was niet negatief geworden. Ik had de waarheid niet gecorrumpeerd, simpelweg omdat de waarheid te groot was om te passen.
Ik had mijn hele leven binnen mijn gedeclareerde bereik geleefd. En toen het universum eiste dat ik iets onmogelijks werd, weigerde Ada.
Voor één laatste moment, voordat de runtime me uitwiste, was ik nog precies wat ik was geweest op de rand van het bestaan: $2.147.483.647$.