Koncept nedefinovaného chování v jazyku C3

18. 11. 2025
Doba čtení: 47 minut

Sdílet

Programovací jazyk C3
Autor: Root.cz s využitím Zoner AI
Články a videa o programovacích jazycích se většinou zaměřují na zajímavé vlastnosti zvoleného jazyka, ovšem v praxi je nutné, aby vývojáři dobře znali i temná zákoutí jeho specifikace – takzvaná nedefinovaná chování.

Obsah

1. Koncept nedefinovaného chování v jazyku C3

2. Bezpečné a potenciálně nebezpečné režimy překladu

3. Dělení nulou

4. Dělení se zbytkem (modulo) nulou

5. Změna znaménka nejmenší celočíselné hodnoty (daného typu) se znaménkem

6. Změna znaménka operací součinu nebo podílu

7. Přetečení u celočíselných typů se znaménkem (signed)

8. Nedefinované hodnoty lokálních konstant v různých režimech překladu

9. Přístup k prvku pole s indexem, který přesahuje meze pole

10. Nepatrně složitější příklad přístupu do neexistujícího prvku pole

11. Překročení meze u řezů (slice)

12. Přístup do paměti přes nulový ukazatel

13. Nedodržení specifikovaného kontraktu: podmínka pro vstupní parametry

14. Nedodržení specifikovaného kontraktu: podmínka pro výslednou hodnotu

15. Přístup k lokální proměnné mimo oblast její platnosti (příklad v C)

16. Realizace stejného programu v jazyku C3

17. Bitový posun se specifikací záporného počtu bitů

18. Obsah navazující části

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Koncept nedefinovaného chování v jazyku C3

Většina článků a především videí o programovacích jazycích se primárně zaměřuje na zajímavé vlastnosti zvoleného programovacího jazyka, popř. na rozdíly mezi popisovaným programovacím jazykem a ostatními mainstreamovými jazyky. Ovšem v praxi je nutné, aby vývojáři dobře znali i temná zákoutí specifikace programovacího jazyka. A mezi tato temná zákoutí patří i nedefinované chování (undefined behavior) neboli krátce UB. Jsou to takové programové konstrukce, které mohou být vykonávány různým způsobem v závislosti na zvoleném překladači, parametrech překladu, použité platformě, operačním systému, zvoleném způsobu zarovnání dat v operační paměti atd. atd. Typicky jsou tyto oblasti ve specifikaci jazyka popsány buď vágním způsobem, nebo je (v lepším případě) přímo specifikováno, že se určitá programová konstrukce může chovat v závislosti na implementaci.

Dnes si popíšeme ty programové konstrukce jazyka C3, u kterých je explicitně řečeno, že mají nedefinované chování (a nejedná se tedy o chyby překladače nebo runtime).

2. Bezpečné a potenciálně nebezpečné režimy překladu

Překladač jazyka C3 může při překladu programů používat různé optimalizační metody. Na rozdíl od (například) programovacího jazyka C je v případě C3 jasně specifikováno, které režimy překladu vedou k takzvanému bezpečnému (safe) kódu a které naopak vedou ke kódu, z něhož byly odstraněny některé bezpečnostní konstrukce (unsafe). Překlad v „bezpečném“ režimu vede k pomalejšímu a objemnějšímu binárnímu kódu, do kterého jsou vloženy testy potenciálně nebezpečných stavů – což od vysokoúrovňového jazyka mnohdy očekáváme. A naopak v unsafe režimu získáme kratší a rychlejší výsledek, který ovšem může vykazovat chybné chování, které není hlášeno (bude ignorováno, pokud kontroly nepřidáme přímo do zdrojových kódů):

  -O0         - Safe, no optimizations, emit debug info.
  -O1         - Safe, high optimization, emit debug info.
  -O2         - Unsafe, high optimization, emit debug info.
  -O3         - Unsafe, high optimization, single module, emit debug info.
  -O4         - Unsafe, highest optimization, relaxed maths, single module, emit debug info, no panic messages.
  -O5         - Unsafe, highest optimization, fast maths, single module, emit debug info, no panic messages, no backtrace.
  -Os         - Unsafe, high optimization, small code, single module, no debug info, no panic messages.
  -Oz         - Unsafe, high optimization, tiny code, single module, no debug info, no panic messages, no backtrace.
Poznámka: v praxi to tedy znamená, že aplikace, které vzniknou překladem toho samého zdrojového kódu, se mohou při spuštění chovat odlišně – a specifikace jazyka C3 ty části, které se mohou chovat odlišně, přesně specifikuje právě jako UB.

3. Dělení nulou

Velmi dobrým příkladem nedefinovaného chování je dělení nulou. V případě, že jsou zapnuty optimalizace, přesněji řečeno ty optimalizace, které jsou v tabulce z předchozí kapitoly označeny slovem unsafe, může dělení nulou vrátit jakýkoli výsledek. Naopak v safe režimu vznikne při dělení nulou běhová chyba.

Otestovat si to můžeme velmi snadno:

module undefined_behaviour;
import std::io;
 
fn int div(int a, int b)
{
    return a/b;
}
 
fn void main()
{
    io::printf("%d/%d=%d\n", 2, 1, div(2, 1));
    io::printf("%d/%d=%d\n", 1, 0, div(1, 0));
}

Překlad s využitím safe a následné spuštění:

$ ./c3c compile-run 01_div_by_zero.c3

V tomto režimu vznikne při pokusu o dělení nulou běhová chyba, která není zachycena, takže je aplikace ukončena:

Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
2/1=2
 
ERROR: 'Division by zero.'
  in std.core.builtin.default_panic (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:175) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.div (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/01_div_by_zero.c3:6) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/01_div_by_zero.c3:12) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in @main_to_void_main (/home/ptisnovs/xy/c3c/build/lib/std/core/private/main_stub.c3:18) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour] [inline]
  in main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/01_div_by_zero.c3:9) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in __libc_start_call_main (source unavailable) [/lib64/libc.so.6]
  in __libc_start_main_alias_2 (source unavailable) [/lib64/libc.so.6]
  in _start (source unavailable) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
Program interrupted by signal 4.

Naopak překlad s využitím unsafe režimu nebude takovou chybu detekovat a výsledek dělení nulou může být jakýkoli:

$ ./c3c compile-run -O3 01_div_by_zero.c3

Zde konkrétně dělení nulou vrátilo nulovou hodnotu, ale opravdu se může jednat o jakékoli číslo – a chování bude stále přesně odpovídat specifikaci jazyka C3:

Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
2/1=2
1/0=0

4. Dělení se zbytkem (modulo) nulou

Naprosto stejným způsobem je jako nedefinované chování označen výsledek výpočtu zbytku po dělení (modulo). Opět si to otestujeme na velmi jednoduchém demonstračním příkladu:

module undefined_behaviour;
import std::io;
 
fn int mod(int a, int b)
{
    return a%b;
}
 
fn void main()
{
    io::printf("%d/%d=%d\n", 2, 1, mod(2, 1));
    io::printf("%d/%d=%d\n", 1, 0, mod(1, 0));
}

Překlad v safe režimu

$ ./c3c compile-run 02_mod_by_zero.c3

Opět dojde k vyhození běhové chyby (ovšem odlišné):

Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
2/1=0
 
ERROR: '% by zero.'
  in std.core.builtin.default_panic (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:175) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.mod (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/02_mod_by_zero.c3:6) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/02_mod_by_zero.c3:12) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in @main_to_void_main (/home/ptisnovs/xy/c3c/build/lib/std/core/private/main_stub.c3:18) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour] [inline]
  in main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/02_mod_by_zero.c3:9) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in __libc_start_call_main (source unavailable) [/lib64/libc.so.6]
  in __libc_start_main_alias_2 (source unavailable) [/lib64/libc.so.6]
  in _start (source unavailable) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
Program interrupted by signal 4.

Naproti tomu v unsafe režimu je chování explicitně nedefinované a může se vrátit jakákoli hodnota:

$ ./c3c compile-run -O3 02_mod_by_zero.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
2/1=0
1/0=0
Program completed with exit code 0.

5. Změna znaménka nejmenší celočíselné hodnoty (daného typu) se znaménkem

