From 4227d52f23d65a4f6d0c811cbda34db30d0d6980 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Thu, 9 Apr 2026 16:11:56 +0200 Subject: [PATCH] ch2 env --- ch002-env.md | 262 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 ch002-env.md diff --git a/ch002-env.md b/ch002-env.md new file mode 100644 index 0000000..3e6b8bf --- /dev/null +++ b/ch002-env.md @@ -0,0 +1,262 @@ +# Chapitre 2 — Environnements et portabilité + +## 2.1 C hébergé vs C freestanding + +Il existe deux modes d’exécution du C. + +Un environnement hébergé fournit : +- un OS +- une libc complète +- un point d’entrée `main` + +```c +#include + +int main(void) +{ + printf("Hello\n"); + return 0; +} +``` + +Un environnement freestanding est minimal. + +```c +void start(void) +{ + // code bas niveau +} +``` + +--- + +## 2.2 Plateformes + +Linux, Windows, macOS ont des APIs différentes. +Un programme C peut s’exécuter sur plusieurs systèmes. +Mais tous les systèmes sont différents. +--- +- Linux + - API POSIX + - forte portabilité + - outils standards +--- +- macOS + - basé sur UNIX + - proche de POSIX + - spécificités Apple +--- +- Windows + - API spécifique (WinAPI) + - comportement différent sur certains points + - pas POSIX natif +--- +- Android + - basé sur Linux + - libc spécifique (Bionic) + - contraintes mobiles +--- +- Embarqué + - pas d’OS ou OS minimal + - ressources limitées + - accès direct au matériel + +--- + +## 2.3 Architecture vs système + +Un programme dépend de plusieurs couches. + +Il faut distinguer : + +- architecture (CPU) +- système (OS) +- compilateur + +--- + +🔹 Architecture + +Exemples : + +- x86 +- x86_64 +- ARM +- RISC-V + +Chaque architecture : + +- a ses registres +- son alignement +- son endianness + +--- + +🔹 Système + +Le système fournit : + +- fichiers +- processus +- mémoire + +--- + +🔹 Compilateur + +Il traduit le code C en binaire. + +Exemples : + +- gcc +- clang +- compilateurs embarqués + +--- + +## 2.4 Endianness + +L’endianness définit l’ordre des octets en mémoire. + +🔹 Little endian + +Octet faible en premier. + +🔹 Big endian + +Octet fort en premier. + +--- + +Exemple : + +```c +#include + +int main(void) +{ + int x = 0x12345678; + unsigned char *p = (unsigned char*)&x; + + printf("%02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]); +} +``` + +Le résultat dépend de l’architecture. + +--- + +## 2.5 Taille des types + +La taille des types n’est pas fixe. + +--- + +Exemple : + +```c +#include + +int main(void) +{ + printf("%zu\n", sizeof(int)); +} +``` + +--- + +## 2.6 Ce qui est portable + +Code portable : + +- respecte la norme +- évite les extensions +- évite les hypothèses + +--- + +Exemple — non portable + +```c +int main(void) +{ + int x = 2147483647 + 1; // overflow + + return 0; +} +``` + +Le comportement n’est pas défini. + +--- + +Exemple — portable + +```c +#include + +int main(void) +{ + int32_t x = 2147483647; + + return 0; +} +``` + +--- + +## 2.7 Dépendances système + +Certains appels dépendent du système. + +--- + +Exemple : + +```c +#include + +int main(void) +{ + system("ls"); // Linux uniquement + + return 0; +} +``` + +--- + +## 2.8 Abstraction + + +Pour être portable, il faut abstraire. + +Cela signifie : + +- isoler le code dépendant +- utiliser des interfaces + +-- + +Exemple : + +```c +void afficher_message(void) +{ +#ifdef _WIN32 + // Code Windows +#else + // Code Linux ? +#endif +} +``` + +--- + +## 2.9 Bonnes pratiques + +- utiliser +- éviter les tailles implicites +- éviter UB +- tester sur plusieurs plateformes +- isoler le code système