# pragma raz kontra strażnicy? [duplikat]

to pytanie ma już odpowiedzi tutaj : czy # pragma jest kiedyś bezpiecznym strażnikiem? (14 odpowiedzi) Zamknięty 1 rok temu .

Pracuję nad bazą kodową, która działa tylko w systemie windows i jest kompilowana pod Visual Studio (integruje się ściśle z Excelem, więc nigdzie się nie wybiera). Zastanawiam się, czy nie powinienem stosować tradycyjnych strażników, czy użyć #pragma once dla naszego kodu. Myślę, że pozwolenie kompilatorowi na obsługę #pragma once przyniesie szybsze Kompilacje i będzie mniej podatne na błędy podczas kopiowania i wklejania. Jest też nieco mniej brzydki ;)

Uwaga: Aby uzyskać szybszy czas kompilacji, możemy użyć redundantnych strażników Include , ale dodaje to ścisłe powiązanie między dołączonym plikiem a plikiem including. Zazwyczaj jest to w porządku, ponieważ strażnik powinien być oparty na nazwie pliku i zmieniałby się tylko wtedy, gdy trzeba zmienić nazwę include.

Author: Jonathan Leffler, 2009-07-17

13 answers

Nie sÄ ... dzÄ™, Ĺźe to zrobi znaczÄ ... cÄ ... răłĺźnicä ™ w czasie kompilacji, ale #pragma once jest bardzo dobrze wspierane przez kompilatory, ale nie jest w rzeczywistoĹ "ci czÄ ™ Ĺ" ciÄ ... standardu. Preprocesor może być z nim nieco szybszy, ponieważ łatwiej jest zrozumieć dokładną intencję.

#pragma once jest mniej podatny na błędy i jest mniej kodu do wpisania.

Aby przyspieszyć czas kompilacji po prostu forward declare zamiast włączać w .pliki h, kiedy możesz.

Wolę używać #pragma once.

Zobacz ten artykuł Wikipedii o możliwości użycia obu .

 345
Author: Brian R. Bondy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-17 15:34:02

Chciałem tylko dodać do tej dyskusji, że właśnie kompiluję na VS i GCC i używałem include guards. Teraz przełączyłem się na #pragma once, i jedynym powodem dla mnie nie jest wydajność, przenośność lub standard, ponieważ nie obchodzi mnie, co jest standardem, o ile VS i GCC wspierają go, i to jest to:

#pragma once zmniejsza możliwości wystąpienia błędów.

Jest zbyt łatwo skopiować i wkleić plik nagłówka do innego pliku nagłówka, zmodyfikować go do własnych potrzeb i zapomnij o zmianie nazwy strażnika. Gdy oba są uwzględnione, śledzenie błędu zajmuje trochę czasu, ponieważ komunikaty o błędach nie muszą być jasne.

 179
Author: Cookie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-30 09:57:05

#pragma once mA nieusuwalne błędy. Nigdy nie należy go używać.

Jeśli ścieżka wyszukiwania #include jest wystarczająco skomplikowana, kompilator może nie być w stanie odróżnić dwóch nagłówków o tej samej nazwie bazowej (np. a/foo.h i b/foo.h), więc #pragma once w jednym z nich powstrzyma oba. Może również nie być w stanie stwierdzić, że dwa różne relatywne include (np. #include "foo.h" i #include "../a/foo.h" odnoszą się do tego samego pliku, więc #pragma once nie powstrzyma redundantnego include, gdy powinien mam.

Wpływa to również na zdolność kompilatora do unikania ponownego odczytywania plików za pomocą strażników #ifndef, ale jest to tylko optymalizacja. Dzięki strażnikom #ifndef kompilator może bezpiecznie odczytać każdy plik, który nie jest pewny , który już widział; jeśli jest zły, po prostu musi wykonać dodatkową pracę. Tak długo, jak żadne dwa nagłówki nie definiują tego samego makra strażnika, kod będzie kompilowany zgodnie z oczekiwaniami. A jeśli dwa nagłówki zrobią zdefiniują to samo makro strażnika, programista może wejść i zmienić jeden z oni.

