en C99, nous avons des littéraux composés et ils peuvent être transmis à des fonctions comme dans: Cependant, si est-ce un bogue dans GCC ou dans la norme C? Si c'est ce dernier, cela règle à peu près toutes les utilisations transparentes de macros en forme de fonction, qui ressemblent à un énorme défaut ... p> mais depuis f code> n'est pas une fonction mais plutôt un Macro en forme de fonction, Barfs GCC à ce sujet en raison du préprocesseur qui l'analysant pas comme un argument, mais comme deux arguments, "
(int [2]) {1 code>" et "code> 2} Code> ". P>
fgetc. / code> pourrait être mis en oeuvre comme une macro (bien que nécessaire pour protéger son argument et protéger son argumentation. Ne pas l'évaluer plus d'une fois), ce code serait effectivement incorrect. Cela me semble surprenant. P> p>
3 Réponses :
Ceci est par la norme C, similaire à la manière dont C ++, ce qui suit est un problème:
f(((int[2]){ 1, 2 })); ^ ^
Dans la mesure où il s'agit d'un bug, c'est avec la norme, pas GCC (c'est-à-dire à cet égard, je pense que GCC fait quelle est la norme requise). P>
Ce "bogue" existe dans la norme depuis C89:
#include <stdio.h> void function(int a) { printf("%d\n", a); } #define macro(a) do { printf("%d\n", a); } while (0) int main() { function(1 ? 1, 2: 3); /* comma operator */ macro(1 ? 1, 2: 3); /* macro argument separator - invalid code */ return 0; }
+1 Excellente trouvaille pour un cas où cette question existe avant la C99. Je suppose que des parenthèses supplémentaires sont simplement nécessaires partout où une fonction pourrait réellement être définie comme une macro de la fonction comme une fonction ...
@ R. leur dit, ce que je pense que cela saura toujours sauver une macro de la fonction variable.
Hmm, je suppose qu'une macro de la fonction variable est en fait une solution à ce problème! C'est-à-dire qu'une implémentation pourrait faire #define fgets (...) __inline_fgets (__ va_args __) code> et le faire fonctionner dans tous les cas. (
#define fgets __inline_fgets code> D'autre part n'est pas valide pour une implémentation à faire car il rendra le nom de la fonction solitaire sans que l'opérateur d'appel de fonction n'est évalué au pointeur de fonction incorrect, c'est-à-dire des pointeurs différents dans différents. Unités de traduction.)
C'est normal et standard. N'oubliez pas que les macros ont existé depuis longtemps avant l'une de ces autres gubbins, et ils ne sont pas aussi intelligents.
GCC 4.5.2 avec le
-std = c99 code> option accepte
macro_fx (((int [2]) {1, 2})) code> Pour regrouper l'expression dans votre exemple dans votre exemple un argument.
Je suis au courant de la solution de contournement. Mais cela signifie que les macros semblables à la fonction ne peuvent pas vraiment être "comme une fonction" en C99. Avant les littéraux composés, je ne pense pas que la langue n'avait aucune construction où cette question importait.
... Et Steve va et me prouve tort!
Ce n'est pas un bug de rien. C et CPP sont langues séparées i> qui ont une boîte à outils intégrée, et le RPC n'est pas (et n'est pas autorisé à être) au courant des constructions de C. Si c'était c'était, vous ne seriez pas capable de faire des choses comme le
faire code> /
pendant code> Trick, blocs personnalisés basé sur
pour code> ou macros Manger des types / des opérateurs (au moins l'un d'entre eux -
offsetof code> - est dans la norme).
@LeShenko: En ce sens, il est sans doute un bug de la norme C, dans ce C permet aux définitions de macro-macro-fonctions pour les fonctions standard malgré elles ne se comportent pas réellement identique aux fonctions. Mais comme le montre la réponse de Steve, c'était déjà le cas que ceux-ci pouvaient se comporter de manière inattendue et étrange à moins que vous n'utilisiez des parenthèses supplémentaires, donc si quelque chose dans la norme devrait être modifié, il s'agit probablement d'ajouter un langage ATENDANT que les programmes conformes doivent être Conscient de cela et utilisez des parenthèses où la question pourrait les affecter.