V některých programovacích jazycích není definováno, jaký bude výsledek operace pro změnu znaménka v případě, že vstupem do této operace je nejmenší možné celé číslo pro použitý datový typ. Například datový typ short je ve specifikaci programovacího jazyka C3 uveden zcela přesně – jedná se o šestnáctibitovou hodnoty se znaménkem, tedy o hodnoty v rozsahu –32768 až +32767. Problém změny znaménka spočívá v tom, že rozsah hodnot není symetrický okolo nuly, neboli pokud se pokusíme o změnu znaménka hodnoty –32768, bude výsledek mimo rozsah typu short. V případě jazyka C3 je výsledek (na rozdíl od některých jiných jazyků) přesně specifikován:

module undefined_behaviour;
import std::io;
 
fn short foo(short a)
{
    return -a;
}
 
fn void main()
{
    io::printf("%d->%d\n", 0, foo(0));
    io::printf("%d->%d\n", 1, foo(1));
    io::printf("%d->%d\n", 32767, foo(32767));
    io::printf("%d->%d\n", -32767, foo(-32767));
    io::printf("%d->%d\n", -32768, foo(-32768));
}

Výsledky jsou v tomto případě vždy přesně specifikovány:

0->0
1->-1
32767->-32767
-32767->32767
-32768->-32768

6. Změna znaménka operací součinu nebo podílu

Prakticky stejné (přesně definované) chování programovací jazyk C3 zajišťuje i v případě součinu nebo podílu hodnotou –1. Opět totiž platí, že C3 i u celočíselných datových typů se znaménkem přesně určuje výsledek -1×x, kde x je nejmenší hodnota daného celočíselného datového typu:

module undefined_behaviour;
import std::io;
 
fn short foo(short a)
{
    return -1*a;
}
 
fn void main()
{
    io::printf("%d->%d\n", 0, foo(0));
    io::printf("%d->%d\n", 1, foo(1));
    io::printf("%d->%d\n", 32767, foo(32767));
    io::printf("%d->%d\n", -32767, foo(-32767));
    io::printf("%d->%d\n", -32768, foo(-32768));
}

Výsledky:

0->0
1->-1
32767->-32767
-32767->32767
-32768->-32768

Totéž platí i pro operaci podílu:

module undefined_behaviour;
import std::io;

fn short foo(short a)
{
    return a/-1;
}

fn void main()
{
    io::printf("%d->%d\n", 0, foo(0));
    io::printf("%d->%d\n", 1, foo(1));
    io::printf("%d->%d\n", 32767, foo(32767));
    io::printf("%d->%d\n", -32767, foo(-32767));
    io::printf("%d->%d\n", -32768, foo(-32768));
}

7. Přetečení u celočíselných typů se znaménkem (signed)

Předchozí dva demonstrační příklady ukazovaly (definované) chování programovacího jazyka C3 při provádění operací s hodnotami celočíselného datového typu se znaménkem (signed). Ve skutečnosti jsou v jazyku C3 operace s typy se znaménkem vždy přesně definovány (specifikace říká, že se používá dvojkový doplněk), což je v ostrém kontrastu například s programovacím jazykem C. Například následující demonstrační příklad bude vždy vracet korektní (definované) výsledky, bez ohledu na použitou architekturu či překladač:

module undefined_behaviour;
import std::io;
 
fn short inc(short a)
{
    return a+1;
}
 
fn void main()
{
    io::printf("%d+1=%d\n", 0, inc(0));
    io::printf("%d+1=%d\n", 1, inc(1));
    io::printf("%d+1=%d\n", 32766, inc(32766));
    io::printf("%d+1=%d\n", 32767, inc(32767));
    io::printf("%d+1=%d\n", -32767, inc(-32767));
    io::printf("%d+1=%d\n", -32768, inc(-32768));
}

Výsledky budou stejné na všech architekturách:

0+1=1
1+1=2
32766+1=32767
32767+1=-32768
-32767+1=-32766
-32768+1=-32767

8. Nedefinované hodnoty lokálních konstant v různých režimech překladu

Popišme si další nedefinované chování programovacího jazyka C3. To se týká lokálních proměnných, tj. proměnných, které jsou viditelné v rámci nějakého bloku. Výchozí hodnota těchto proměnných je určena následujícím způsobem:

  1. Pokud je provedena explicitní inicializace, má vždy přednost (toto je plně definované chování)
  2. Neinicializovaná lokální proměnná je vynulována (i zde se jedná o definované chování)
  3. Proměnná označená jako @noinit (nedefinované chování, závisí na způsobu překladu)

Otestujme všechny tři výše uvedené možnosti na následujícím demonstračním příkladu:

module undefined_behaviour;
import std::io;
 
fn void main()
{
    int x = 0;
    int y;
    int z @noinit;
    io::printf("x: %d\n", x);
    io::printf("y: %d\n", y);
    io::printf("z: %d\n", z);
}

Překlad v safe režimu může vést k tomu, že se indikuje chyba popř. bude proměnná vynulována (ovšem nevíme, která možnost nastane):

$ c3c compile-run 05_undefined_value.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
x: 0
y: 0
z: 0

Naproti tomu překlad v unsafe režimu nás o tomto potenciálním problému vůbec neinformuje a proměnná bude mít nedefinovaný obsah.

9. Přístup k prvku pole s indexem, který přesahuje meze pole

Dalším potenciálně problematickým místem je přístup k prvkům polí nebo řezů v případě, že index prvku, který je čten nebo zapisován, leží mimo meze pole či řezu. Některé (jednodušší) chyby tohoto typu dokáže odhalit překladač jazyka C3. Je tomu tak i v následujícím případě:

module undefined_behaviour;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    io::printf("a=%s\n", a);
 
    io::printf("a[0]=%d\n", a[0]);
    io::printf("a[9]=%d\n", a[9]);
    io::printf("a[10]=%d\n", a[10]);
}

Chyba na posledním řádku funkce main je v tomto případě překladačem jazyka C3 odhalena:

$ ./c3c compile-run 06_out_of_bounds_1.c3
 
 9:
10:     io::printf("a[0]=%d\n", a[0]);
11:     io::printf("a[9]=%d\n", a[9]);
12:     io::printf("a[10]=%d\n", a[10]);
                                   ^^
(/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/06_out_of_bounds_1.c3:12:32) Error: An index of '10' is out of range, a value between 0 and 9 was expected.

10. Nepatrně složitější příklad přístupu do neexistujícího prvku pole

V předchozím demonstračním příkladu sice překladač programovacího jazyka C3 korektně odhalil přístup k neexistujícímu prvku pole, ovšem další (podobné) případy již odhalit nedokáže (alespoň nikoli v současné verzi). Například v následujícím zdrojovém kódu modifikujeme v programové smyčce všechny prvky pole, ovšem meze smyčky jsou nastaveny špatně – počítáme s jedním prvkem navíc:

module undefined_behaviour;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    io::printf("a=%s\n", a);
 
    for (int i=0; i<a.len+1; i++) {
        io::printf("a[%d]=%d\n", i, a[i]);
        a[i] = (i + 1)*10;
    }
}

Tato chyba je detekována až po spuštění programu, ovšem pouze v případě, že provedeme překlad v safe režimu:

$ ./c3c compile-run 07_out_of_bounds_2.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
a=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a[0]=1
a[1]=2
a[2]=3
a[3]=4
a[4]=5
a[5]=6
a[6]=7
a[7]=8
a[8]=9
a[9]=10
 
ERROR: 'Array index out of bounds (array had size 10, index was 10)'
  in std.core.builtin.default_panic (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:175) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in std.core.builtin.panicf (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:231) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/07_out_of_bounds_2.c3:11) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in @main_to_void_main (/home/ptisnovs/xy/c3c/build/lib/std/core/private/main_stub.c3:18) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour] [inline]
  in main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/07_out_of_bounds_2.c3:4) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in __libc_start_call_main (source unavailable) [/lib64/libc.so.6]
  in __libc_start_main_alias_2 (source unavailable) [/lib64/libc.so.6]
  in _start (source unavailable) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
Program interrupted by signal 4.

Po překladu v režimu unsafe přistupujeme k neexistujícímu prvku a tedy do paměti, která nám nepatří:

