#define — c'est une directive de préprocesseur qui remplace simplement toutes les occurrences de l'identifiant par la valeur avant la compilation. Elle ne crée pas de variables, ne connaît pas les types, ne vérifie pas les limites et ne respecte pas la portée.
const — c'est un qualificateur qui crée une véritable variable, mais qui est bloquée en écriture après l'initialisation. La variable const a un type, une portée, participe au débogage et peut être plus sûre. De telles variables sont placées dans le segment .rodata ou sur la pile/en mémoire vive.
#define — pour des valeurs scalaires simples qui sont nécessaires à l'étape de compilation, surtout si utilisé dans des conditions de préprocesseur ou des tailles de tableau (#define SIZE 16).const — pour des valeurs qui doivent être passées de manière typée, déboguées, et sécurisées lors de l'exportation (dans les fichiers d'en-tête, inter-modules).const.Exemple :
#define PI 3.14159 const double G = 9.81; int arr[PI]; // ERREUR! PI n'est pas un entier int arr2[G]; // ERREUR! G n'est pas une valeur de temps de compilation
Question : const int a = 10; fonctionne-t-il comme une constante de temps de compilation pour créer un tableau : int arr[a]; ?
Réponse : Non. En langage C, const est un qualificateur, mais la variable est créée et initialisée au moment de l'exécution, et non au moment de la compilation, donc la taille du tableau doit être un littéral ou une expression connue du compilateur. Utilisez #define ou enum { SIZE = 10 };.
Exemple d'erreur :
const int a = 5; int arr[a]; // En C89/90 cela ne fonctionnera pas (les VLA sont apparus en C99, mais pas partout)
Histoire
Dans un serveur multimédia, on a essayé d'utiliser
const intpour définir les tailles de buffer, pensant que c'était une "constante de temps de compilation". Sur un compilateur (GCC, C99), tout fonctionnait, mais sur la plupart — erreur de compilation (VLA non supportés), urgent de réécrire en #define.
Histoire
Dans un code dépendant de la plateforme, une chaîne a été définie via
#define NAME "MyApp", utilisée à plusieurs endroits et oubliée d'être encadrée par des parenthèses. Après avoir ajouté des caractères à la chaîne sans parenthèses explicites, on a obtenu des résultats incorrects, entraînant des bugs étranges dans les logs.
Histoire
Dans un projet avec plusieurs modules, une constante a été définie via #define à deux endroits avec des valeurs différentes (copier-coller). Le résultat — les modules travaillaient avec des constantes différentes, des notifications de données qui n'ont été corrigées qu'après un débogage minutieux.