#pragma once nie ma takiej siatki bezpieczeństwa-jeśli kompilator pomyli się co do tożsamości pliku nagłówkowego, tak czy siak, Program nie dokona kompilacji. Jeśli trafisz na ten błąd, jedyną opcją jest zaprzestanie używania #pragma once lub zmiana nazwy jednego z nagłówków. Nazwy nagłówków są częścią umowy API, więc zmiana nazwy prawdopodobnie nie wchodzi w grę.

(skrócona wersja why this is unfixable jest taka, że ani Unix, ani Windows filesystem API Nie oferują żadnych mechanizm gwarantuje informację, czy dwie ścieżki bezwzględne odnoszą się do tego samego pliku. Jeśli masz wrażenie, że numery i-węzłów mogą być używane do tego celu, przykro mi, mylisz się.)

(Uwaga historyczna: jedynym powodem, dla którego nie wyrwałem #pragma once i #import z GCC, kiedy miałem do tego prawo, ~12 lat temu, były nagłówki systemowe Apple polegające na nich. Z perspektywy czasu, to nie powinno mnie powstrzymywać.)

(skoro to już dwa razy w komentarzu wątek: Programiści GCC włożyli sporo wysiłku w to, aby #pragma once było jak najbardziej wiarygodne; zobacz GCC bug report 11569. Jednak implementacja w obecnych wersjach GCC może nadal zawieść w wiarygodnych warunkach, takich jak budowa farm cierpiących na przekrzywienie zegara. Nie wiem, jaka jest implementacja innego kompilatora, ale nie spodziewałbym się, że ktoś zrobiłby lepiej.)

 141
Author: zwol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-08 01:57:05

Dopóki dzień #pragma once nie stanie się standardem (nie jest to obecnie priorytet dla przyszłych standardów), proponuję go używać i używać strażników, w ten sposób:

#ifndef BLAH_H
#define BLAH_H
#pragma once

// ...

#endif

Powody są następujące:

  • #pragma once nie jest standardem, więc możliwe, że niektóre Kompilatory nie zapewniają tej funkcjonalności. To powiedziawszy, wszystkie główne Kompilatory go obsługują. Jeśli kompilator tego nie zna, przynajmniej zostanie zignorowany.
  • ponieważ nie ma standardowego zachowania dla #pragma once, nie należy zakładać, że zachowanie będzie taki sam na wszystkich kompilatorach. Guards zapewni co najmniej, że podstawowe założenie jest takie samo dla wszystkich kompilatorów, które przynajmniej implementują potrzebne instrukcje preprocesora dla guards.
  • na większości kompilatorów, #pragma once przyspieszy kompilację (jednego cpp), ponieważ kompilator nie otworzy ponownie pliku zawierającego tę instrukcję. Więc posiadanie go w pliku może pomóc, lub nie, w zależności od kompilatora. Słyszałem, że g++ może zrobić taką samą optymalizację po wykryciu strażników, ale musi potwierdzam.

Używając tych dwóch razem otrzymujesz najlepsze z każdego kompilatora do tego.

Teraz, jeśli nie masz jakiegoś automatycznego skryptu do generowania strażników, wygodniej będzie użyć #pragma once. Po prostu wiedz, co to oznacza dla przenośnego kodu. (Używam VAssistX do szybkiego generowania strażników i pragmy)

Powinieneś prawie zawsze myśleć o swoim kodzie w przenośny sposób (bo nie wiesz, z czego powstaje przyszłość), ale jeśli naprawdę myślisz, że nie jest w celu skompilowania za pomocą innego kompilatora (np. kodu dla konkretnego wbudowanego sprzętu) powinieneś po prostu sprawdzić dokumentację kompilatora o #pragma once, aby wiedzieć, co naprawdę robisz.

 39
Author: Klaim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-19 17:43:08

Z punktu widzenia testera oprogramowania

#pragma once jest krótszy od osłony include, mniej podatny na błędy, obsługiwany przez większość kompilatorów, a niektórzy twierdzą, że kompiluje się szybciej (co nie jest prawdą [dłużej]).

Ale nadal sugeruję, byś wybrał standardową ochronę.

Dlaczego #ifndef?

Rozważ taką wymyśloną hierarchię klas, gdzie każda z klas A, B, i C żyje w swoim własnym plik:

A. h

#ifndef A_H
#define A_H

class A {
public:
  // some virtual functions
};

#endif

B. h

#ifndef B_H
#define B_H

#include "a.h"

class B : public A {
public:
  // some functions
};

#endif

C. h

#ifndef C_H
#define C_H

#include "b.h"

class C : public B {
public:
  // some functions
};

#endif

Załóżmy teraz, że piszesz testy do swoich klas i musisz symulować zachowanie naprawdę złożonej klasy B. Jednym ze sposobów na to jest napisanie klasy mock za pomocą na przykład Google mock i umieszczenie jej w katalogu mocks/b.h. Zauważ, że nazwa klasy nie uległa zmianie, ale jest przechowywana tylko w innym katalogu. Ale najważniejsze jest to, że include guard ma taką samą nazwę jak w oryginalnym pliku b.h.

Kpiny / b. h

#ifndef B_H
#define B_H

#include "a.h"
#include "gmock/gmock.h"

class B : public A {
public:
  // some mocks functions
  MOCK_METHOD0(SomeMethod, void());
};

#endif

Jakie są korzyści?

Dzięki takiemu podejściu możesz wyśmiewać zachowanie klasy B bez dotykania oryginalnej klasy lub mówienia o niej C. Wszystko co musisz zrobić, to umieścić katalog mocks/ w ścieżce dołączania kompilatora.

Dlaczego nie można tego zrobić z #pragma once?

Jeśli użyłbyś #pragma once, dostałbyś nazwę, ponieważ nie może Chroń przed zdefiniowaniem klasy B dwa razy, raz oryginalnej i raz wyśmiewanej wersji.

 34
Author: Konrad Kleine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-13 11:38:26

Jeśli jesteś pewien, że nigdy nie użyjesz tego kodu w kompilatorze, który go nie obsługuje( Windows / VS, GCC i Clang są przykładami kompilatorów, które obsługują go), to z pewnością możesz użyć #pragma raz bez obaw.

Możesz również użyć obu (patrz przykład poniżej), aby uzyskać przenośność i przyspieszenie kompilacji na kompatybilnych systemach

#pragma once
#ifndef _HEADER_H_
#define _HEADER_H_

...

#endif
 24
Author: Donnie DeBoer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-02 20:05:36

Po dłuższej dyskusji na temat rzekomego kompromisu pomiędzy #pragma once i #ifndef strażnikami a argumentem poprawności czy nie (byłem po stronie #pragma once w oparciu o relatywnie niedawną indoktrynację w tym celu), postanowiłem w końcu przetestować teorię, że #pragma once jest szybsza, ponieważ kompilator nie musi próbować ponownie-#include pliku, który już został dołączony.

Do testu wygenerowałem automatycznie 500 plików nagłówkowych ze złożonymi współzależności i miał .c plik, który #includesą wszystkie. Przeprowadziłem test na trzy sposoby, raz z just #ifndef, raz z just #pragma once, a raz z obu. Przeprowadziłem test na dość nowoczesnym systemie (2014 MacBook Pro z systemem OSX, używając dołączonego Clang XCode, z wewnętrznym dyskiem SSD).

Po pierwsze, kod testu:

#include <stdio.h>

//#define IFNDEF_GUARD
//#define PRAGMA_ONCE

int main(void)
{
    int i, j;
    FILE* fp;

    for (i = 0; i < 500; i++) {
        char fname[100];

        snprintf(fname, 100, "include%d.h", i);
        fp = fopen(fname, "w");

#ifdef IFNDEF_GUARD
        fprintf(fp, "#ifndef _INCLUDE%d_H\n#define _INCLUDE%d_H\n", i, i);
#endif
#ifdef PRAGMA_ONCE
        fprintf(fp, "#pragma once\n");
#endif


        for (j = 0; j < i; j++) {
            fprintf(fp, "#include \"include%d.h\"\n", j);
        }

        fprintf(fp, "int foo%d(void) { return %d; }\n", i, i);

#ifdef IFNDEF_GUARD
        fprintf(fp, "#endif\n");
#endif

        fclose(fp);
    }

    fp = fopen("main.c", "w");
    for (int i = 0; i < 100; i++) {
        fprintf(fp, "#include \"include%d.h\"\n", i);
    }
    fprintf(fp, "int main(void){int n;");
    for (int i = 0; i < 100; i++) {
        fprintf(fp, "n += foo%d();\n", i);
    }
    fprintf(fp, "return n;}");
    fclose(fp);
    return 0;
}

A teraz moje różne testy:

folio[~/Desktop/pragma] fluffy$ gcc pragma.c -DIFNDEF_GUARD
folio[~/Desktop/pragma] fluffy$ ./a.out 
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.164s
user    0m0.105s
sys 0m0.041s
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.140s
user    0m0.097s
sys 0m0.018s
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.193s
user    0m0.143s
sys 0m0.024s
folio[~/Desktop/pragma] fluffy$ gcc pragma.c -DPRAGMA_ONCE
folio[~/Desktop/pragma] fluffy$ ./a.out 
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.153s
user    0m0.101s
sys 0m0.031s
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.170s
user    0m0.109s
sys 0m0.033s
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.155s
user    0m0.105s
sys 0m0.027s
folio[~/Desktop/pragma] fluffy$ gcc pragma.c -DPRAGMA_ONCE -DIFNDEF_GUARD
folio[~/Desktop/pragma] fluffy$ ./a.out 
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.153s
user    0m0.101s
sys 0m0.027s
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.181s
user    0m0.133s
sys 0m0.020s
folio[~/Desktop/pragma] fluffy$ time gcc -E main.c  > /dev/null

real    0m0.167s
user    0m0.119s
sys 0m0.021s
folio[~/Desktop/pragma] fluffy$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin17.0.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Jak widać, wersje z #pragma once były rzeczywiście nieco szybsze do wstępnego przetworzenia niż #ifndef - tylko jedna, ale różnica była dość znikoma i byłaby znacznie przyćmiona przez ilość czasu, jaki zajmie zbudowanie i połączenie kodu. Być może przy wystarczająco dużej bazie kodowej może to prowadzić do kilku sekundowej różnicy w czasie kompilacji, ale między nowoczesnymi kompilatorami, które są w stanie zoptymalizować strażników #ifndef, faktem, że osy mają dobre pamięci podręczne dysków, a rosnącą szybkością technologii pamięci masowej, wydaje się, że argument wydajności jest dyskusyjny, przynajmniej na typowych systemach operacyjnych. system programisty w dzisiejszych czasach. Starsze i bardziej egzotyczne środowiska budowania (np. nagłówki hostowane na udziale sieciowym, budowanie z taśmy itp.) może nieco zmienić równanie, ale w tych okolicznościach wydaje się bardziej przydatne po prostu zrobić mniej kruche środowisko budowania w pierwszej kolejności.

Faktem jest, że {[3] } jest standaryzowany ze standardowym zachowaniem, podczas gdy #pragma once nie jest, a #ifndef obsługuje również dziwne przypadki systemu plików i rogu ścieżki wyszukiwania, podczas gdy {[2] } może uzyskać bardzo zdezorientowany przez pewne rzeczy, co prowadzi do nieprawidłowego zachowania, nad którym programista nie ma kontroli. Głównym problemem {[3] } jest to, że programiści wybierają złe nazwy dla swoich strażników (z kolizjami nazw itp.) i nawet wtedy jest całkiem możliwe, aby konsument API nadpisał te słabe nazwy używając #undef - być może nie jest to idealne rozwiązanie, ale jest to możliwe, podczas gdy #pragma once nie ma możliwości, jeśli kompilator błędnie pobiera #include.

Zatem nawet choć #pragma once jest wyraźnie (nieco) szybszy, nie zgadzam się, że to samo w sobie jest powodem do używania go nad #ifndef strażnikami.

EDIT: Dzięki informacjom zwrotnym od @ LightnessRacesInOrbit zwiększyłem liczbę plików nagłówkowych i zmieniłem test, aby uruchamiał tylko krok preprocesora, eliminując jakikolwiek mały czas dodawany przez proces kompilacji i linkowania(który wcześniej był banalny, a obecnie nieistniejący). Zgodnie z oczekiwaniami, różnica polega na to samo.

 24
Author: fluffy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-15 20:34:15

Generalnie nie zawracam sobie głowy #pragma once, ponieważ mój kod czasami musi być skompilowany z czymś innym niż MSVC lub GCC (Kompilatory systemów wbudowanych nie zawsze mają #pragma).

Więc i tak muszę użyć # include. Mógłbym również użyć #pragma once, jak sugerują niektóre odpowiedzi, ale nie wydaje się, aby było to zbyt wiele powodów i często będzie to powodować niepotrzebne ostrzeżenia na kompilatorach, które go nie obsługują.

Nie wiem, jakie oszczędności czasu może przynieść pragma. Słyszałem, że Kompilatory zazwyczaj rozpoznają, kiedy nagłówek nie zawiera nic poza komentarzami poza makrami guard i wykonają odpowiednik #pragma once W takim przypadku (np., nigdy więcej nie przetwarzając pliku). Ale nie jestem pewien, czy to prawda, czy tylko przypadek kompilatorów mógłby zrobić tę optymalizację.

W obu przypadkach łatwiej jest mi użyć # include guards, które będą działać wszędzie i nie martwić się o to dalej.

 15
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-17 18:42:22

Jest powiązane pytanie na które odpowiedziałem :

#pragma once ma jedną wadę (inną niż niestandardowe) i to jest, jeśli masz ten sam plik w różnych lokalizacjach (mamy to, ponieważ nasz system kompilacji kopiuje pliki wokół) wtedy kompilator pomyśli, że są to różne pliki.

Tutaj też dodaję odpowiedź na wypadek, gdyby ktoś potknął się o to pytanie, a nie o drugie.

 12
Author: Motti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:36

Myślę, że pierwszą rzeczą, którą powinieneś zrobić, to sprawdzić, czy to naprawdę ma coś zmienić, tj. powinieneś najpierw przetestować wydajność. Jedno z wyszukiwań w google wyrzuciło to .

Na stronie wyników kolumny są dla mnie slightly off, ale jasne jest, że przynajmniej do VC6 microsoft nie implementował optymalizacji include guard, której używały Inne narzędzia. Tam, gdzie osłona była wewnętrzna, trwało to 50 razy dłużej w porównaniu z tym, gdzie osłona include była zewnętrzna (zewnętrzne osłony include są co najmniej tak dobre jak #pragma). Ale rozważmy możliwy wpływ tego:

Zgodnie z prezentowanymi tabelami, czas otwarcia include i sprawdzenia jest 50 razy większy niż odpowiednik # pragma. Ale rzeczywisty czas, aby to zrobić, był mierzony na 1 mikrosekundę na plik w 1999 roku!

Więc, ile zduplikowanych nagłówków będzie miał pojedynczy TU? To zależy od Twojego stylu, ale jeśli powiemy, że przeciętny TU ma 100 duplikatów, to w 1999 roku płacimy 100 mikrosekund za TU. Dzięki ulepszeniom HDD jest to prawdopodobnie znacznie niższe, ale nawet wtedy z wstępnie skompilowanymi nagłówkami i poprawnym śledzeniem zależności całkowity łączny koszt tego projektu jest prawie na pewno istotną częścią czasu kompilacji.

Teraz, z drugiej strony, tak mało prawdopodobne, jak to może być, jeśli kiedykolwiek przejdziesz do kompilatora, który nie obsługuje #pragma once wtedy zastanów się, ile czasu zajmie zaktualizowanie całej bazy źródłowej mieć strażników zamiast # pragma?

Nie ma powodu, aby Microsoft nie mógł zaimplementować optymalizacji include guard w taki sam sposób, jak GCC i każdy inny kompilator(czy ktoś może potwierdzić, czy ich nowsze wersje implementują to?). IMHO, #pragma once nie robi nic poza ograniczeniem wyboru alternatywnego kompilatora.

 9
Author: Richard Corden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-20 08:45:47

#pragma once pozwala kompilatorowi na całkowite pominięcie pliku, gdy wystąpi ponownie - zamiast analizować plik, aż osiągnie wartośći # include.

Jako takie, semantyka jest trochę inna, ale są identyczne, jeśli są używane w sposób, w jaki mają być używane.

Połączenie obu jest chyba najbezpieczniejszą drogą, ponieważ w najgorszym przypadku (kompilator oznaczający nieznane pragmy jako rzeczywiste błędy, a nie tylko ostrzeżenia) trzeba by usunąć #pragma siebie.

Kiedy ograniczasz swoje platformy do, powiedzmy, "kompilatorów głównego nurtu na pulpicie", możesz bezpiecznie pominąć strażników # include, ale ja też czuję się nieswojo w tej kwestii.

OT: jeśli macie inne wskazówki/doświadczenia, którymi możecie się podzielić na temat przyspieszania kompilacji, byłbym ciekaw.

 4
Author: peterchen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-17 15:38:07

Dla tych, którzy chcieliby raz użyć # pragma i dołączyć strażników razem: jeśli nie używasz MSVC, to nie dostaniesz zbyt wiele optymalizacji z #pragma raz.

I nie powinieneś umieszczać "# pragma raz " w nagłówku, który powinien być dołączany wielokrotnie, a każde włączenie może mieć inny efekt.

Tutaj {[6] } jest szczegółowa dyskusja z przykładami na temat # pragma once use.

 1
Author: Deqing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-17 02:48:48

Na górze Wyjaśnienie przezKonrad Kleine powyżej.

Krótkie podsumowanie:

  • kiedy używamy # pragma once jest to duża część odpowiedzialności kompilatora, aby nie dopuścić do jego włączenia więcej niż jeden raz. Co oznacza, że po tym, jak wspomnisz o fragmencie kodu w pliku, nie jest to już twoja odpowiedzialność.

Teraz kompilator szuka tego fragmentu kodu na początku pliku i pomija go (jeśli już raz został dołączony). To zdecydowanie zmniejszy czas kompilacji (średnio i w ogromnym systemie). Jednak w przypadku mocks/środowiska testowego, utrudni implementację przypadków testowych, ze względu na kołowe zależności itp.

  • teraz, kiedy używamy #ifndef XYZ_H dla nagłówków, to bardziej deweloperzy są odpowiedzialni za utrzymanie zależności nagłówków. Co oznacza, że kiedykolwiek z powodu jakiegoś nowego pliku nagłówkowego, istnieje możliwość okrągłej zależności, kompilator po prostu oznaczyć niektóre komunikaty błędów "undefined .." w czasie kompilacji, i to jest użytkownik, aby sprawdzić logiczne połączenie / przepływ podmiotów i naprawić niewłaściwe obejmuje.

To zdecydowanie zwiększy czas kompilacji (w razie potrzeby skorygowania i ponownego uruchomienia). Ponadto, ponieważ działa na podstawie włączania pliku, na podstawie stanu zdefiniowanego" XYZ_H", i nadal narzeka, jeśli nie jest w stanie uzyskać wszystkich definicji.

Dlatego, aby uniknąć takich sytuacji, powinniśmy użyć, as;

#pragma once
#ifndef XYZ_H
#define XYZ_H
...
#endif

Tj. połączenie obu.

 1
Author: parasrish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:24