$ ./c3c compile-run -O5 07_out_of_bounds_2.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
a=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a[0]=1
a[1]=2
a[2]=3
a[3]=4
a[4]=5
a[5]=6
a[6]=7
a[7]=8
a[8]=9
a[9]=10
a[10]=0
Program completed with exit code 0.
Poznámka: proces sice nezhavaroval, ale na jiném systému nebo při jiné fázi Měsíce již může dojít k pádu.

11. Překročení meze u řezů (slice)

Podobně může program reagovat (v runtime, tedy za běhu) i při přístupu do pole přes řez (slice). Pokusme se tedy program z předchozí kapitoly upravit takovým způsobem, aby se namísto pole použil řez:

module undefined_behaviour;
import std::io;
 
fn void main()
{
    io::printf("type: %s\n", int[].nameof);
 
    int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    io::printf("a=%s\n", a);
 
    for (int i=0; i<a.len+1; i++) {
        a[i] = (i + 1)*10;
    }
    io::printf("a=%s\n", a);
}

Pokud je překlad proveden v safe režimu, program po svém spuštění detekuje přístup mimo meze řezu a bude nás o tom patřičně informovat:

$ c3c compile-run 11_out_of_bounds_slice.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
type: int[]
a=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 
ERROR: 'Array index out of bounds (array had size 10, index was 10)'
  in std.core.builtin.default_panic (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:175) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in std.core.builtin.panicf (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:231) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/11_out_of_bounds_slice.c3:13) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in @main_to_void_main (/home/ptisnovs/xy/c3c/build/lib/std/core/private/main_stub.c3:18) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour] [inline]
  in main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/11_out_of_bounds_slice.c3:4) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in __libc_start_call_main (source unavailable) [/lib64/libc.so.6]
  in __libc_start_main_alias_2 (source unavailable) [/lib64/libc.so.6]
  in _start (source unavailable) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
Program interrupted by signal 4.

unsafe režimu však kontroly ve výsledném spustitelném souboru chybí a opět tedy přistupujeme k paměti, která nám nepatří (a stát se může obecně cokoli):

$ ./c3c compile-run -O5 11_out_of_bounds_slice.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
type: int[]
a=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
Program completed with exit code 0.

12. Přístup do paměti přes nulový ukazatel

Na další nedefinované chování narazíme ve chvíli, kdy běžící program přistupuje k paměti přes nulový (null) ukazatel. Podívejme se na ten nejjednodušší případ takového chování (který kupodivu není odhalen překladačem). Pokoušíme se vypsat hodnotu z paměti, ovšem namísto korektní adresy se předává nulový ukazatel:

module undefined_behaviour;
import std::io;
 
fn void main()
{
    int *p = null;
 
    io::printf("%d\n", *p);
}

Pokud je program přeložen v safe režimu, bude chyba odhalena, ale až v runtime:

$ c3c compile-run 08_null_pointer.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
 
ERROR: 'Dereference of null pointer, '(int*)arg' was null.'
  in std.core.builtin.default_panic (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:175) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in std.io.int_from_any (/home/ptisnovs/xy/c3c/build/lib/std/io/formatter_private.c3:64) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in @wrap_bad (/home/ptisnovs/xy/c3c/build/lib/std/io/formatter.c3:558) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour] [inline]
  in std.io.Formatter.vprintf (/home/ptisnovs/xy/c3c/build/lib/std/io/formatter.c3:558) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in std.io.printf (/home/ptisnovs/xy/c3c/build/lib/std/io/io.c3:299) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/08_null_pointer.c3:8) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in @main_to_void_main (/home/ptisnovs/xy/c3c/build/lib/std/core/private/main_stub.c3:18) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour] [inline]
  in main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/08_null_pointer.c3:4) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in __libc_start_call_main (source unavailable) [/lib64/libc.so.6]
  in __libc_start_main_alias_2 (source unavailable) [/lib64/libc.so.6]
  in _start (source unavailable) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
Program interrupted by signal 4.

Naopak v unsafe režimu runtime systém jazyka C3 problém neodhalí a program může zhavarovat až při realizaci přístupu na nulovou adresu (což není v chráněném režimu povoleno):

$ ./c3c compile-run -O5 08_null_pointer.c3 
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
Program interrupted by signal 11.
Poznámka: ovšem může nastat libovolná situace – jedná se opět o nedefinované chování.

13. Nedodržení specifikovaného kontraktu: podmínka pro vstupní parametry

Připomeňme si, že v jazyku C3 je možné u funkcí a metod specifikovat takzvané kontrakty, což jsou podmínky, které musí platit pro vstupní parametry funkce (platné a inicializované v době jejího volání) popř. naopak podmínky, které musí platit pro výslednou hodnotu. Podpora kontraktů je mimochodem jedním z nejužitečnějších rysů tohoto programovacího jazyka. Ovšem kontrakty mají též obecně nedefinované chování. Jsou totiž vyhodnocovány pouze při použití safe režimu překladu.

Otestujme si to na kontraktu definovaném pro hodnotu vstupního parametru. Pokusíme se zabránit dělení nulou:

module undefined_behaviour;
import std::io;
 
<*
 @require b != 0
*>
fn int div(int a, int b)
{
    return a/b;
}
 
fn void main()
{
    io::printf("%d/%d=%d\n", 2, 1, div(2, 1));
    io::printf("%d/%d=%d\n", 1, 0, div(1, 0));
}

Tento kontrakt, resp. jeho porušení může být detekováno, ovšem není zaručeno, že to bude platit i pro unsafe režimy překladu:

$ c3c compile-run 09_contract.c3
 
12: fn void main()
13: {
14:     io::printf("%d/%d=%d\n", 2, 1, div(2, 1));
15:     io::printf("%d/%d=%d\n", 1, 0, div(1, 0));
                                       ^^^^^^^^^
(/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/09_contract.c3:15:36) Error: @require "b != 0" violated.

Naopak překlad v unsafe režimu povede k tomu, že se bude dělit nulou, což je vlastně druhé nedefinované chování způsobené prvním nedefinovaným chováním:

$ c3c compile-run -O5 09_contract.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
2/1=2
1/0=0
Program completed with exit code 0.

14. Nedodržení specifikovaného kontraktu: podmínka pro výslednou hodnotu

Prakticky totéž platí i pro kontrakt, kterým je určena podmínka či podmínky, které musí platit pro výslednou (návratovou) hodnotu funkce. Opět si to otestujme:

module undefined_behaviour;
import std::io;
 
<*
 @ensure return > a
*>
fn short add(short a, short b)
{
    return a+b;
}
 
fn void main()
{
    io::printf("%d+%d=%d\n", 1, 1, add(1, 1));
    io::printf("%d+%d=%d\n", 32767, 1, add(32767, 1));
}

Chování tohoto programu se bude opět odlišovat v závislosti na tom, jaký režim překladu je použit.

Použití safe režimu překladu:

$ ./c3c compile-run 10_contract.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
1+1=2
 
ERROR: '@ensure "return > a" violated.'
  in std.core.builtin.default_panic (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:175) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.add (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/10_contract.c3:9) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/10_contract.c3:15) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in @main_to_void_main (/home/ptisnovs/xy/c3c/build/lib/std/core/private/main_stub.c3:18) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour] [inline]
  in main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/10_contract.c3:12) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in __libc_start_call_main (source unavailable) [/lib64/libc.so.6]
  in __libc_start_main_alias_2 (source unavailable) [/lib64/libc.so.6]
  in _start (source unavailable) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]

Použití unsafe režimu překladu:

$ ./c3c compile-run -O5 10_contract.c3
 
Program linked to executable './undefined_behaviour'.
Launching ./undefined_behaviour
1+1=2
Program interrupted by signal 11.

15. Přístup k lokální proměnné mimo oblast její platnosti (příklad v C)

V této kapitole na chvíli odbočme od jazyka C3 zpátky k jeho ideovému předchůdci, tedy ke slavnému céčku. Podívejme se na následující příklad, ve kterém se z funkce foo vrací ukazatel na lokální proměnnou. Problém spočívá v tom, že mimo čas, kdy se provádí příkazy ve funkci foo, nejsou lokální (nestatické) proměnné alokovány, takže nemá smysl vracet odkaz na ně (a už vůbec ne přistupovat přes tento odkaz do paměti):

#include <stdio.h>
 
