2012-11-12 6 views
33

enter image description hereCzy nadal powinienem używać #include GUARD AND #pragma once?

http://en.wikipedia.org/wiki/Pragma_once
Czy mogę nadal korzystać z osłon, kiedy to wszystkie te kompilatory obsługują #pragma once?
Wiele odpowiedzi na przepełnienie stosu mówi, że używa się obu dla kompatybilności, ale nie jestem pewien, czy to nadal dzwoni prawda. Jakie kompilatory dzisiaj nie obsługują #pragma once?

Nie jestem pewien, czy korzystanie z obu było tylko zaleceniem, zanim zostało szeroko przyjęte, lub jeśli nadal istnieją bardzo dobre powody, aby korzystać z obu metod.
Dowolne przykłady użycia tylko #pragma once mogą powodować problemy?

+11

Pamiętaj, że starsze wersje wymienionych kompilatorów mogą go nie obsługiwać, więc jeśli tworzysz program o otwartym kodzie źródłowym, który ma być dystrybuowany, wówczas pragma może nie działać. –

+5

Nie chodzi tylko o obsługę kompilatora, ale także zależy od tego, jak skomplikowane jest środowisko. Czy ufasz kompilatorowi, aby wiedzieć * na pewno *, jeśli dwa pliki są takie same lub nie, w tym wszystkie zawieszenia sieci i linki symboliczne? –

+2

również rozważyć pomocnicze narzędzia, takie jak indeksatory i analizatory. nie może istnieć pełny preprocesor lub analizator składni, tak jak w przypadku kompilatora. – justin

Odpowiedz

13

To zależy od tego, ile przenośny Oczekuje się program być.

Tak długo, jak piszesz program, który ma działać z kompilatorami, które znasz zdecydowanie wspierają #prama once, wystarczy użycie #pragma once powinno wystarczyć. Ale robiąc to, ograniczasz swój program do zestawu kompilatorów, które obsługują określoną funkcję.

Jeśli potrzebujesz programu do pracy na wszystkich kompilatorach, powinieneś użyć #pragma once i dołączyć oba strażników.

W przypadku kompilator nie obsługuje #pragma once będzie to po prostu zignorować to [Ref # 1], w takim przypadku strażnicy header będzie służył celowi, więc nic złego w korzystaniu z ich obu, jeśli nie są świadomi funkcji obsługiwanych przez kompilatory docelowe.

Jeśli chcesz, aby Twój program był w 100% przenośny na różnych kompilatorach, idealnym rozwiązaniem jest użycie tylko osłony. Jako że @CharlesBailey słusznie zwraca uwagę, ponieważ zachowanie dla #pragma once jest określoną implementacją, zachowanie na nieznanym kompilatorze może mieć szkodliwy wpływ na twój program.


[Nr 1] 03
standard C++ 16,6 dyrektywy Pragma

Dyrektywa przerób formy

# pragma pp-tokensopt new-line

powoduje implementacja do zachowania w sposób zdefiniowany przez implementację. Każda pragma, która nie jest rozpoznawana przez implementację, jest ignorowana.

+7

Jeśli chcesz, aby twój program był w 100% przenośny, musisz używać włączników, ale musisz także unikać '#pragma raz', ponieważ zachowanie zdefiniowane w implementacji na nieznany kompilator może mieć szkodliwy wpływ na twój program. –

+0

@CharlesBailey: Zgoda. Odpowiedź wymaga modyfikacji. Zrobię to. Dzięki za wskazanie. –

+3

'#pragma once' nie powiedzie się, jeśli ten sam plik jest aliasingowany przez dwie różne nazwy na poziomie Systemu Operacyjnego/Systemu Plików. Jednak # include-guard w pliku będzie mieć tę samą nazwę, niezależnie od odwołania do systemu plików i nadal będzie działać. – abelenky

10

To nietypowe, więc jeśli chcesz być bezpieczne użytkowanie include strażników

5

W tabeli pokazuje, że jest teraz bardzo rzadko zdarza się spotkać kompilatora w głównym nurcie użytku, który nie obsługuje #pragma once. Utrzymanie bazy kodu w czystości i tanie utrzymanie wymaga ciągłego wysiłku związanego z refaktoryzacją. Konieczność aktualizacji obejmuje strażników za każdym razem, gdy zmieniasz nazwę klasy lub przenosisz jakiś kod, co stanowi znaczne obciążenie dla tego wysiłku.

Powiedziałbym więc, że oprócz pewnych niszowych przypadków narożnych lub uszkodzonych systemów kompilacji, w praktyce bezpieczne jest poleganie na #pragma once. Jeśli zależy Ci na wydajności i jakości kodu przy użyciu tylko #pragma once wydaje się oczywistym wyborem.

Wyjątkiem jest pisanie biblioteki, która musi obsługiwać każdy kompilator pod słońcem lub niefortunne, że musi pracować z jednym z tych rzadkich kompilatorów, które nie mają tej funkcji.

Powiązane problemy