Do czego służy „stdafx.h” w Visual Studio?

500

Nazwany plik stdafx.hjest generowany automatycznie, kiedy uruchamiam projekt w Visual Studio 2010. Potrzebuję stworzyć międzyplatformową bibliotekę C ++, więc nie mogę / nie mogę użyć tego pliku nagłówka.

Do czego stdafx.hsłuży? Czy mogę po prostu usunąć ten plik nagłówka?

prosseek
źródło
2
Jeśli dostaję błąd kompilacji związany ze plikiem
stdafx.h
6
Artykuł: StdAfx.h dla nowicjuszy - viva64.com/en/b/0265
Możesz użyć pliku nagłówka w porządku na innych platformach, dla nich jest to zwykły plik nagłówka. Po prostu nie zapewnia żadnej poprawy wydajności.
Andrea

Odpowiedzi:

826

Wszystkie kompilatory C ++ mają jeden poważny problem z wydajnością. Kompilowanie kodu C ++ jest długim, wolnym procesem.

Kompilowanie nagłówków zawartych w plikach C ++ jest bardzo długim i wolnym procesem. Kompilowanie ogromnych struktur nagłówków, które tworzą część Windows API i innych dużych bibliotek API jest bardzo , bardzo długim i wolnym procesem. To, że trzeba to robić w kółko, w kółko dla każdego pojedynczego pliku źródłowego Cpp, jest zapowiedzią śmierci.

Nie jest to unikalne dla systemu Windows, ale stary problem, z którym zmagają się wszystkie kompilatory, które muszą się kompilować z dużym interfejsem API, takim jak Windows.