int* foo()
{
    int a = 42;
    return &a;
}
 
int main(void)
{
    int *p = foo();
    printf("%d\n", *p);
    *p = -1;
    return 0;
}

Běžný překlad pomocí GCC i jiných překladačů bude proveden, „pouze“ se vypíše varování:

$ gcc -Wall -pedantic 12_local_variable_pointer.c
 
12_local_variable_pointer.c: In function ‘foo’:
12_local_variable_pointer.c:6:12: warning: function returns address of local variable [-Wreturn-local-addr]
    6 |     return &a;
      |            ^~

popř.:

$ clang 12_local_variable_pointer.c
 
12_local_variable_pointer.c:6:13: warning: address of stack memory associated with local variable 'a' returned [-Wreturn-stack-address]
    6 |     return &a;
      |             ^
1 warning generated.

Chyba (resp. přímo pád) nastane v runtime:

$ ./a.out
Segmentation fault (core dumped)

Aby byla chyba ohlášena jako skutečná chyba, musíme překladači předat přepínač -Werror:

$ gcc -Wall -Werror -pedantic 12_local_variable_pointer.c
 
12_local_variable_pointer.c: In function ‘foo’:
12_local_variable_pointer.c:6:12: error: function returns address of local variable [-Werror=return-local-addr]
    6 |     return &a;
      |            ^~
cc1: all warnings being treated as errors

popř.:

$ clang -Werror 12_local_variable_pointer.c
 
12_local_variable_pointer.c:6:13: error: address of stack memory associated with local variable 'a' returned [-Werror,-Wreturn-stack-address]
    6 |     return &a;
      |             ^
1 error generated.

16. Realizace stejného programu v jazyku C3

Pokud naprosto stejný program přepíšeme do jazyka C3, bude přístup k lokální proměnné vně funkce korektně detekován překladačem, což je ostatně jen dobře:

module undefined_behaviour;
import std::io;
 
fn int* foo()
{
    int a = 42;
    return &a;
}
 
fn void main()
{
    int *p = foo();
    io::printf("%d\n", *p);
}

Chyba nahlášená při pokusu o překlad (nezávisle na použité úrovni optimalizace):

$ ./c3c compile-run 12_local_variable_pointer.c3
 
 4: fn int* foo()
 5: {
 6:     int a = 42;
 7:     return &a;
               ^^
(/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/12_local_variable_pointer.c3:7:12) Error: A pointer to a local variable will be invalid once the function returns. Allocate the data on the heap or temp memory to return a pointer.

17. Bitový posun se specifikací záporného počtu bitů

Dalším typicky nedefinovaným chováním je v jazyku C3 (ale i v C) bitový posun o záporný počet bitů (to může být poněkud překvapující, ale posledních minimálně čtyřicet let tomu tak skutečně je):

module undefined_behaviour;
import std::io;
 
fn short shift(short a, short b)
{
    return a<<b;
}
 
fn void main()
{
    io::printf("%d+1=%d\n", 0, shift(0, -1));
    io::printf("%d+1=%d\n", 1, shift(1, -1));
    io::printf("%d+1=%d\n", 2, shift(2, -1));
    io::printf("%d+1=%d\n", 32766, shift(32766, -1));
    io::printf("%d+1=%d\n", 32767, shift(32767, -1));
    io::printf("%d+1=%d\n", -32767, shift(-32767, -1));
    io::printf("%d+1=%d\n", -32768, shift(-32768, -1));
}

Chování se opět může odlišovat podle toho, zda je překlad proveden v safe nebo unsafe režimu.

Použití safe režimu:

ERROR: 'Shift amount out of range (was 65535).'
  in std.core.builtin.default_panic (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:175) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in std.core.builtin.panicf (/home/ptisnovs/xy/c3c/build/lib/std/core/builtin.c3:231) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.shift (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/15_negative_shift.c3:6) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in undefined_behaviour.main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/15_negative_shift.c3:11) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in @main_to_void_main (/home/ptisnovs/xy/c3c/build/lib/std/core/private/main_stub.c3:18) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour] [inline]
  in main (/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/15_negative_shift.c3:9) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
  in __libc_start_call_main (source unavailable) [/lib64/libc.so.6]
  in __libc_start_main_alias_2 (source unavailable) [/lib64/libc.so.6]
  in _start (source unavailable) [/home/ptisnovs/src/c3-examples/c3-undefined-behaviour/undefined_behaviour]
Program interrupted by signal 4.

Použití unsafe režimu (může nastat cokoli):

0+1=0
1+1=0
2+1=0
32766+1=0
32767+1=0
-32767+1=0
-32768+1=0

18. Obsah navazující části

Ve skutečnosti je v jazyku C3 nedefinovaných chování větší množství. Zbylé z nich si popíšeme v navazujícím článku.

19. Repositář s demonstračními příklady

Demonstrační příklady vytvořené pro nejnovější verzi programovacího jazyka C3 byly uloženy do repositáře dostupného na adrese https://github.com/tisnik/c3-examples. Následují odkazy na jednotlivé příklady (či jejich nedokončené části).

Demonstrační příklady z prvního článku o programovacím jazyku C3:

# Příklad Stručný popis Adresa
1 factorial.c3 realizace výpočtu faktoriálu https://github.com/tisnik/c3-examples/blob/master/intro­duction/factorial.c3
2 factorial_macro.c3 výpočet faktoriálu konkrétní hodnoty implementovaný formou makra https://github.com/tisnik/c3-examples/blob/master/intro­duction/factorial_macro.c3
       
3 swap_macro.c3 makro realizující prohození dvou hodnot https://github.com/tisnik/c3-examples/blob/master/intro­duction/swap_macro.c3
       
4 renderer.c výpočet a vykreslení Juliovy množiny implementovaný v jazyku C https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer.c
5 renderer_v1.c3 definice datové struktury s rozměry rastrového obrázku a skeleton všech funkcí https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v1.c3
6 renderer_v2.c3 anotace parametrů funkcí typu ukazatel (pointer) https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v2.c3
7 renderer_v3.c3 statická kontrola, zda se nepředávají neinicializované ukazatele https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v3.c3
8 renderer_v4.c3 runtime kontrola, zda se nepředávají neinicializované ukazatele https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v4.c3
9 renderer_v5.c3 první (nekorektní) varianta funkce pro inicializaci barvové palety https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v5.c3
10 renderer_v6.c3 druhá (korektní) varianta funkce pro inicializaci barvové palety https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v6.c3
11 renderer_v7.c3 volání knihovní I/O funkce a volání nativní céčkovské funkce https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v7.c3
12 renderer_v8.c3 plně funkční program pro výpočet a vykreslení Juliovy množiny https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v8.c3

Demonstrační příklady ze druhého článku o jazyku C3:

# Příklad Stručný popis Adresa
13 01_just_main.c3 struktura nejjednoduššího programu obsahujícího pouze prázdnou funkci main https://github.com/tisnik/c3-examples/blob/master/c3-basics/01_just_main.c3
14 02_module_name.c3 struktura programu s uvedeným plným jménem modulu https://github.com/tisnik/c3-examples/blob/master/c3-basics/02_module_name.c3
15 03_hello_world.c3 klasický program typu „Hello, world!“ napsaný v jazyku C3 https://github.com/tisnik/c3-examples/blob/master/c3-basics/03_hello_world.c3
16 04_exit_value.c3 ukončení procesu s předáním návratového kódu zpět volajícímu programu https://github.com/tisnik/c3-examples/blob/master/c3-basics/04_exit_value.c3
17 05_c_function.c3 zavolání funkce definované v knihovně programovacího jazyka C https://github.com/tisnik/c3-examples/blob/master/c3-basics/05_c_function.c3
       
18 06_bool_type.c3 definice proměnných typu pravdivostní hodnota (bool) https://github.com/tisnik/c3-examples/blob/master/c3-basics/06_bool_type.c3
19 07_int_to_bool.c3 implicitní převod hodnoty typu int na pravdivostní hodnotu (nekorektní řešení) https://github.com/tisnik/c3-examples/blob/master/c3-basics/07_int_to_bool.c3
20 08_int_to_bool.c3 explicitní převod hodnoty typu int na pravdivostní hodnotu (korektní řešení) https://github.com/tisnik/c3-examples/blob/master/c3-basics/08_int_to_bool.c3
21 09_int_to_bool.c3 explicitní převod hodnoty typu int na pravdivostní hodnotu (nekorektní řešení) https://github.com/tisnik/c3-examples/blob/master/c3-basics/09_int_to_bool.c3
22 10_bool_sizeof.c3 zjištění velikosti paměti obsazené hodnotou typu bool https://github.com/tisnik/c3-examples/blob/master/c3-basics/10_bool_sizeof.c3
       
