Comportements de #import et de #define

ThibautThibaut Membre
mars 2010 modifié dans Objective-C, Swift, C, C++ #1
Imaginez que vous ayez les deux classes suivantes :
#define _CLASS1_<br />#import &quot;DefineLog.h&quot;<br />#import &lt;Foundation/Foundation.h&gt;<br /><br />@interface Class1 : NSObject { }<br />+ (void)log;<br />@end


#define _CLASS2_<br />#import &quot;DefineLog.h&quot;<br />#import &lt;Foundation/Foundation.h&gt;<br /><br />@interface Class2 : NSObject { }<br />+ (void)log;<br />@end


L'implémentation de la méthode [tt]log[/tt] est la suivante (même implémentation dans chacune des classes) :
+ (void)log {<br />	NSLog(_LOG_);<br />}


Le fichier [tt]DefineLog.h[/tt] contient le code suivant :
#if defined _CLASS1_<br />#undef _LOG_<br />#define _LOG_ @&quot;Class 1!&quot;<br /><br />#elif defined _CLASS2_<br />#undef _LOG_<br />#define _LOG_ @&quot;Class 2!&quot;<br /><br />#else<br />#undef _LOG_<br />#define _LOG_ @&quot;Unknown class...&quot;<br /><br />#endif



Que va-t-il se passer dans la console si l'on fait le code suivant ?
[Class1 log];<br />[Class2 log];





Réponse :
Class 1!<br />Class 2!



Dans le premier cas, [tt]DefineLog.h[/tt] étant inclus par Class1, _LOG_ vaut @Class 1! dans la première classe. Mais lors de l'inclusion dans la seconde classe, on pourrait penser que comme [tt]DefineLog.h[/tt] a déjà  été inclus, il n'est pas inclus une seconde fois et _LOG_ reste à  @Class 1!. Cependant, il vaut @Class 2!.

Avec #import, le fichier est donc inclus plusieurs fois ?


Ce qui me ramène à  un autre problème, les #define.
_CLASS1_ est définit dans Class1, on passe bien dans le premier if. Dans Class2, on définit _CLASS2_ afin de passer non pas par le premier if mais par le second. _CLASS1_ n'est donc plus définit.

Quelle est donc la portée des #define ?

Réponses

  • AliGatorAliGator Membre, Modérateur
    05:16 modifié #2
    Je ne vois pas ce qui te choque dans ton exemple.
    #import n'empêche pas un .h d'être inclus plusieurs fois, et encore heureux.

    Ou plutôt pour être plus précis :
    - il n'empêche pas du tout d'inclure un .h à  différents endroits dans tout ton projet, à  chaque endroit ça va inclure le .h.
    - ce qu'il empêche, contrairement au #include, c'est les inclusions récursives. Par exemple si Class2.h importait à  la fois DefineLog.h et Class1.h (qui lui aussi importe DefineLog.h). Là  il n'incluera alors, lors de la compilation du fichier Class2.m en un fichier objet, qu'une seule fois DefineLog.h : quand il importera ensuite Class1.h et qu'il verra un autre import de DefineLog.h dans ce 2e header, il ne va pas le réinclure une 2e fois au risque de définir 2 fois les méthodes et les classes.


    Donc le comportement décrit est tout à  fait normal ;)
  • ThibautThibaut Membre
    05:16 modifié #3
    J'ai pourtant déjà  eu des erreurs d'inclusion récursive avec les #import...


    Et je n'ai pas spécialement dit que le comportement est anormal, je dis juste que finalement je ne comprends pas tout.
  • AliGatorAliGator Membre, Modérateur
    05:16 modifié #4
    Ah, t'es sûr pour les erreurs d'inclusion récursive avec #import ? T'as des exemples ?
    Ca m'intrigue ;)
Connectez-vous ou Inscrivez-vous pour répondre.