2010-01-04 5 views
1
#define PLAINTEXT_TARGET "plaintext" 
if(strstr(PLAINTEXT_TARGET, optarg) == PLAINTEXT_TARGET) 
    /* ... */ 

Le langage C garantit-il que PLAINTEXT_TARGET ci-dessus est compilé en une instance unique? Si le compilateur peut produire deux instances de la macro, alors le conditionnel ci-dessus est trompeur et peut être faux.Adresse de résolution de macro

Répondre

6

Les macros effectuent un remplacement textuel simple. Le préprocesseur remplace chaque occurrence de PLAINTEXT_TARGET par "plaintext", après quoi le compilateur examine le résultat et le compile.

Ainsi, le compilateur voit deux chaînes littérales et il n'est pas garanti que celles-ci ne seront pas stockées séparément (voir la réponse d'Alok pour la citation correspondante de la norme). Le code est en effet trompeur, il serait plus raisonnable de déclarer PLAINTEXT_TARGET comme constante:

const char* const PLAINTEXT_TARGET = "plaintext"; 
+0

Ahh! Vos réponses se réfèrent les unes aux autres! Je ne peux pas m'arrêter d'aller et venir entre eux! –

+0

Si maintenant seule la question aurait été sur la récursivité ... – sth

+0

LOL! Un bon exemple de récurrence mutuelle, j'espère. –

5

Non, ce n'est pas garanti par la norme. La norme dit ceci au sujet « string » littéraux (6.4.5p6):

Il est précisé si ces tableaux sont distincts à condition que leurs éléments ont les valeurs appropriées.

Ces tableaux se réfère au tableau de char créé à partir d'une chaîne littérale en phase de traduction 7.

Depuis que vous utilisez une macro, le code vu par le compilateur est:

if(strstr("plaintext", optarg) == "plaintext") 

Lorsque optarg est "plaintext", le code réduit à

if("plaintext" == "plaintext") 

Comme mentionné ci-dessus, ce n'est pas garanti pour être vrai en C.

Donc, vous devez utiliser strcmp() au lieu de vérifier les pointeurs pour l'égalité, ou, comme dans l'autre réponse, définir un pointeur char * utiliser à la place de la macro.