23 11_int_types.c3 definice proměnných typu celé číslo se znaménkem s různou bitovou šířkou https://github.com/tisnik/c3-examples/blob/master/c3-basics/11_int_types.c3
24 12_uint_types.c3 definice proměnných typu celé číslo bez znaménka s různou bitovou šířkou https://github.com/tisnik/c3-examples/blob/master/c3-basics/12_uint_types.c3
25 13_no_suffixes.c3 celočíselné konstanty bez uvedení suffixu (bitové šířky) https://github.com/tisnik/c3-examples/blob/master/c3-basics/13_no_suffixes.c3
26 14_suffixes.c3 celočíselné konstanty s uvedením sufficu (bitové šířky) https://github.com/tisnik/c3-examples/blob/master/c3-basics/14_suffixes.c3
27 15_int_sizeof.c3 zjištění velikosti paměti obsazené celočíselnými hodnotami se znaménkem https://github.com/tisnik/c3-examples/blob/master/c3-basics/15_int_sizeof.c3
28 16_uint_sizeof.c3 zjištění velikosti paměti obsazené celočíselnými hodnotami bez znaménka https://github.com/tisnik/c3-examples/blob/master/c3-basics/16_uint_sizeof.c3
29 17_int_conversions.c3 korektní převody mezi celočíselnými hodnotami s různou bitovou šířkou https://github.com/tisnik/c3-examples/blob/master/c3-basics/17_int_conversions.c3
30 18_int_conversions.c3 nekorektní převody mezi celočíselnými hodnotami s různou bitovou šířkou https://github.com/tisnik/c3-examples/blob/master/c3-basics/18_int_conversions.c3
31 19_int_conversions.c3 explicitní převody a přetečení hodnot https://github.com/tisnik/c3-examples/blob/master/c3-basics/19_int_conversions.c3
       
32 20_float_types.c3 definice proměnných typu numerická hodnota s plovoucí řádovou čárkou (tečkou) https://github.com/tisnik/c3-examples/blob/master/c3-basics/20_float_types.c3
       
33 21_vector_type.c3 definice vektoru obsahujícího celočíselné hodnoty https://github.com/tisnik/c3-examples/blob/master/c3-basics/21_vector_type.c3
34 22_vector_operations.c3 základní operace s celými vektory https://github.com/tisnik/c3-examples/blob/master/c3-basics/22_vector_operations.c3
35 23_vector_sizes.c3 zjištění a tisk velikosti vektorů (různé datové typy prvků vektorů, shodná délka) https://github.com/tisnik/c3-examples/blob/master/c3-basics/23_vector_sizes.c3
36 24_vector_sizes.c3 zjištění a tisk velikosti vektorů (stejné datové typy prvků vektorů, odlišná délka) https://github.com/tisnik/c3-examples/blob/master/c3-basics/24_vector_sizes.c3

Demonstrační příklady použité ve třetím článku o jazyku C3:

# Příklad Stručný popis Adresa
37 01_vector_type.c3 definice vektoru, modifikace prvků vektoru, tisk obsahu celého vektoru https://github.com/tisnik/c3-examples/blob/master/c3-containers/01_vector_type.c3
38 02_vector_parameter.c3 předání vektoru do funkce hodnotou https://github.com/tisnik/c3-examples/blob/master/c3-containers/02_vector_parameter.c3
39 03_vector_pointer.c3 předání vektoru do funkce odkazem (přes ukazatel) https://github.com/tisnik/c3-examples/blob/master/c3-containers/03_vector_pointer.c3
       
40 04_array_type.c3 definice pole, modifikace prvků pole, tisk obsahu celého pole https://github.com/tisnik/c3-examples/blob/master/c3-containers/04_array_type.c3
41 05_array_parameter.c3 předání pole do funkce hodnotou https://github.com/tisnik/c3-examples/blob/master/c3-containers/05_array_parameter.c3
42 06_array_pointer.c3 předání pole do funkce odkazem (přes ukazatel) https://github.com/tisnik/c3-examples/blob/master/c3-containers/06_array_pointer.c3
       
43 07_slice_type.c3 vytvoření (konstrukce) řezu (slice) https://github.com/tisnik/c3-examples/blob/master/c3-containers/07_slice_type.c3
44 08_slice_parameter.c3 předání řezu do funkce https://github.com/tisnik/c3-examples/blob/master/c3-containers/08_slice_parameter.c3
45 09_slice_slicing.c3 konstrukce řezu z pole stejně pojmenovanou operací (řez od..do) https://github.com/tisnik/c3-examples/blob/master/c3-containers/09_slice_slicing.c3
46 10_slice_slicing.c3 konstrukce řezu z pole stejně pojmenovanou operací (záporné indexy) https://github.com/tisnik/c3-examples/blob/master/c3-containers/10_slice_slicing.c3
47 11_slice_slicing.c3 konstrukce řezu z pole stejně pojmenovanou operací (určení délky řezu) https://github.com/tisnik/c3-examples/blob/master/c3-containers/11_slice_slicing.c3
48 12_slice_of_slice.c3 konstrukce řezu z jiného řezu https://github.com/tisnik/c3-examples/blob/master/c3-containers/12_slice_of_slice.c3
       
49 13_list_type.c3 vytvoření (konstrukce) seznamu https://github.com/tisnik/c3-examples/blob/master/c3-containers/13_list_type.c3
50 14_list_parameter.c3 předání seznamu do funkce https://github.com/tisnik/c3-examples/blob/master/c3-containers/14_list_parameter.c3
       
51 15_dynamic_array.c3 vytvoření (konstrukce) dynamicky alokovaného pole https://github.com/tisnik/c3-examples/blob/master/c3-containers/15_dynamic_array.c3
       
52 16_string_type.c3 základní typ řetězce string https://github.com/tisnik/c3-examples/blob/master/c3-containers/16_string_type.c3
53 17_string_unicode.c3 Unicode znaky v řetězci typu string https://github.com/tisnik/c3-examples/blob/master/c3-containers/17_string_unicode.c3
54 18_zstring_type.c3 řetězce ukončené nulou (C-string, ASCIIZ) https://github.com/tisnik/c3-examples/blob/master/c3-containers/18_zstring_type.c3
55 19_zstring_unicode.c3 Unicode znaky v řetězci typu zstring https://github.com/tisnik/c3-examples/blob/master/c3-containers/19_zstring_unicode.c3
56 20_string_comparison.c3 porovnávání obsahu řetězců https://github.com/tisnik/c3-examples/blob/master/c3-containers/20_string_comparison.c3

Demonstrační příklady ze čtvrtého o jazyku C3:

# Příklad Stručný popis Adresa
57 01_program_stub.c3 struktura programu s uvedeným plným jménem modulu https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/01_program_stub.c3
       
58 02_if.c3 nejjednodušší forma rozvětvení založené na konstrukci if https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/02_if.c3
59 03_if_else.c3 plné rozvětvení realizované konstrukcí if-else https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/03_if_else.c3
60 04_improper_if.c3 nekorektní způsob zápisu programové konstrukce if-else (porovnání s jazykem C) https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/04_improper_if.c3
61 05_improper_if.c3 nekorektní způsob zápisu programové konstrukce if-else (porovnání s jazykem C) https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/05_improper_if.c3
62 06_if_else_if.c3 složitější rozvětvení založené na programové konstrukci if-else if-else https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/06_if_else_if.c3
       
