Files
Cours-C/ch002-env.md

264 lines
3.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Chapitre 2 — Environnements et portabilité
## 2.1 C hébergé vs C freestanding
Il existe deux modes dexécution du C.
Un environnement hébergé fournit :
- un OS
- une libc complète
- un point dentrée `main`
```c
#include <stdio.h>
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 sexé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 dOS 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
Lendianness définit lordre des octets en mémoire.
🔹 Little endian
Octet faible en premier.
🔹 Big endian
Octet fort en premier.
---
Exemple :
```c
#include <stdio.h>
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 larchitecture.
---
## 2.5 Taille des types
La taille des types nest pas fixe.
---
Exemple :
```c
#include <stdio.h>
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 nest pas défini.
---
Exemple — portable
```c
#include <stdint.h>
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 <stdlib.h>
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 <stdint.h>
- éviter les tailles implicites
- éviter UB
- tester sur plusieurs plateformes
- isoler le code système