2017-03-02 4 views
1

Je rencontre un comportement que je trouve bizarre avec le pré-traitement de _Pragma("GCC error")._Pragma ("erreur GCC") est traité différemment à l'intérieur et à l'extérieur d'une directive #if

Je reçois les mêmes résultats avec avr-gcc (GCC) 4.9.2 et avec gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4).

Le code source:

#define E    _Pragma("GCC error \"This is an error\"") 

#define _IS_VOID_  , 1 

/* Return "1" if <c> is "", return "0" otherwise. 
*/ 
#define ISVOID(c)   _ISVOID2(c) 
#define _ISVOID2(c)  _ISVOID3(_IS_VOID_##c,0,) 
#define _ISVOID3(...)  _ISVOID4(__VA_ARGS__) 
#define _ISVOID4(v,x,...) x 


"ISVOID(something):" ISVOID(something) 
"ISVOID():" ISVOID() 
"ISVOID(E):" ISVOID(E) 


#if ISVOID(something) == 1 
"ISVOID(something)==1: true" 
#else 
"ISVOID(something)==1: false" 
#endif 

#if ISVOID() == 1 
"ISVOID()==1: true" 
#else 
"ISVOID()==1: false" 
#endif 

#if ISVOID(E) == 1 
"ISVOID(E)==1: true" 
#else 
"ISVOID(E)==1: false" 
#endif 

Je traite cela avec gcc -E -std=c1x -Wall -Wextra -Wpedantic main.c >output.

Je reçois cela sur la ligne de commande (presque normale):

main.c:16:11: error: This is an error 
"ISVOID(E):" ISVOID(E) 
     ^

et ceci dans la sortie:

# 1 "main.c" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "/usr/include/stdc-predef.h" 1 3 4 
# 1 "<command-line>" 2 
# 1 "main.c" 
# 14 "main.c" 
"ISVOID(something):" 0 
"ISVOID():" 1 
"ISVOID(E):" 
# 16 "main.c" 

# 16 "main.c" 
1 





"ISVOID(something)==1: false" 



"ISVOID()==1: true" 







"ISVOID(E)==1: false" 

Ensuite, ISVOID(E) étend à 1 en dehors de la directive #if et étend à 0 à l'intérieur, ce qui signifie que _Pragma("GCC error") est traité différemment à l'intérieur et à l'extérieur d'une directive #if.

De plus, il n'y a pas d'émission d'une "Ceci est une erreur" liée au #if ISVOID(E) == 1.

Ce comportement est-il normal?

+0

Intéressant; hallucinant - pourquoi est-ce un problème dans la pratique? Lorsque vous prétraitez, obtenez-vous un message comme '' 'cpp13.c: 15: 11: erreur: Ceci est une erreur''' et ' '' "ISVOID (E):" ISVOID (E) '' 'est identifié comme l'emplacement de l'erreur? En cours d'exécution cpp de GCC 6.3.0 sur un Mac (MacOS Sierra 10.12.3), qui fait partie de la sortie, écrit à l'erreur standard, bien sûr. Le pré-processeur signale l'échec, bien sûr (état de sortie 1). –

+0

Ceci est un problème en pratique pour mon [projet HWA] (http://github.com/duparq). C'est un ensemble de macros qui donne un accès au matériel via une interface générique. J'ai besoin de détecter et de gérer les erreurs (principalement les fautes de frappe) pour émettre des messages polis et informatifs sur l'origine des erreurs au lieu des tonnes de messages que le compilateur lancera sur les erreurs dans les expansions de macros. Comme l'utilisateur peut utiliser les définitions HWA à la fois dans la source et dans les directives, j'ai besoin que le _Pragma soit traité de la même manière quel que soit le contexte. – duparq

+0

J'ai aussi l'erreur 'cpp13.c: 15: 11: C'est une erreur' située' '" ISVOID (E): "ISVOID (E)'. J'ai le même résultat avec avr-cpp (GCC) 4.9.2. – duparq

Répondre