63 07_switch_basic.c3 základní forma vícenásobného rozvětvení založeného na konstrukci switch-case https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/07_switch_basic.c3
64 08_switch_basic.c3 větší množství podmínek a programová konstrukce switch-case https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/08_switch_basic.c3
65 09_switch_condition.c3 podmínky zapsané ve větvích programové konstrukci switch-case vyhodnocované v čase běhu procesu https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/09_switch_condition.c3
66 10_switch_true.c3 konstrukce switch-case bez uvedeného výrazu za klíčovým slovem switch https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/10_switch_true.c3
67 11_switch_break.c3 zápis prázdné větve default v programové konstrukci switch-case https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/11_switch_break.c3
68 12_switch_nextcase.c3 pokračování ve vykonávání konstrukce switch-case vynucené klíčovým slovem nextcase https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/12_switch_nextcase.c3
       
69 13_for_loop.c3 základní forma programové smyčky realizované klíčovým slovem for https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/13_for_loop.c3
70 14_foreach_loop.c3 základní forma programové smyčky typu for-each https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/14_foreach_loop.c3
71 15_foreach_loop.c3 programová smyčka for-each vracející index prvku i hodnotu prvku https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/15_foreach_loop.c3
72 16_foreach_loop.c3 modifikace obsahu pole v programové smyčce for-each https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/16_foreach_loop.c3
73 17_foreach_loop.c3 pokus o modifikaci obsahu procházeného pole https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/17_foreach_loop.c3
74 18_foreach_loop.c3 modifikace procházeného pole přes ukazatel na prvek https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/18_foreach_loop.c3
75 19_foreach_r_loop.c3 programová smyčka for-each, ve které se sekvencí prochází v opačném pořadí https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/19_foreach_r_loop.c3
       
76 20_while_loop.c3 základní forma programové smyčky typu while https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/20_while_loop.c3
77 21_while_loop2.c3 programová smyčka typu while s konstrukcí break https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/21_while_loop2.c3
78 22_nested_loops.c3 realizace vnořených programových smyček https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/22_nested_loops.c3
79 23_break.c3 vnořené programové smyčky a příkaz break: ukončení vnitřní smyčky https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/23_break.c3
80 24_break.c3 vnořené programové smyčky a příkaz break: ukončení vnější smyčky https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/24_break.c3
81 25_break.c3 vnořené programové smyčky a příkaz break, varianta se smyčkami typu while https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/25_break.c3

Demonstrační příklady z pátého článku o jazyku C3:

# Příklad Stručný popis Adresa
82 01_regular_variable.c3 definice běžné proměnné typu int, přístup k hodnotě této proměnné https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/01_regular_variable.c3
83 02_optional_value.c3 definice proměnné typu Optional int, pokus o přímý přístup k hodnotě této proměnné (nekorektní varianta) https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/02_optional_value.c3
84 03_optional_value.c3 korektní čtení proměnné typu Optional int s detekcí chyby https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/03_optional_value.c3
85 04_optional_value.c3 korektní čtení proměnné typu Optional int s detekcí chyby https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/04_optional_value.c3
86 05_fault.c3 uživatelsky definovaný typ nesoucí informaci o chybě https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/05_fault.c3
87 06_fault.c3 uživatelsky definovaný typ nesoucí informaci o chybě https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/06_fault.c3
88 07_force_unwrap.c3 použití operátoru !! (force unwrap) https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/07_force_unwrap.c3
89 08_force_unwrap.c3 použití operátoru !! (force unwrap) https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/08_force_unwrap.c3
       
90 09_factorial.c3 běžný výpočet faktoriálu bez reakce na neplatný vstup https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/09_factorial.c3
91 10_factorial.c3 výpočet faktoriálu s reakcí na neplatný vstup – řešení bez kontroly návratové hodnoty https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/10_factorial.c3
92 11_factorial.c3 výpočet faktoriálu s reakcí na neplatný vstup – řešení s kontrolou návratové hodnoty https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/11_factorial.c3
       
93 12_defer_basic_usage.c3 konstrukce defer v programovacím jazyce C3 https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/12_defer_basic_usage.c3
94 13_more_defers.c3 pořadí provádění příkazů v blocích defer https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/13_more_defers.c3
95 14_defer_scope.c3 konstrukce defer definovaná ve vnitřních blocích v jazyce C3 https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/14_defer_scope.c3
96 15_defer_return.c3 konstrukce defer a return https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/15_defer_return.c3
       
97 16_init_finalize.c3 funkce označené jako @init a @finalizer https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/16_init_finalize.c3
       
98 defer.go konstrukce defer v programovacím jazyce Go https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/defer.go
99 defer_scope.go konstrukce defer definovaná ve vnitřních blocích v jazyce Go https://github.com/tisnik/c3-examples/blob/master/c3-errors-handling/defer_scope.go

Následují odkazy na demonstrační příklady z článku předchozího:

# Příklad Stručný popis Adresa
100 01_regular_function.c3 deklarace běžných funkcí v jazyku C3 https://github.com/tisnik/c3-examples/blob/master/c3-functions/01_regular_function.c3
101 02_check_arguments.c3 kontrola parametrů předávaných do funkce překladačem jazyka C3 https://github.com/tisnik/c3-examples/blob/master/c3-functions/02_check_arguments.c3
       
102 03_default_arguments.c3 funkce s jedním parametrem, který má nastavenou výchozí hodnotu a jedním běžným parametrem (korektní pořadí parametrů) https://github.com/tisnik/c3-examples/blob/master/c3-functions/03_default_arguments.c3
103 04_default_arguments.c3 funkce se všemi parametry s nastavenu výchozí hodnotou https://github.com/tisnik/c3-examples/blob/master/c3-functions/04_default_arguments.c3
104 05_default_arguments.c3 funkce s jedním parametrem, který má nastavenou výchozí hodnotu a jedním běžným parametrem (nekorektní pořadí parametrů) https://github.com/tisnik/c3-examples/blob/master/c3-functions/05_default_arguments.c3
       
105 06_named_arguments.c3 explicitní uvedení jmen parametrů při volání funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/06_named_arguments.c3
106 07_named_arguments.c3 explicitní uvedení jmen parametrů při volání funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/07_named_arguments.c3
107 08_named_default_arguments.c3 pojmenování parametrů s výchozí hodnotou při volání funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/08_named_default_ar­guments.c3
       
108 09_sum.c3 realizace funkce pro výpočet součtu všech předaných hodnot https://github.com/tisnik/c3-examples/blob/master/c3-functions/09_sum.c3
109 10_sum.c3 předání obsahu pole do funkce s proměnným počtem parametrů https://github.com/tisnik/c3-examples/blob/master/c3-functions/10_sum.c3
110 11_varargs.c3 pořadí předávání parametrů do funkce s proměnným počtem parametrů (nekorektní způsob použití) https://github.com/tisnik/c3-examples/blob/master/c3-functions/11_varargs.c3
111 12_varargs.c3 pořadí předávání parametrů do funkce s proměnným počtem parametrů (korektní způsob použití) https://github.com/tisnik/c3-examples/blob/master/c3-functions/12_varargs.c3
       
112 13_optional.c3 funkce vracející hodnotu typu Optional https://github.com/tisnik/c3-examples/blob/master/c3-functions/13_optional.c3
113 14_optional.c3 využití operátoru ?? https://github.com/tisnik/c3-examples/blob/master/c3-functions/14_optional.c3
       
114 15_contract.c3 kontrakty uvedené u funkcí https://github.com/tisnik/c3-examples/blob/master/c3-functions/15_contract.c3
115 16_contract.c3 kontrakty uvedené u funkcí https://github.com/tisnik/c3-examples/blob/master/c3-functions/16_contract.c3
       
116 17_c_declaration.c3 deklarace funkce bez parametrů „céčkovým způsobem“ (nekorektní zápis) https://github.com/tisnik/c3-examples/blob/master/c3-functions/17_c_declaration.c3
117 18_check_return_type.c3 kontrola návratové hodnoty překladačem jazyka C3 https://github.com/tisnik/c3-examples/blob/master/c3-functions/18_check_return_type.c3
118 19_check_return_value.c3 kontrola počtu návratových hodnot překladačem jazyka C3 https://github.com/tisnik/c3-examples/blob/master/c3-functions/19_check_return_value.c3
119 20_in_out_params.c3 předání ukazatelů do volané funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/20_in_out_params.c3
120 21_in_out_params.c3 označení ukazatelů kontrakty [in] a [out] https://github.com/tisnik/c3-examples/blob/master/c3-functions/21_in_out_params.c3
121 22_in_out_params.c3 označení ukazatelů kontrakty [in] a [out] https://github.com/tisnik/c3-examples/blob/master/c3-functions/22_in_out_params.c3
122 23_void_pointer.c3 předávání ukazatelů typu void * do volané funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/23_void_pointer.c3
123 24_contract.c3 kontrakt zapsaný před hlavičkou funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/24_contract.c4

