2009-01-14 11 views

Odpowiedz

58

C++ standardowe nagłówki nie mają ".h" sufiks. Sądzę, że powodem jest to, że było wiele różnych pre-standardowych implementacji, które złamałoby standard. Zamiast wymagać, aby dostawcy zmienili swój wyjściowy nagłówek "iostream.h" (na przykład) pod kątem zgodności z normami (co złamałoby kod istniejącego użytkownika), komitet ds. Standardów zdecydował, że zrzuci sufiks (który, jak sądzę, nie już istniejąca implementacja już się odbyła).

W ten sposób istniejące, niestandardowe programy nadal działałyby przy użyciu niestandardowych bibliotek dostawcy. Gdy użytkownik chciał, aby ich standardy były zgodne ze standardami, jednym z kroków, które należy wykonać, jest zmiana dyrektywy "#include" w celu usunięcia przyrostka ".h".

Więc

#include <iostream>  // include the standard library version 
#include <iostream.h> // include a vendor specific version (which by 
         //  now might well be the same) 

Jak inne odpowiedzi wspomniałem, pisarze niestandardowych bibliotek może wybrać konwencji nazewnictwa, ale ja myślę, że chcą nadal korzystać „.h” lub „.hpp” (jak uczynił doładowania) na kilka powodów:

  1. jeśli & gdy biblioteka zostanie znormalizowana, standardowa wersja nie będzie automatycznie zastąpić poprzednią niestandardowy jednego (powodując złamany kod użytkownika według wszelkiego prawdopodobieństwa)
  2. wydaje się być konwencją (mniej więcej), że nagłówki bez sufiksu są standardowymi bibliotekami, a te z przyrostkiem (innym niż stare nagłówki C) są niestandardowe.

Zauważ, że podobny problem się stało, kiedy komisja poszedł do dodawania map hash do STL - okazało się, że istnieje już wiele (różnych) hash_map implementacje, które istnieją, więc zamiast wymyślanie standardowego, który rozkłada wiele rzeczy tam dzisiaj nazywają standardową implementacją "unordered_map". Przestrzenie nazw miały pomagać w zapobieganiu tego typu skokom przez obręcze, ale nie działały one wystarczająco dobrze (lub były używane wystarczająco dobrze), aby umożliwić im korzystanie z bardziej naturalnej nazwy bez łamania wielu kodów.

Należy zauważyć, że dla nagłówków "C" C++ umożliwia włączenie wariantu <cxxxxxx> lub <xxxxxx.h>. Ten, który zaczyna się od "c" i nie ma przyrostka ".h" umieszcza swoje deklaracje w przestrzeni nazw std (i prawdopodobnie globalnej przestrzeni nazw), te z rozszerzeniem ".h" umieszczają nazwy jako globalną przestrzeń nazw (niektóre kompilatory również umieścić nazwy w przestrzeni nazw std - nie jest dla mnie jasne, czy jest to zgodne ze standardami, chociaż nie widzę szkody).

+8

innym (prawdopodobnie nie głównym powodem :)) może wskazywać na fakt, że nagłówki standardowe nie muszą być w ogóle plikami. więc mogliby zdecydować się na upuszczenie ".h", ponieważ sugeruje rozszerzenie pliku. –

+4

To prawda, ponieważ ANSI C 1989, który ma przypis: "Nagłówek niekoniecznie jest plikiem źródłowym ..." Przy okazji - jest każdy świadomy kompilatora, który robi coś innego niż zwykłe pliki źródłowe dla standardowych nagłówków ? –

+1

@MichaelBurr Czy prekompilowane nagłówki nie pasowałyby do tego rachunku? –

16

Jeżeli plik o nazwie tuple to trzeba #include <tuple> jeśli jest nazwany tuple.h to trzeba #include <tuple.h>

To takie proste. Nie pomijasz żadnego rozszerzenia.

15

Zawiera plik o nazwie "krotka" - sam plik nie ma rozszerzenia.

Domniemany standard dla C++ obejmuje pliki to ich nazwy bez rozszerzenia .h; wielu autorów bibliotek postępuje zgodnie z tym standardem (STL itp.), ale niektórzy nie.

+1

O ile mi wiadomo, pliki Boost mają rozszerzenie .hpp. – mannicken

+1

Oh! Masz rację. Naprawię odpowiedź. – Crashworks

4

Moje zrozumienie polegało na tym, że #include tuple "wskaże" na tuple.h.

to sprawdzić: iostream vs iostream.h

+1

Połączony artykuł jest całkiem niezły. –

+1

Kompilator może zdecydować, że tak. Konwersja ciągu znaków w kodzie źródłowym w celu ukończenia ścieżki pliku dla systemu operacyjnego zależy od kompilatora. Przedrostek katalogów jest dość powszechny, ale rozszerzenie sufiksów nie jest – MSalters

+1

bardzo ciekawym artykułem, thx –

6

Nie ma nic szczególnego. Plik ma po prostu nazwę tuple.

Przyczyną tego ... że standardowe nagłówki bibliotek nie mają rozszerzenia plików z powodu namespace s.

Przestrzenie nazw zostały dodane do standardu C++ późno w grze ze standardem C++ 98, w tym std nazw że wszystkie standardowe jednostki biblioteczne zamieszkują w.

Kiedy średnia biblioteka został przeniesiony do nazw std, oznaczało to, że cały istniejący kod C++ zostałby złamany, ponieważ wszyscy oczekiwali, że biblioteka znajdzie się w globalnym obszarze nazw. Rozwiązaniem było pozostawienie samych starych plików nagłówkowych "dot-h" i zapewnienie biblioteki z pamięcią nazw w plikach bez rozszerzenia.

W ten sposób stary kod, który byłby #include<iosteam.h> mógł oczekiwać globalnego cout, podczas gdy nowy kod mógł #include<iostream> i oczekiwać std::cout.

4

Oprócz już opublikowanych drobnych odpowiedzi, należy zauważyć, że standard C++ nie wymaga dyrektywy "#include <iostream>", aby odczytać plik o nazwie "iostream" lub nawet "iostream.h". Można go nazwać "fuzzball". Lub nie może istnieć odpowiedni plik i definicje mogą być wbudowane w kompilator i aktywowane przez dyrektywę include.

-3

Folks,

Myślę, że sprawa jest: #include <lib> zawsze dobrze pre pends/lib/include do ścieżki wyszukiwania (The .h jest infrerred), natomiast #include <lib.h> wyszukiwań tylko -I < ścieżka dostępu >.

Proszę zauważyć, że mogę się mylić ... Tak właśnie myślę, że to działa (w Forte cc na Solaris).

+2

Myślisz źle - Standardowe C++ nie określa ścieżek wyszukiwania. –

+1

W miarę możliwości unikałem -1, przyznając, że możesz być w błędzie ... którym jesteś. :-) –

Powiązane problemy