Cela dépend du degré de portabilité de votre programme.
Tant que vous écrivez un programme qui est censé fonctionner avec des compilateurs dont vous savez qu'ils supportent certainement #prama once
en utilisant simplement #pragma once
devrait suffire. Mais en faisant cela, vous limitez votre programme à l'ensemble des compilateurs qui supportent la fonctionnalité définie par l'implémentation.
Si vous voulez que votre programme fonctionne sur tous les compilateurs alors vous devez utiliser #pragma once
et inclure les gardes à la fois.
Dans le cas où un compilateur ne supporte pas #pragma once
il l'ignorera tout simplement [Ref#1] Dans ce cas, les gardes d'en-tête vous serviront, donc il n'y a rien de mal à les utiliser tous les deux lorsque vous n'êtes pas au courant des fonctionnalités supportées par vos compilateurs cibles.
Ainsi, si vous voulez que votre programme soit 100% portable sur différents compilateurs, l'idéal est encore d'utiliser uniquement les gardes d'inclusion. Comme @CharlesBailey le fait remarquer à juste titre, puisque le comportement de #pragma once
est définie par l'implémentation, le comportement sur un compilateur inconnu pourrait avoir un effet néfaste sur votre programme.
[Ref#1]
Standard C++03 : 16.6 Directive Pragma
Une directive de prétraitement de la forme
# pragma pp-tokensopt new-line
fait en sorte que l'implémentation se comporte d'une manière définie par l'implémentation. Tout pragma qui n'est pas reconnu par l'implémentation est ignoré.