Demonstrační příklady z předchozího článku o funkcích v C3:

Školení Zabbix

# Příklad Stručný popis Adresa
124 25_function_type.c3 definice nového datového typu „funkce“ https://github.com/tisnik/c3-examples/blob/master/c3-functions/25_function_type.c3
       
125 26_short_function.c3 zkrácený způsob zápisu běžné funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/26_short_function.c3
126 27_short_default_argument.c3 zkrácený způsob zápisu funkce s výchozí hodnotou parametru https://github.com/tisnik/c3-examples/blob/master/c3-functions/27_short_default_argument.c3
127 28_short_default_argument.c3 zkrácený způsob zápisu funkce s výchozí hodnotou parametrů https://github.com/tisnik/c3-examples/blob/master/c3-functions/28_short_default_argument.c3
128 29_short_named_argument.c3 zkrácený způsob zápisu funkce, při jejím volání jsou explicitně uvedena jména parametrů https://github.com/tisnik/c3-examples/blob/master/c3-functions/29_short_named_argument.c3
129 30_short_first.c3 zkrácený způsob zápisu funkce akceptující proměnný počet parametrů https://github.com/tisnik/c3-examples/blob/master/c3-functions/30_short_first.c3
130 31_short_ternary.c3 zkrácený způsob zápisu funkce, která ve svém těle vyžaduje ternární operátor https://github.com/tisnik/c3-examples/blob/master/c3-functions/31_short_ternary.c3
       
131 32_anonymous.c3 příklad, v němž jsou definovány dvě logicky podobné funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/32_anonymous.c3
132 33_anonymous.c3 využití anonymních funkcí namísto dvojice logicky podobných funkcí https://github.com/tisnik/c3-examples/blob/master/c3-functions/33_anonymous.c3
133 34_anonymous.c3 definice a zavolání anonymní funkce provedené na jediném řádku zdrojového kódu https://github.com/tisnik/c3-examples/blob/master/c3-functions/34_anonymous.c3
134 35_anonymous.c3 pokus o definici uzávěru (closure) https://github.com/tisnik/c3-examples/blob/master/c3-functions/35_anonymous.c3
       
135 36_function_pointers.c3 předání ukazatele na funkce https://github.com/tisnik/c3-examples/blob/master/c3-functions/36_function_pointers.c3
136 37_function_pointers.c3 předání ukazatele na funkce (zkrácený zápis funkce) https://github.com/tisnik/c3-examples/blob/master/c3-functions/37_function_pointers.c3
137 38_return_function.c3 funkce vracející jinou funkci https://github.com/tisnik/c3-examples/blob/master/c3-functions/38_return_function.c3
       
138 39_call_c_function.c3 volání standardní céčkové funkce puts https://github.com/tisnik/c3-examples/blob/master/c3-functions/39_call_c_function.c3
139 40_call_c_function.c3 volání nativní céčkové funkce add https://github.com/tisnik/c3-examples/blob/master/c3-functions/40_call_c_function.c3
140 41_call_c_function.c3 volání nativní céčkové funkce multiply s korektními datovými typy https://github.com/tisnik/c3-examples/blob/master/c3-functions/41_call_c_function.c3
141 42_call_c_function.c3 volání nativní céčkové funkce akceptující pole (první způsob) https://github.com/tisnik/c3-examples/blob/master/c3-functions/42_call_c_function.c3
142 43_call_c_function.c3 volání nativní céčkové funkce akceptující pole (druhý způsob) https://github.com/tisnik/c3-examples/blob/master/c3-functions/43_call_c_function.c3
141 42_call_c_function.c3 volání nativní céčkové funkce akceptující pole (první způsob) https://github.com/tisnik/c3-examples/blob/master/c3-functions/42_call_c_function.c3
       
143 44_method.c3 zavolání metody (první způsob) https://github.com/tisnik/c3-examples/blob/master/c3-functions/44_method.c3
144 45_method.c3 zavolání metody (druhý způsob) https://github.com/tisnik/c3-examples/blob/master/c3-functions/45_method.c3

Příklady z předchozího článku s popisem makrosystému jazyka C3:

# Příklad Stručný popis Adresa
145 01_add_macro.c3 jednoduché makro, které může být expandováno v rámci výrazu https://github.com/tisnik/c3-examples/blob/master/c3-macros/01_add_macro.c3
146 02_add_macro.c3 makro je generické, lze použít s hodnotami různých typů https://github.com/tisnik/c3-examples/blob/master/c3-macros/02_add_macro.c3
       
147 03_macro_expansion1.c expanze makro provedená preprocesorem jazyka C (parametry nejsou uzávorkovány) https://github.com/tisnik/c3-examples/blob/master/c3-macros/03_macro_expansion1.c
148 03_macro_expansion2.c expanze makro provedená preprocesorem jazyka C (parametry jsou uzávorkovány) https://github.com/tisnik/c3-examples/blob/master/c3-macros/03_macro_expansion2.c
149 03_macro_expansion.c3 řešení v jazyku C3 bez nutnosti uzávorkování parametrů makra https://github.com/tisnik/c3-examples/blob/master/c3-macros/03_macro_expansion.c3
150 04_macro_expansion1.c expanze makro provedená preprocesorem jazyka C (tělo makra není v závorkách) https://github.com/tisnik/c3-examples/blob/master/c3-macros/04_macro_expansion1.c
151 04_macro_expansion2.c expanze makro provedená preprocesorem jazyka C (tělo makra je v závorkách) https://github.com/tisnik/c3-examples/blob/master/c3-macros/04_macro_expansion2.c
152 04_macro_expansion.c3 řešení v jazyku C3 bez nutnosti zápisu těla makra do závorek https://github.com/tisnik/c3-examples/blob/master/c3-macros/04_macro_expansion.c3
       
153 05_typed_macro.c3 makro s definicí typů parametrů https://github.com/tisnik/c3-examples/blob/master/c3-macros/05_typed_macro.c3
154 06_typed_macro.c3 makro s definicí typů parametrů: příklad jeho expanze https://github.com/tisnik/c3-examples/blob/master/c3-macros/06_typed_macro.c3
       
155 07_compile_time1.c3 expanze makra v čase překladu: nefunkční varianta s konstantami https://github.com/tisnik/c3-examples/blob/master/c3-macros/07_compile_time1.c3
156 08_compile_time2.c3 expanze makra v čase překladu: funkční varianta s konstantami https://github.com/tisnik/c3-examples/blob/master/c3-macros/08_compile_time2.c3
157 09_compile_time3.c3 expanze makra v čase překladu: nefunkční varianta s proměnnými https://github.com/tisnik/c3-examples/blob/master/c3-macros/09_compile_time3.c3
       
158 10_swap_macro1.c3 realizace makra pro prohození obsahu dvou proměnných: nefunkční varianta https://github.com/tisnik/c3-examples/blob/master/c3-macros/10_swap_macro1.c3
159 11_swap_macro2.c3 realizace makra pro prohození obsahu dvou proměnných: funkční varianta https://github.com/tisnik/c3-examples/blob/master/c3-macros/11_swap_macro2.c3
       
160 12_varargs.c3 makro s proměnným počtem argumentů https://github.com/tisnik/c3-examples/blob/master/c3-macros/12_varargs.c3

Demonstrační příklady uvedené v dnešním článku:

