11
votes

Différence entre pragma une fois à l'intérieur et à l'extérieur incluent les gardes?

Y a-t-il une différence entre placer le #pragma une fois code> à l'intérieur des gardes include par opposition à l'extérieur?

Case 1: P>

#pragma once
#ifndef SOME_HEADER_H
#define SOME_HEADER_H


4 commentaires

C'est assez redondant d'inclure les deux, ne pensez-vous pas? Je voudrais simplement utiliser les définitions de vérification.


Dupliqué possible de #pragma une fois que vs incluent des gardes?


@Tim: Ils sont non redondants sur un compilateur qui reconnaît "pragma une fois", mais n'effectue pas l'optimisation intelligente que GCC fait que GCC, à repérer lorsque des gardes d'en-tête lui permettent de ne pas déranger la ré-visité du fichier. Au moins certaines versions de MSVC sont dans cet état, ne connaissez pas le dernier.


Je pense que vous êtes mal interprété ma question ... Je demande à propos de l'emplacement de Pragma une fois, non pas si je devrais utiliser Pragma une fois ou des gardes d'en-tête.


3 Réponses :


5
votes

Ils sont redondants.

#pragma une fois n'est pas pris en charge par tous les compilateurs, tandis que les gardes sont des gardes. Il suffit d'utiliser des gardes. Les compilateurs comme GCC sont suffisamment intelligents pour comprendre incluent les gardes et n'ouvriront même pas le fichier à nouveau.


1 commentaires

Bien que, à des fins pratiques, #pragma une fois est pris en charge par tous les compilateurs notables.



1
votes

Pour répondre à votre question:

cas 1:

Le compilateur vérifiera si la constante de préprocesseur est définie ou non, sinon le définissez, puis vérifiez la directive #pragma Ońce. Ceci est probablement une recherche de hasch sur la chaîne "quelque_header_h" pour savoir s'il est défini ou non avant de faire une autre recherche de hasch sur le nom du fichier actuel (probablement le fichier __ constant défini par le pré-processus). Donc, si le fichier n'a jamais été lu, nous avons deux recherches de hasch et deux sauvegardes de hachage, si le fichier a été lu juste une seule recherche de hasch.

Cas 2:

Ceci est évidemment la même chose que le cas 1 mais dans l'ordre opposé. Donc, la seule chose que nous pouvons comparer est la longueur des touches de hachage à utiliser comme recherche. Selon le chemin du chemin du fichier d'en-tête actuel, c'est-à-dire la longueur du chemin, la recherche de hachage pour la directive #pragma une fois que la directive pourrait être plus coûteuse à calculer. Si le nom du fichier est "C: \ mec.h", il est plus court que "quelque_header_h".

Je suppose donc en résumé. Non, il n'y a pas de cas particulier au cas où le cas 1 serait plus bénéfique que le cas 2 ou inversement. Au moins pas crier heureka sur;)

acclamations


0 commentaires

7
votes

Il y a une différence subtile dans celle si quelque_header_h est déjà défini avant que l'en-tête ne soit inclus, puis dans le second cas, le prétraiteur traitera le #pragma une fois , et Le premier cas, ce ne sera pas.

Vous verrez une différence fonctionnelle si vous #undef quelque_header_h et incluez le fichier à nouveau par le même Tu: xxx

Maintenant, dans le cas 1, j'ai toutes les définitions du fichier d'en-tête. Dans le cas 2, je ne le fais pas.

Même sans le #undef , vous pouvez concevoir une différence de temps de prétraitement en raison du #pragma une fois être ignoré dans le cas 1. Cela dépend de la mise en œuvre.

Je peux penser à deux manières plausibles qu'il pourrait déjà être définie avant la première inclusion de ce fichier d'en-tête:

  • (l'évident) Un fichier complètement séparé le définit, délibérément ou par nom accidentel, affrontement,
  • Une copie de ce fichier l'a déjà définie. En fonction de la mise en œuvre pouvant inclure le cas où ce fichier participe à la même TU sous deux noms de fichiers différents, par ex. en raison d'un lien symbolique ou d'une fusion de système de fichiers. Si votre implémentation prend en charge #pragma une fois , et que vous examinez la documentation très soignée, vous pouvez trouver une déclaration définitive si l'optimisation est appliquée par le chemin sous lequel le fichier est inclus ou par comparaison de quelque chose qui identifie le stockage d'un fichier, comme le numéro d'inode. Si ce dernier, vous pouvez même être capable de déterminer s'il existe toujours des escroqueries pouvant être tirées pour tromper le pré-processeur, telle que le montage de la télécommande, un système de fichiers local pour dissimuler que c'est "le même fichier vraiment" ...

    utilisé à la manière attendue, il n'y a aucune différence à condition que la mise en œuvre traite #pragma une fois de la manière dont Microsoft le définit. Tant que cela est traité plutôt que d'ignorer, il marque le fichier contenant de l'optimisation, de sorte que cela ne comporte pas si elle serait traitée sur un second passage dans le fichier - le deuxième passage ne se produira pas.

    Et bien sûr puisque le pragma n'est pas standard, du moins en théorie, il pourrait avoir une signification complètement différente sur différentes implémentations, auquel cas cela pourrait compter quand et combien de fois il est traité. En pratique, vous penseriez que personne ne le fera.


0 commentaires