10
votes

Pour comprendre comment printf ("% d \ n", ({int N; scanf ("% d", & n); n * n;})); travaille en C

Je suis tombé sur ce programme via un Quora Réponse XXX Je me demandais comment cela fonctionne-t-il et si cela conforme la norme?


3 commentaires

C99 strict: ideone.com/9k9bcv et c ideone.com/pdalsh mon compilateur IDE C déclare un tas d'erreurs et d'avertissements à ce sujet. Intéressé pourquoi le deuxième lien compile.


@Armin Le lien utilise GCC, qui utilise par défaut GNU C89.


Ne répondez pas à votre question, mais cela fonctionne avec GCC ici, j'ai écrit des codes similaires Premier et second , rappelez-vous dans int i = (5, 7); i serait 7


3 Réponses :


0
votes

Je ne crois pas que cela fonctionne ... n a une portée locale dans les accolades ... Lorsque vous quittez les accolades, n devient indéniable si je suppose que je suppose que je suppose est pourrait existe toujours quelque part sur la pile et pourrait travail. Il mendie pour les problèmes de mise en œuvre et je garantis sont la mise en œuvre dépendante.

Une chose que je peux vous dire est que quiconque travaillant pour moi qui a écrit que ce serait lu la loi anti-émeute.


6 commentaires

Ça marche. Il suffit de la coller dans un fichier et compilez (même fonctionne à l'aide de -ansi drapeau dans GCC). C'est certainement mauvais style.


Il y a beaucoup de choses qui "travaillent" - ne veut pas dire qu'ils sont valides. Je peux voir comment le dernier n * n peut laisser une valeur sur la pile, mais je vais garantir qu'il n'y a aucune pénurie de la mise en œuvre de C qui ne le compilera même pas.


@PaulProgrammatère que le drapeau n'est pas suffisant, vous devez utiliser -pedantic si vous voulez un avertissement pour des choses non standard comme ça. Ce code est pas C.


Options GCC telles que -std = c89 (AKA -ansi ) ou -std = c99 seule tentative de s'assurer que tous les programmes conformes seront interprétés correctement , en désactivant des extensions qui entrent en conflit avec l'interprétation standard (telle que le traitement ASM ou attribut comme mot clé). Ils ne sortent pas de leur façon de rejeter des programmes non conformes. -PeRtic-Erreurs est la chose la plus proche que vous avez à une option "Programmes non conformes à rejeter" dans GCC.


Quoi qu'il en soit, je pense que le comportement est bien défini dans GCC, et j'espère donc pour chaque compilateur à l'appui d'une telle déclaration. Lorsque vous quittez les accolades, vous n'utilisez plus n , mais la valeur de la dernière expression, qui est n * n .


@effreffe: En effet, le comportement est bien défini sur les compilateurs GNU C.



0
votes

Ça marche. Je ne reçois aucun avertissement de GCC, alors je suppose que cela se conforme à la norme.

La magie est la fermeture: xxx

Ce pépite scanne un entier de la console ( sans vérification des erreurs) et les carrés, retourner le nombre au carré. Dans les implémentations antiques de C, le dernier numéro sur la pile est renvoyé. Le n * n met le numéro sur la pile.

Cette valeur est transmise au printf: xxx

donc, Pour répondre à vos questions: Oui, cela fonctionne. Oui, c'est "standard" (dans la mesure où tout le monde suit entièrement la norme). Non, ce n'est pas une bonne pratique. C'est un bon exemple de ce que j'ai par la réaction de Knee-Serk appeler une "lettre d'amour du compilateur", conçue principalement pour montrer à quel point le programmeur est intelligent, pas nécessairement de résoudre un problème ou d'être efficace.


2 commentaires

Ce n'est pas standard. C'est "gnu c".


Je vais acheter ça. Travaillé avec le drapeau --ansi , alors figuré c'était assez ANSI-assez.



7
votes

Ce code utilise une fonctionnalité "GNU C" appelée instruction-Expressions, dans la mesure où une instruction composée par la parenthèses-ci-jointe peut être utilisée comme expression, dont le type et la valeur correspondent au résultat de la dernière instruction de l'instruction composée. Ceci n'est pas valide syntaxiquement C, mais une fonction GCC (également adoptée par certains autres compilateurs) a été ajoutée probablement parce qu'elle était considérée comme importante pour écrire des macros qui n'évaluent pas leurs arguments plus d'une fois.

Vous devez être conscient de ce que c'est et ce qu'il fait au cas où vous le rencontrerez dans le code que vous devez lire, mais j'éviterais de l'utiliser vous-même. C'est déroutant, inutile et non standard. La même chose peut presque toujours être réalisée de manière portraitement avec des fonctions en ligne statiques.


0 commentaires