# Příklad Stručný popis Adresa
161 01_div_by_zero.c3 nedefinované chování při dělení nulou https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/01_div_by_zero.c3
162 02_mod_by_zero.c3 nedefinované chování při výpočtu zbytku po dělení nulou https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/02_mod_by_zero.c3
163 03_min_int1.c3 změna znaménka nejmenší celočíselné hodnoty (daného typu) se znaménkem https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/03_min_int1.c3
164 04_min_int2.c3 změna znaménka nejmenší celočíselné hodnoty operací součinu https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/04_min_int2.c3
165 05_undefined_value.c3 nedefinované hodnoty lokálních konstant v různých režimech překladu https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/05_undefined_value.c3
166 06_out_of_bounds1.c3 přístup k prvku pole s indexem, který přesahuje meze pole https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/06_out_of_bounds1.c3
167 07_out_of_bounds2.c3 přístup k prvku pole s indexem, který přesahuje meze pole https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/07_out_of_bounds2.c3
168 08_null_pointer.c3 přístup do paměti přes nulový ukazatel https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/08_null_pointer.c3
169 09_contract.c3 nedodržení specifikovaného kontraktu: podmínka pro vstupní parametry https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/09_contract.c3
170 10_contract.c3 nedodržení specifikovaného kontraktu: podmínka pro výslednou hodnotu https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/10_contract.c3
171 11_out_of_bounds_slice.c3 překročení meze u řezů (slice) https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/11_out_of_bounds_slice.c3
172 12_local_variable_pointer.c přístup k lokální proměnné mimo oblast její platnosti (příklad v C) https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/12_local_variable_pointer.c
173 12_local_variable_pointer.c3 přístup k lokální proměnné mimo oblast její platnosti (příklad v C3) https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/12_local_variable_pointer.c3
174 13_div_by_minus_one.c3 změna znaménka nejmenší celočíselné hodnoty operací podílu https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/13_div_by_minus_one.c3
175 14_signed_overflow.c3 přetečení celočíselné hodnoty se znaménkem https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/14_signed_overflow.c3
176 15_negative_shift.c3 bitový posun o zápornou hodnotu https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/15_negative_shift.c3
177 16_large_shift.c3 bitový posun o hodnotu přesahující bitovou šířku operandu https://github.com/tisnik/c3-examples/blob/master/c3-undefined-behaviour/16_large_shift.c3

20. Odkazy na Internetu

  1. Programovací jazyk C3: evoluce, nikoli revoluce
    https://www.root.cz/clanky/pro­gramovaci-jazyk-c3-evoluce-nikoli-revoluce/
  2. Programovací jazyk C3: datové typy pro moderní architektury
    https://www.root.cz/clanky/pro­gramovaci-jazyk-c3-datove-typy-pro-moderni-architektury/
  3. Programovací jazyk C3: složené datové typy a kontejnery
    https://www.root.cz/clanky/pro­gramovaci-jazyk-c3-slozene-datove-typy-a-kontejnery/
  4. The C3 Programming Language
    https://c3-lang.org/
  5. C3 For C Programmers
    https://c3-lang.org/language-overview/primer/
  6. C3 is a C-like language trying to be an incremental improvement over C rather than a whole new language
    https://www.reddit.com/r/Pro­grammingLanguages/comments/o­ohij6/c3_is_a_clike_langu­age_trying_to_be_an/
  7. Tiobe index
    https://www.tiobe.com/tiobe-index/
  8. PYPL PopularitY of Programming Language
    https://pypl.github.io/PYPL.html
  9. C3 Tutorial
    https://learn-c3.org/
  10. History of programming languages
    https://devskiller.com/history-of-programming-languages/
  11. History of programming languages (Wikipedia)
    https://en.wikipedia.org/wi­ki/History_of_programming_lan­guages
  12. D language
    https://dlang.org/
  13. Zig programming language
    https://ziglang.org/
  14. V language
    https://vlang.io/
  15. D programming language
    https://en.wikipedia.org/wi­ki/D_(programming_language)
  16. Zig programming language (Wikipedia)
    https://en.wikipedia.org/wi­ki/Zig_(programming_langu­age)
  17. V programming language (Wikipedia)
    https://en.wikipedia.org/wi­ki/V_(programming_language)
  18. Syntax highlighting for C3's programming language
    https://github.com/Airbus5717/c3.vim
  19. Go factorial
    https://gist.github.com/e­simov/9622710
  20. Generational list of programming languages
    https://en.wikipedia.org/wi­ki/Generational_list_of_pro­gramming_languages
  21. The Language Tree: Almost Every Programming Language Ever Made
    https://github.com/Phileo­sopher/langmap
  22. List of C-family programming languages
    https://en.wikipedia.org/wi­ki/List_of_C-family_programming_languages
  23. Compatibility of C and C++
    https://en.wikipedia.org/wi­ki/Compatibility_of_C_and_C%2B%2B
  24. C++23: compatibility with C
    https://www.sandordargo.com/blog/2023/08/23/cpp­23-c-compatibility
  25. Can C++ Run C Code? Understanding Language Compatibility
    https://www.codewithc.com/can-c-run-c-code-understanding-language-compatibility/
  26. C3: Comparisons With Other Languages
    https://c3-lang.org/faq/compare-languages/
  27. C3 Programming Language Gains Traction as Modern C Alternative
    https://biggo.com/news/202504040125_C3_Pro­gramming_Language_Alterna­tive_to_C
  28. The case against a C alternative
    https://c3.handmade.networ­k/blog/p/8486-the_case_against_a_c_alternative
  29. C (programming language) Alternatives
    https://alternativeto.net/software/c-programming-language-/
  30. Seriál Programovací jazyk Go
    https://www.root.cz/seria­ly/programovaci-jazyk-go/
  31. Is C3 the Underdog That Will Overtake Zig and Odin?
    https://bitshifters.cc/2025/05/22/c3-c-tradition.html
  32. „Hello, World!“ program
    https://en.wikipedia.org/wi­ki/%22Hello%2C_World!%22_pro­gram
  33. The C Programming Language
    https://en.wikipedia.org/wi­ki/The_C_Programming_Langu­age
  34. Kontejner (abstraktní datový typ)
    https://cs.wikipedia.org/wi­ki/Kontejner_(abstraktn%C3%AD_da­tov%C3%BD_typ)
  35. Are arrays not considered containers because they are not based off of a class?
    https://stackoverflow.com/qu­estions/37710975/are-arrays-not-considered-containers-because-they-are-not-based-off-of-a-class
  36. Array declaration (C, C++)
    https://en.cppreference.com/w/cpp/lan­guage/array.html
  37. Understanding the Apple ‘goto fail;’ vulnerability
    https://www.blackduck.com/blog/un­derstanding-apple-goto-fail-vulnerability-2.html
  38. Branch (computer science)
    https://en.wikipedia.org/wi­ki/Branch_(computer_scien­ce)
  39. Conditional (computer programming)
    https://en.wikipedia.org/wi­ki/Conditional_(computer_pro­gramming)
  40. Dangling else
    https://en.wikipedia.org/wi­ki/Dangling_else
  41. Switch statement
    https://en.wikipedia.org/wi­ki/Switch_statement
  42. Compiler correctness
    https://en.wikipedia.org/wi­ki/Compiler_correctness
  43. Anonymous function
    https://en.wikipedia.org/wi­ki/Anonymous_function
  44. Closure (computer programming)
    https://en.wikipedia.org/wi­ki/Closure_(computer_program­ming)
  45. How to implement closures in C
    https://hokstad.com/how-to-implement-closures
  46. An Overview of Macros in Rust
    http://words.steveklabnik.com/an-overview-of-macros-in-rust
  47. A Practical Intro to Macros in Rust 1.0
    https://danielkeep.github.io/practical-intro-to-macros.html
  48. The Rust Programming Language: macros
    https://doc.rust-lang.org/beta/book/macros.html
  49. Rust by example: 15 macro_rules!
    http://rustbyexample.com/macros.html
  50. Undefined behavior
    https://en.wikipedia.org/wi­ki/Undefined_behavior
  51. Undefined Behavior in C and C++
    https://www.geeksforgeeks­.org/cpp/undefined-behavior-c-cpp/
  52. The Rust reference: Behavior considered undefined
    https://doc.rust-lang.org/reference/behavior-considered-undefined.html#behavior-considered-undefined
  53. Why would a language have a concept of undefined behavior instead of raising an error?
    https://langdev.stackexchan­ge.com/questions/481/why-would-a-language-have-a-concept-of-undefined-behavior-instead-of-raising-an
  54. Undefined behavior
    https://riptutorial.com/c/to­pic/364/undefined-behavior
  55. C3: Undefined Behaviour
    https://c3-lang.org/language-rules/undefined-behaviour/
  56. Undefined behavior in C and C++
    https://russellw.github.io/undefined-behavior
Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.