ProgrammationDéveloppeur C

Parlez des principales différences entre const et #define pour définir des constantes en langage C. Quand et pourquoi utiliser chaque approche, avec des exemples d'erreurs typiques ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

#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.

Quand et pourquoi utiliser :

  • #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).
  • Pour les pointeurs sur des chaînes et des tableaux, il est préférable d'utiliser 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 piège.

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 int pour 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.