Pourquoi le C++ pour les Tech Artists ?
En tant que Technical Artist, le C++ vous offre :
Performance : Le C++ est le langage qui fait tourner les moteurs de jeu. Quand les Blueprints sont trop lents, le C++ est la solution.
Accès à Unreal : Accès direct aux systèmes sous-jacents d’UE5 — des choses que vous ne pouvez tout simplement pas faire depuis les Blueprints.
Standard de l’industrie : Tous les grands studios de jeux vidéo utilisent le C++. C’est la lingua franca du développement de jeux.
**Rust, Zig, Carbon, Verse **? L’avenir nous dira quel sera le langage temps-réel qui remplacera C++. Rust semble avoir une belle longueur d’avance, à telle enseigne que Microsoft, Linus Torvald (Linux Kernel), Chromium, Android, et d’autres réécrivent une partie de leur vieux codebase en Rust. Yazi est un Terminal Based File manager extrêmement rapide écrit en Rust. Rust est le candidat le plus sérieux pour remplacer C++ dans ses bastions historiques (systèmes, embarqué, moteurs de jeu, navigateurs). Il résout le problème fondamental du C++ — la gestion mémoire — avec son borrow checker, sans sacrifier la performance. L’adoption par Linux kernel, Android, Windows, et Chromium est un signal fort. Mais sa courbe d’apprentissage est raide, et l’écosystème C++ existant est colossal. Go ne joue pas vraiment dans la même cour. Il excelle pour les services réseau, le cloud, les CLI — mais il a un garbage collector et n’offre pas le contrôle bas-niveau dont on a besoin là où C++ règne. Go remplace plutôt Java/Python pour le backend, pas C++. Verse (Epic Games / Tim Sweeney) est un pari intéressant et un peu à part. C’est un langage fonctionnel orienté vers le scripting de jeu dans UEFN/Fortnite. Pour l’instant il est trop jeune et trop niché pour menacer C++ — mais venant d’Epic, ça mérite d’être suivi, surtout dans l’écosystème Unreal qui t’intéresse directement.
Mon intuition : personne ne “remplacera” C++ à court terme. Ce qui va se passer, c’est une érosion progressive. Rust grignote les nouveaux projets systèmes. Zig attire ceux qui trouvent Rust trop complexe. Carbon (Google) tente l’interopérabilité directe avec le C++ existant. Et les projets C++ existants — qui représentent des milliards de lignes — resteront en C++ pendant des décennies, comme le COBOL avant eux.
Pour le TechArt, C++ restera central encore longtemps — Epic a trop investi dedans. Mais Verse pourrait devenir le layer de scripting dominant pour le gameplay, pendant que C++ reste le moteur sous le capot.
Bref historique du C++
Bjarne Stroustrup est le créateur du langage de programmation C++ (je l’ai « presque » rencontré à OOPSLA ‘95 (Object-Oriented Programming, Systems, Languages & Applications ) ! P.S., j’avais ceci dit rencontré Alan Kay, le fondateur du concept de programmation orienté objet à OOPSLA ‘97. Les deux ont profondément marqué ma vie; Alan Kay avait dit: “ I made up the term ‘object-oriented’, and I can tell you I did not have C++ in mind!”).
Au début, le langage se nommait C with Classes. Puis il est devenu C++, comme dans C incrémenté de 1.
Ne vous spécialisez pas trop. Ne soyez pas trop sûr de connaître l’avenir. Soyez flexible et n’oubliez pas que les carrières et les emplois s’inscrivent dans la durée. Trop de jeunes pensent qu’ils peuvent optimiser quelque chose, puis ils se rendent compte qu’ils ont passé quelques années ou plus à se spécialiser dans quelque chose qui n’était peut-être pas la bonne chose à faire. Et ce faisant, ils s’épuisent parce qu’ils n’ont pas passé assez de temps à nouer des amitiés et à avoir une vie en dehors de l’informatique.
Je rencontre beaucoup de personnes - je ne sais pas comment vous les appelez, des “geeks juniors” ? - qui pensent que la seule chose qui compte est la spécialité de l’informatique - la programmation ou l’IA ou le graphisme ou quelque chose comme ça. Et - eh bien, ce n’est pas le cas… Et s’ils ne font rien d’autre, eh bien - si vous ne communiquez pas vos idées, vous pouvez tout aussi bien faire du Sudoku… Il faut communiquer. Et beaucoup d’intellos caricaturaux l’oublient. Ils pensent qu’en écrivant le meilleur code, ils changeront le monde. Mais il faut savoir écouter. Il faut savoir communiquer avec les utilisateurs potentiels et apprendre d’eux. Et vous devez être en mesure de leur communiquer vos idées.
Vous ne pouvez donc pas vous contenter de faire du code. Il faut s’intéresser à la culture et à la manière d’exprimer les idées. Je n’ai jamais regretté le temps que j’ai consacré à l’histoire et aux mathématiques. Les mathématiques aiguisent votre esprit, l’histoire vous donne une idée de vos limites et de ce qui se passe dans le monde. Ne soyez donc pas trop sûrs de vous. Prenez le temps d’avoir une vie équilibrée.
Et soyez prêt à saisir l’occasion qui se présente. Je veux dire qu’une éducation diversifiée, un ensemble de compétences diversifiées - ce que vous construisez lorsque vous vous instruisez, vous construisez essentiellement un portefeuille de compétences - signifie que vous pouvez tirer parti d’une opportunité lorsqu’elle se présente. Vous pouvez parfois la reconnaître. Nous avons beaucoup d’opportunités. Mais pour beaucoup d’entre elles, nous ne pouvons pas en profiter ou nous ne les remarquons pas. C’est mon éducation assez large - j’ai fait de l’informatique standard, j’ai fait des compilateurs, j’ai fait plusieurs langages… Je crois que j’en connaissais deux douzaines à l’époque. J’ai également étudié l’architecture des machines et les systèmes d’exploitation. Et cet ensemble de compétences s’est avéré utile.
Il est difficile de donner des conseils - et il est au moins aussi difficile d’en recevoir.
Je suis devenu programmeur par erreur, en me trompant de mot au moment de choisir ce qu’il allait étudier après mes examens de fin d’études secondaires. Je pensais m’inscrire à un cours de mathématiques appliquées, qui s’est avéré être un cours d’informatique !
C++98 → Le standard originalC++11 → Le "C++ moderne" commence (auto, lambdas, smart pointers)C++14 → AmeliorationsC++17 → std::optional, structured bindingsC++20 → Concepts, ranges, coroutines, modulesC++23 → std::print, std::expected, plus de ranges
Cliquez sur le bouton “Download for Windows” (l’installeur détecte automatiquement votre architecture x64)
Lancez le fichier VSCodeUserSetup-x64-X.XX.X.exe téléchargé
1.2 — Options d’installation
Pendant l’installation, cochez les options suivantes (elles sont importantes) :
Ajouter l’action “Ouvrir avec Code” au menu contextuel de fichier Windows
Ajouter l’action “Ouvrir avec Code” au menu contextuel de répertoire Windows
Ajouter à PATH (permet d’ouvrir VS Code depuis un terminal avec la commande code)
Terminez l’installation et lancez VS Code pour vérifier qu’il fonctionne.
1.3 — Configurer la langue en français (optionnel)
Ouvrez VS Code
Appuyez sur Ctrl+Shift+P pour ouvrir la palette de commandes
Tapez Configure Display Language
Sélectionnez Français ou installez le pack de langue française
Installer le compilateur C++ (MSVC Build Tools)
C’est l’étape la plus importante. VS Code n’inclut pas de compilateur — il faut en installer un séparément. On utilise le compilateur officiel de Microsoft (MSVC), le même qu’Unreal Engine utilise.
Descendez jusqu’à la section “Outils pour Visual Studio” (ou “Tools for Visual Studio”)
Téléchargez “Build Tools pour Visual Studio 2022”
☝🏼
2026 ne fonctionne pas avec UE 5.7.4
- C’est un installeur léger (~1.5 Mo) qui téléchargera les composants nécessaires
☝🏼
Si vous ne trouvez pas la version 2022 (MS en ce moment ne montre que la version 2026), soit téléchargez-le via le lien https://aka.ms/vs/17/release/vs_community.exe ou téléchargez-le via Powershell ou GitBash via winget (attention, pas cmd !) :
cd $env:USERPROFILE/Downloadswinget install --id=Microsoft.VisualStudio.2022.Community -e
Note, l’option -e si vous utilisez winget va l’installer une fois téléchargé. Sinon, exécutez vs_community.exe à la main en double-cliquant dessus dans le dossier Downloads.
2.2 — Installer les composants C++
Le Visual Studio Installer se lance. Voici quoi sélectionner :
Dans l’onglet “Charges de travail” (Workloads), cochez :
Développement Desktop en C++ (“Desktop development with C++”)
Dans le panneau de droite, vérifiez que les composants suivants sont cochés :
Outils de build MSVC v145 (MSVC 2022 - 2026 ne fonctionne pas avec Unreal Engine)
SDK Windows 11 (la version la plus récente proposée)
Outils CMake C++ pour Windows
Fonctionnalités C++ de base
Cliquez sur “Installer” et patientez (environ 4 à 8 Go de téléchargement)
Redémarrez votre ordi
2.3 — Vérifier l’installation
Ouvrez le menu Démarrer
Cherchez “Developer Command Prompt for VS 2026”
Ouvrez-le et tapez :
cl
Vous devriez voir un message comme :
Microsoft (R) C/C++ Optimizing Compiler Version 19.xx.xxxxx
Si ce message apparaît, le compilateur est correctement installé.
Installer CMake
CMake est le système de build standard pour les projets C++ modernes. Il génère les fichiers de compilation à partir d’un fichier CMakeLists.txt.
Téléchargez le Windows x64 Installer (.msi) — version 4.2.3 ou plus récente
Lancez l’installateur
3.2 — Option cruciale pendant l’installation
Quand l’installateur vous le demande, Assurez-vous que “Add CMake to the system PATH for all users” est activé
C’est indispensable pour que VS Code puisse trouver CMake automatiquement.
3.3 — Vérifier l’installation
Ouvrez un nouveau terminal (PowerShell ou cmd) et tapez :
cmake --version
Vous devriez voir :
cmake version 4.2.3
Installer les extensions VS Code
Ouvrez VS Code et installez les extensions suivantes. Pour chaque extension, appuyez sur Ctrl+Shift+X (panneau Extensions) et cherchez le nom.
4.1 — Extensions essentielles
Extension
Éditeur
Rôle
C/C++
Microsoft
IntelliSense, débogage, navigation dans le code
C/C++ Extension Pack
Microsoft
Pack complet (inclut C/C++ Themes et autres)
CMake Tools
Microsoft
Intégration CMake dans VS Code (build, configure, etc.)
4.2 — Extensions recommandées
Extension
Éditeur
Rôle
Code Runner
Jun Han
Exécuter rapidement un fichier C++ avec un raccourci
Error Lens
Alexander
Affiche les erreurs directement dans le code, pas seulement dans le panneau
GitLens
GitKraken
Pour l’intégration Git (fortement recommandé)
Créer votre premier projet C++
5.1 — Créer la structure du projet
Créez un dossier sur votre disque, par exemple : C:\Projets\MonPremierCpp
Ouvrez VS Code
Fichier > Ouvrir le dossier... → sélectionnez MonPremierCpp
Oui je trust
5.2 — Créer les fichiers
Créez un fichier **CMakeLists.txt** à la racine du dossier :
cmake_minimum_required(VERSION 4.0)project(MonPremierCpp LANGUAGES CXX)# Utiliser le standard C++20set(CMAKE_CXX_STANDARD 20)set(CMAKE_CXX_STANDARD_REQUIRED ON)set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")add_executable(MonPremierCpp main.cpp)
Créez un fichier **main.cpp** à la racine du dossier :
Dans File → Preferences → Settings, cherchez pour “Auto Save” et mettre Auto Save à “After Delay” et Delay à 1ms
Assurez-vous que File → Auto Save est activé également.
Raccourcis clavier essentiels
Action
Raccourci
Palette de commandes
Ctrl+Shift+P
Compiler (Build)
F7
Exécuter sans débogage
Ctrl+F5
Déboguer
F5
Aller à la définition
F12
Voir les références
Shift+F12
Renommer un symbole
F2
Formater le fichier
Shift+Alt+F
Terminal intégré
`Ctrl+“
Chercher dans les fichiers
Ctrl+Shift+F
Dépannage courant
“cl n’est pas reconnu comme commande interne” — Vous n’êtes pas dans un Developer Command Prompt. Soit ouvrez-en un via le menu Démarrer, soit configurez VS Code pour utiliser le kit MSVC via CMake Tools.
“CMake Error: Could not find compiler” — Relancez VS Code, puis Ctrl+Shift+P → “CMake: Scan for Kits” pour que CMake Tools détecte votre compilateur.
“IntelliSense ne fonctionne pas” — Vérifiez que l’extension C/C++ est bien installée et que CMake a configuré le projet avec succès. L’IntelliSense utilise le fichier compile_commands.json généré par CMake.
Les erreurs de linking apparaissent — Vérifiez que vous avez bien sélectionné le kit x64 (et non x86) si vous développez en 64 bits.
Votre premier programme : Hello World
Décortiquons chaque ligne d'un programme C++ complet :
// A complete C++ program#include <iostream>int main(){ int answer {42}; // Defines the variable answer with value 42 std::cout << "The answer to life, the universe, and everything is " << answer << std::endl; return 0;}
Étape par étape : créer et exécuter ce programme
Ouvrez Visual Studio
Créez un nouveau projet “Console App”
Remplacez le code généré par le code ci-dessus
Appuyez sur Ctrl+F5 pour compiler et exécuter
Vous devriez voir : The answer to life, the universe, and everything is 42.
Types fondamentaux et variables
Types entiers
Type
Taille typique
Plage de valeurs
short
2 octets
-32 768 à 32 767
int
4 octets
-2 147 483 648 à 2 147 483 647
long
4 ou 8 octets
Au moins identique à int
long long
8 octets
±9,2 × 10^18
unsigned int
4 octets
0 à 4 294 967 295
Types à virgule flottante
Type
Taille
Précision
float
4 octets
~7 chiffres
double
8 octets
~15 chiffres
Un float 32 bits est découpé en trois parties selon la norme IEEE 754 :
[1 bit signe] [8 bits exposant] [23 bits mantisse]
Signe — 0 pour positif, 1 pour négatif
Exposant — détermine l’ordre de grandeur (la puissance de 2)
Mantisse — les chiffres significatifs
Le nombre se reconstitue ainsi : (-1)^signe × 1.mantisse × 2^(exposant - 127)
Pourquoi ce n’est pas précis :
Le problème fondamental est que la mantisse n’a que 23 bits, soit environ 7 chiffres décimaux de précision. Mais surtout, beaucoup de nombres décimaux simples n’ont pas de représentation binaire exacte.
Prenons 0.1 en base 10. En binaire, ça donne 0.000110011001100110011... qui se répète à l’infini, exactement comme 1/3 = 0.333... en décimal. Avec seulement 23 bits, on tronque, donc on stocke une approximation.
float f = 0.1f + 0.2f;std::cout << std::format("{:.20f}", f);// Affiche : 0.30000001192092895508// et non pas 0.3
Les conséquences pratiques sont importantes. Les comparaisons directes sont dangereuses :
if (f == 0.3f) // risque de ne jamais être vrai// Mieux : comparer avec une tolérance (epsilon)if (std::abs(f - 0.3f) < 0.0001f)
Et les erreurs s’accumulent à chaque opération. En additionnant des milliers de petites valeurs, l’écart peut devenir significatif.
C’est pour ça que double (52 bits de mantisse, ~15 chiffres de précision) est le choix par défaut. Et dans des domaines comme la finance, on évite complètement les flottants au profit d’arithmétique entière en centimes.
En game dev (Unreal, Blender), float reste courant pour les positions et couleurs parce que la performance mémoire prime et qu’une erreur au septième chiffre n’est pas visible à l’écran.
Autres types fondamentaux
Type
Taille
Utilisation
char
1 octet
Caractère unique (‘A’, ‘7’, ’!’)
bool
1 octet
true ou false
auto
variable
Le compilateur déduit le type
Déclaration et initialisation de variables
Le C++ offre plusieurs façons d'initialiser des variables. L'initialisation par accolades{} est la méthode moderne et recommandée :
int apple_count {15}; // Number of applesint orange_count {5}; // Number of orangesint total_fruit {apple_count + orange_count}; // Total number of fruit
Pourquoi l’initialisation par accolades **{}** ?
Empêche les conversions restrictives (ex. int x {3.14}; ne compilera pas — tant mieux !)
Fonctionne de manière cohérente pour tous les types
Montre clairement l’intention
unsigned a {}; est en fait l’option sûre — c’est une initialisation par valeur (value initialization), qui met a à 0.
Ce qu’il faut éviter, c’est :
unsigned a; // non initialisé — contient une valeur indéterminée
C’est une initialisation par défaut pour une variable locale de type primitif, ce qui en C++ signifie « aucune initialisation ». Lire a avant de lui assigner une valeur est un comportement indéfini (undefined behavior).
Résumé des options
unsigned a; // dangereux : valeur indéterminéeunsigned a {}; // sûr : initialisé à zéro (C++11, accolades vides)unsigned a = 0; // sûr : initialisation explicite classiqueunsigned a{0}; // sûr : initialisation directe par listeunsigned a(); // ATTENTION : ce n'est PAS une variable, // c'est une déclaration de fonction (most vexing parse)
En résumé
unsigned a {}; est parfaitement valide et considéré comme du C++ moderne idiomatique. Les accolades vides {} garantissent l’initialisation à zéro pour les types scalaires. C’est le style recommandé par les C++ Core Guidelines justement pour éviter les bugs liés à l’oubli d’initialisation.
Autres styles d’initialisation (à connaître, préférez **{}**) :
int a = 5; // C-style (allows narrowing — dangerous)int b(5); // Constructor-styleint c {5}; // Brace initialization (preferred!)int d {}; // Zero-initialized (preferred for default values)
const et constexpr
const int MAX_HEALTH {100}; // Cannot be changed after initializationconstexpr double PI {3.14159265}; // Computed at compile time (even better!)
const = “Je promets de ne pas modifier cette valeur” (définie à l’exécution ou à la compilation)
constexpr = “Cette valeur doit être connue à la compilation” (garantie plus forte)
Exercices
1. Explorer les tailles et limites des types
// Finding maximum and minimum values for data typesimport std;int main(){ std::println("The range for type short is from {} to {}", std::numeric_limits<short>::min(), std::numeric_limits<short>::max()); std::println("The range for type unsigned int is from {} to {}", std::numeric_limits<unsigned int>::min(), std::numeric_limits<unsigned int>::max()); std::println("The range for type long long is from {} to {}", std::numeric_limits<long long>::min(), std::numeric_limits<long long>::max()); std::println("The positive range for type float is from {} to {}", std::numeric_limits<float>::min(), std::numeric_limits<float>::max()); std::println("The full range for type float is from {} to {}", std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max()); std::println("The positive range for type double is from {} to {}", std::numeric_limits<double>::min(), std::numeric_limits<double>::max());}
Ce que vous apprendrez : Chaque type a des limites. std::numeric_limits vous donne min(), max() et lowest() pour tout type numérique. C’est important quand vous devez choisir le bon type pour vos données.
2. Entrées/sorties basiques avec des variables
// Writing values of variables to the screenimport std;int main(){ int apple_count {15}; // Number of apples int orange_count {5}; // Number of oranges int total_fruit {apple_count + orange_count}; // Total number of fruit std::println("The value of apple_count is {}", apple_count); std::println("The value of orange_count is {}", orange_count); std::println("The value of total_fruit is {}", total_fruit);}
Sortie attendue :
The value of apple_count is 15The value of orange_count is 5The value of total_fruit is 20
Concepts clés :
std::println() affiche une ligne avec un retour à la ligne à la fin
{} est un espace réservé de formatage — remplacé par l’argument correspondant
Les variables stockent des valeurs qui peuvent être utilisées dans des expressionsTravail personnel — Semaine 1 (2 heures)
⚠️
Retirez la variable total_fruit, comment faire pour imprimer le total maintenant ?
3. Écrivez un programme qui affiche la taille de tous les types fondamentaux en utilisant sizeof :
import std;int main(){ std::println("Size of bool: {} bytes", sizeof(bool)); std::println("Size of char: {} bytes", sizeof(char)); std::println("Size of short: {} bytes", sizeof(short)); std::println("Size of int: {} bytes", sizeof(int)); std::println("Size of long: {} bytes", sizeof(long)); std::println("Size of long long: {} bytes", sizeof(long long)); std::println("Size of float: {} bytes", sizeof(float)); std::println("Size of double: {} bytes", sizeof(double));}
⚠️
On peut trouver “Size of string” vous pensez ?
Oui mais non quoi qu’à bien y penser en fait du coup
std::string str {"Hello World"}; std::println("Size of string (\"{}\") is {} bytes", str, sizeof(str));
4. Écrivez un programme qui :
Demande à l’utilisateur son nom et son âge
Calcule son année de naissance
Affiche : “Bonjour [nom], vous êtes né(e) en [année].”
Indice : Utilisez std::cin >> pour lire l’entrée et string une fois avoir #include <string> pour le nom.
Solutions
Solution de l'exercice 3 :
#include <iostream>#include <string>int main(){ std::string name; int age {}; std::cout << "Entrez votre nom : "; std::cin >> name; std::cout << "Entrez votre âge : "; std::cin >> age; const int current_year {2026}; int birth_year {current_year - age}; std::cout << "Bonjour " << name << ", vous êtes né(e) en " << birth_year << "." << std::endl;}
Travail personnel
Lecture
Lire Beginning C++23 Chapitre 1
Lire Tour of C++ Chapitre 1
Exercices
Exercice 1 : Écrivez un programme qui affiche la taille de tous les types fondamentaux en utilisant sizeof :
#include <iostream>#include <format>int main(){ std::cout << std::format("Size of bool: {} bytes", sizeof(bool)) << std::endl; std::cout << std::format("Size of char: {} bytes", sizeof(char)) << std::endl; std::cout << std::format("Size of short: {} bytes", sizeof(short)) << std::endl; std::cout << std::format("Size of int: {} bytes", sizeof(int)) << std::endl; std::cout << std::format("Size of long: {} bytes", sizeof(long)) << std::endl; std::cout << std::format("Size of long long: {} bytes", sizeof(long long)) << std::endl; std::cout << std::format("Size of float: {} bytes", sizeof(float)) << std::endl; std::cout << std::format("Size of double: {} bytes", sizeof(double)) << std::endl;}
Exercice 2 : Écrivez un programme qui :
Demande à l’utilisateur son nom et son âge
Calcule son année de naissance
Affiche : “Bonjour [nom], vous êtes né(e) en [année].”
Indice : Utilisez std::cin >> pour lire l’entrée et std::string pour le nom.
Exercice 3 (Trouvez les erreurs) : Trouvez et corrigez tous les bugs dans ce programme :
include <iostream> // Bug 1: missing #using namespace std // Bug 2: missing ;int main{ // Bug 3: missing () int 2numbers; // Bug 4: identifiers can't start with a digit std:cout << "Hello" // Bug 5: should be std::cout, also missing ; return 0;}
Solutions
Solution de l’exercice 1 : Le code de l’exercice est la solution - exécutez-le et observez les tailles.
Solution de l’exercice 2 :
#include <iostream>#include <format>#include <string>int main(){ std::string name; int age {}; std::cout << std::format("Entrez votre nom : "); std::cin >> name; std::cout << std::format("Entrez votre âge : "); std::cin >> age; const int current_year {2025}; int birth_year {current_year - age}; std::cout << std::format("Bonjour {}, vous êtes né(e) en {}.", name, birth_year) << std::endl;}
Solution de l’exercice 3 : Les bugs et corrections sont déjà annotés dans l’énoncé. Le programme corrigé :
#include <iostream> // Bug 1 corrigé: ajout du #using namespace std; // Bug 2 corrigé: ajout du ;int main() // Bug 3 corrigé: ajout des (){ int numbers; // Bug 4 corrigé: identifiant valide (pas de chiffre au début) std::cout << "Hello" << std::endl; // Bug 5 corrigé: std:: et ajout du ; return 0;}