Kompilator Microsoft może rozwiązać ten problem za pomocą prostej sztuczki zwanej wstępnie skompilowanymi nagłówkami . Sztuczka jest całkiem sprytna: chociaż każdy plik CPP może potencjalnie i prawnie nadać nieco nieco znaczenie łańcuchowi plików nagłówkowych znajdujących się na wierzchu każdego pliku Cpp (np. Poprzez różne makra #definiowane przed załącznikami lub przez włączenie nagłówków w innej kolejności), najczęściej tak nie jest. Zazwyczaj mamy dziesiątki lub setki dołączonych plików, ale wszystkie mają mieć takie samo znaczenie dla wszystkich plików Cpp kompilowanych w Twojej aplikacji.

Kompilator może znacznie zaoszczędzić czas, jeśli nie będzie musiał zaczynać kompilacji każdego pliku Cpp, a jego dziesiątki dołączonych dosłownie za każdym razem.

Sztuczka polega na wyznaczeniu specjalnego pliku nagłówka jako punktu początkowego wszystkich łańcuchów kompilacji, tak zwanego pliku „prekompilowanego nagłówka”, który zwykle jest plikiem o nazwie stdafx.h ze względów historycznych.

Po prostu wypisz wszystkie swoje wielkie, ogromne nagłówki dla swoich interfejsów API w pliku stdafx.h, w odpowiedniej kolejności, a następnie uruchom każdy z plików CPP na samej górze z #include "stdafx.h", przed jakąkolwiek znaczącą treścią (prawie jedyną dozwoloną wcześniej rzeczą jest komentarze).

W tych warunkach, zamiast zaczynać od zera , kompilator zaczyna kompilować od już zapisanych wyników kompilacji wszystkiego stdafx.h.

Nie wierzę, że ta sztuczka jest unikalna dla kompilatorów Microsoft, ani nie uważam, że była to oryginalna wersja.

Dla kompilatorów firmy Microsoft, ustawienia, które kontroluje wykorzystanie prekompilowanymi nagłówków jest kontrolowany przez argument wiersza poleceń dla kompilatora: /Yu "stdafx.h". Jak możesz sobie wyobrazić, użycie stdafx.hnazwy pliku jest po prostu konwencją; możesz zmienić nazwę, jeśli chcesz.

W Visual Studio 2010 to ustawienie jest kontrolowane z GUI poprzez kliknięcie prawym przyciskiem myszy projektu CPP, wybranie „Właściwości” i przejście do „Właściwości konfiguracji \ C / C ++ \ Prekompilowane nagłówki”. W przypadku innych wersji programu Visual Studio lokalizacja w interfejsie GUI będzie inna.

Pamiętaj, że jeśli wyłączysz prekompilowane nagłówki (lub uruchomisz projekt za pomocą narzędzia, które ich nie obsługuje), nie spowoduje to, że twój program będzie nielegalny; oznacza to po prostu, że Twoje narzędzie za każdym razem kompiluje wszystko od zera.

Jeśli tworzysz bibliotekę bez zależności systemu Windows, możesz łatwo skomentować lub usunąć #includes z stdafx.hpliku. Nie ma potrzeby usuwania pliku jako takiego, ale oczywiście możesz to zrobić, wyłączając powyższe ustawienie nagłówka prekompilacji.

Euro Micelli
źródło
6
Nawet jeśli używałeś tylko plików ze standardowej przestrzeni nazw, zyskujesz
przewagę
11
omg, naprawdę fajna odpowiedź. szukałem standardowego kompilatora c. okazuje się, że mogę wyłączyć rozszerzenia micro $ oft z właściwości projektu, zmienić kompilator z „auto” na „c”, a ty masz prawie „standardowy” kompilator i IDE.
EKanadily
4
@Rishi: przez „linię”, masz na myśli #include "stdafx.h"? Jasne, ale to tylko standardowy #include. Część „MS extension” to tylko optymalizacja wydajności kompilatora; nie zmienia semantyki posiadania pliku nagłówkowego, który nazywa się „stdafx.h”. Pamiętaj, że jeśli usuniesz dołączenie, a Twój kod zależy od wszystkiego, co zostało dołączone przez stdafx.h, będziesz musiał dołączyć to bezpośrednio.
Euro Micelli,
4
@ Youda008, niezupełnie prawda. Przed skompilowaniem pliku kodu zawartość nagłówków jest po prostu i dosłownie „wklejana” w miejscu, w którym znajdują się #includeone w pliku źródłowym (wykonywane przez ten sam krok „preprocesora”, który ocenia makra). Wynikowy plik całkowity jest następnie przekazywany do faktycznego kompilatora, który nigdy nie widzi pliku nagłówkowego jako osobnej jednostki. Deklaracje umieszczasz tylko w pliku nagłówkowym, ponieważ to działa dobrze w pliku nagłówkowym - jest to konwencjonalna zasada. Spróbuj! Utwórz plik nagłówka z całym programem, a następnie utwórz plik źródłowy, który ma tylko #include. Kompiluje się dobrze.
Euro Micelli,
28
Ciekawość historyczna. Nazwa stdafx.h pochodzi z około 1992 roku, kiedy MFC nazywało się „Application Framework Extensions” przed wydaniem. Visual Studio 2015 nadal domyślnie nazywa się ...
Ker
48

Jest to „wstępnie skompilowany plik nagłówka” - wszystkie nagłówki zawarte w pliku stdafx.h są wstępnie przetwarzane w celu zaoszczędzenia czasu podczas kolejnych kompilacji. Możesz przeczytać więcej o tym tutaj na MSDN .

Jeśli budujesz aplikację wieloplatformową, zaznacz „Opróżnij projekt” podczas tworzenia projektu, a Visual Studio w ogóle nie umieści żadnych plików w projekcie.

Casablanka
źródło
15
W tym pliku nie ma nic, co nie działałoby na innych platformach. Może to spowolnić kompilację, jeśli kompilator nie obsługuje wstępnie skompilowanych nagłówków, ale nie powinien go złamać. To tylko plik nagłówka, który zawiera inne pliki nagłówka.
ustalono
2
@detunized: Może moja odpowiedź brzmiała inaczej, więc dziękuję za wyjaśnienie tej części.
casablanca
3

„Stdafx.h” to prekompilowany nagłówek. Zawiera plik dla standardowych plików dołączanych do systemu i dla specyficznych dla projektu plików dołączanych, które są często używane, ale są rzadko zmieniane. Co skraca czas kompilacji i niepotrzebne przetwarzanie.

Wstępnie skompilowany nagłówek plik stdafx.h jest zasadniczo używany w programie Microsoft Visual Studio, aby informować kompilator o plikach, które zostały skompilowane, i nie trzeba go kompilować od zera. Możesz przeczytać więcej na ten temat

http://www.cplusplus.com/articles/1TUq5Di1/

https://docs.microsoft.com/en-us/cpp/ide/precompiled-header-files?view=vs-2017

Akash das
źródło
-10

Właśnie wpadłem na to sam, ponieważ próbuję stworzyć sobie szkielet bez kości, ale zacząłem od utworzenia nowej opcji programu Win32 w Visual Studio 2017. „stdafx.h” jest niepotrzebne i powinno zostać usunięte. Następnie możesz usunąć głupie pliki „stdafx.h” i „stdafx.cpp” znajdujące się w Eksploratorze rozwiązań, a także pliki z projektu. Na swoim miejscu musisz położyć

#include <Windows.h>

zamiast.

Adam H.
źródło