Maison > développement back-end > C++ > Pourquoi mes protections d'inclusion ne parviennent-elles pas à empêcher l'inclusion récursive et les définitions de symboles multiples ?

Pourquoi mes protections d'inclusion ne parviennent-elles pas à empêcher l'inclusion récursive et les définitions de symboles multiples ?

Mary-Kate Olsen
Libérer: 2024-12-22 19:37:11
original
598 Les gens l'ont consulté

Why Are My Include Guards Failing to Prevent Recursive Inclusion and Multiple Symbol Definitions?

Pourquoi mes gardes d'inclusion n'empêchent-ils pas l'inclusion récursive et les définitions de symboles multiples ?

PREMIÈRE QUESTION :

Pourquoi ne sont-elles pas incluses les gardes protègent mes fichiers d'en-tête d'une inclusion mutuelle et récursive ?

Inclure les gardes font leur emploi. Le problème vient des dépendances entre les définitions des structures de données dans les en-têtes qui s'incluent mutuellement.

Par exemple, supposons que a.h et b.h contiennent :

// a.h
#ifndef A_H
#define A_H
#include "b.h"
struct A {...};
#endif

// b.h
#ifndef B_H
#define B_H
#include "a.h"
struct B {...};
#endif
Copier après la connexion

Sans inclure les gardes, main.cpp ne le fera pas compiler en raison de la limite de profondeur de compilation.

Avec les gardes d'inclusion, la récursivité infinie est empêchée. Cependant, des dépendances entre les définitions demeurent :

  • Lors de la compilation de a.h, le préprocesseur rencontre #include "b.h" et le traite.
  • Lors du traitement de b.h, il rencontre #include "a.h" et le traite à nouveau.
  • Cela crée une dépendance où A doit être défini avant que B puisse être défini.

Pour résoudre ce problème, utilisez des déclarations forward dans les en-têtes qui en ont besoin :

// b.h
#ifndef B_H
#define B_H
struct A; // Forward declaration
struct B {...};
#endif
Copier après la connexion

DEUXIÈME QUESTION :

Pourquoi ne sont-ils pas inclus des gardes empêchant plusieurs définitions ?

Inclure des gardes peut empêcher la redéfinition au sein d'une seule unité de traduction, mais pas à travers différentes unités.

Par exemple, lorsque header.h :

#ifndef HEADER_H
#define HEADER_H
int f() {...};
#endif
Copier après la connexion

Est inclus dans plusieurs unités de traduction, telles que source1.cpp et source2.cpp :

// source1.cpp
#include "header.h"

// source2.cpp
#include "header.h"
Copier après la connexion

L'éditeur de liens se plaindra de plusieurs définitions de f(), car il voit la même définition dans des fichiers objets séparés.

Pour résoudre ce problème, utilisez le approches suivantes :

  • mot-clé en ligne : demande au compilateur d'intégrer le corps de la fonction, permettant ainsi plusieurs définitions sans erreurs d'éditeur de liens.
  • mot-clé statique : Donne à la fonction un lien interne, créant une copie privée pour chaque unité de traduction.
  • Sans nom espace de noms : déclarer la fonction dans un espace de noms sans nom lui donne un lien interne, empêchant plusieurs définitions.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal