views:

414

answers:

8

I know that .h file is supposed to have:

  • class declarations,
  • function prototypes,
  • and extern variables (for global variables)

But is there some significance of making it a .h file? I tried renaming my .h file to a .c file and it still works.

We can name our file to be anything, but we choose to name it as a .h file.

Am I correct?

+5  A: 

It's just a convention - the "h" stands for "header". Like most conventions though, you would need to have a very good reason to contravene it.

Paul R
+1 for getting right to the point. The asker never used the word "header" so it's reasonable to assume that the gap in his/her logic was that class declarations, prototypes and externs can be thought of as the "header" to an implementing "body". All the other answers presuppose that this is understood.
gWiz
+1  A: 

The name of a file, as well as its extension, means absolutely nothing to compiler. You can name them h.main or anything else. Just remember to keep includes intact.

alemjerus
+10  A: 

The use of .h to name header files is just a convention. You will also see (probably on Unix-like platforms):

  • .hpp (the Boost library uses these)
  • .hxx (looks like h++ with the + signs tilted - cute, huh?)
  • .H (Unix is case sensitive so you can distinguish these from .h files)

Personally, I'd strongly advise sticking with .h. Particularly, don't use .H, or you will be in a world of pain if you ever need to port to case-insensitive file system.

anon
Keep in mind, however, that while .h is used for both C and C++, .hpp and .hxx are specifically for C++ header files. I don't know if .H (upper-case) is used too for C++ headers, following the convention of .C (upper-case) for C++ sources.
Matteo Italia
@Niel, I think the OP is asking about the difference between header files and source files -- judging by the first paragraph of his question.
Kornel Kisielewicz
@Matteo Yes it is - that was my point.
anon
@Kornel Not my take - he said "we can name our file to be anything, but we choose to name it as a .h file", which I read as a question.
anon
+1: @Niel - point
Kornel Kisielewicz
@Kprnel And it's "Neil", not "Niel" :-)
anon
@Neil: oh my, I'm really sorry, those exotic foreign names, y'know :D
Kornel Kisielewicz
@Neil: Ok, I just pointed out the whole C++ question because it wasn't really clear in your answer. BTW, I'd suggest to avoid the case convention for the motivation you already said, and use .hpp/.hxx headers (according to the .cpp/.cxx convention used in thre project) for the sake of clarity. Using .hpp/.hxx instead of simple .h is useful also if you work for editors whose default syntax highlighting scheme for .h is the one for C.
Matteo Italia
+11  A: 

While the exact naming is a convention, the difference between the treatment of header files and source files is not -- header files are not compiled into object files, but included in source files (collectively forming translation units). Moreover they may be included in multiple source files, so that multiple source files share the same definitions. The semantics of the files may be the same, but the compiler treats them differently, because of their usage.

As far as naming goes, personally I've seen at least these -- *.h, *.H (ugh), *.hpp, *.hxx, *.hh, *.inl (for normal headers, not just inlined code -- yuck). Usually accompanied by a matching object file extension.

Note that standard library headers don't have an extension -- e.g. string.

So it's all a matter of taste and conventions -- what you will #include, that will be included.

Kornel Kisielewicz
But isn't the question if the naming is just a convention? That's how I read it.
kotlinski
@kotlinski: yes, you are right. thats what I meant.
Lazer
@eSKay, then what was the mentioning of class declarations, function prototypes, and extern variables (for global variables) for? Couldn't you just ask "is naming .h and .c a convention?".
Kornel Kisielewicz
@Kornel Kisielewicz: Maybe I misframed the question. Anyways thanks for the answer. It is helpful, more so now after editing.
Lazer
@eSKay, no problem :-) -- I'll leave the reference to the difference between header files and source files however, so a lost soul reading it in the future wont get misguided by the answers.
Kornel Kisielewicz
But there is no difference between header and source files. The #include-directive is substituted with the text content from the file given there. After that, the header file became a part of the source file. The functional part is plain convention. Of course headers are not compiled by themselves, because by convention they shouldn't contain code. In fact, when I have a module that contains some larger subfunctionality, I often put these parts into there own .inc files containing the C-code, which are included in the C-file to where they belong. #include is text insertion, nothing more.
Secure
@Kornel Sorry I seem to have misread the answer's edit history - I've deleted my comment.
anon
@Secure, there is no difference in the files, exactly how there's no difference between C++ and Pascal files. The true difference lies in how the **compiler** treats them.
Kornel Kisielewicz
@Neil, no problem, I misread your name so we're even :P
Kornel Kisielewicz
@Secure, However, actually, good point. There is no difference in semantics, only in treatment by the compiler (one is linked, the other one is inlined).
Kornel Kisielewicz
@Kornel, .c-files are not "linked". I suggest you learn about the different compilation steps and what "translation unit" means. Here is a nice diagram: http://www.acm.uiuc.edu/sigmil/RevEng/ch02.htmlNote that the inclusion of the header files happens in the very first step (Preprocessor).
Secure
@Secure, having built a basic C compiler I know what a translation unit, object file and preprocessor works like -- it's just a matter of wording. inlined in this case meant inclusion.
Kornel Kisielewicz
@Kornel: It's "inlined" **because** it is `#include` d, not because it is a header file. There is nothing stopping you from putting definitions into a header and compiling it separately, or putting definitions/code into a ".cpp" and `#include`ing that ".cpp" into another, and hence compiling it. Header files are *used* by the compiler (as they become part of the compilation unit) and thus are indeed "compiled"... they contribute to the generated object code. The compiler doesn't "treat" them at all... you do.
@STingRaySC, your thinking's wrong - it wouldn't be a header file if it weren't `#include`d ;). Because of the lack of semantic difference between header file and source file `header file <=> #included file` -- at least there's nothing more than "opinioning" that can differantiate them. What you guys are arguing about is language semantics, not actual operation.
Kornel Kisielewicz
@Kornel, the equivalence sign is wrong. Every header file may be included, but not every included file is a header file. Same as with "linked", you should really care for the correct terminology. Experts will evaluate your knowledge by it, and using the terminology wrong will confuse and misguide the learners.
Secure
@Secure, prove your statement by something else than opinion.
Kornel Kisielewicz
@Secure, and while you're at it, downvote 99% of answers on SO for not using correct terminology. Not to mention 80% of the books on C++ ;>
Kornel Kisielewicz
@Kornel, now I'm unsure which specific statement you mean. I've made some more in this thread. And regarding the terminology, I only care for the threads where I'm involved. ;) But I guess you mean "But there is no difference between header and source files." Now that is easy to prove. Write a little Hello World and put it into "file.h". The only statement in "file.c" is #include "file.h". Compile "file.c" and see what happens. After that, the prove ball is on your side -- whatever the statement may be after the Xth edit...
Secure
To complete my prove, don't forget to compile file.h as well!
Secure
@Kornel: I believe that you understand the concepts, but you are not articulating them well. We are indeed arguing about language semantics (which *is* "actual operation" by the way). There is no *formal* definition of a "header file" -- it is borne from convention. Rest assured that the compiler does not recognize the concept, and hence does not "treat" them at all. Because your use of terminology is not accurate, it raises suspicion of your overall understanding. For someone who claims to recognize that 80-99% of all literature is inaccurate, you should recognize your own inaccuracies.
@Secure, sorry, the C++ standard explicitly states "headers **or** source files" in paragraph 2.9.1. Hence these sets are not the same. Unless you state that the standard is bullshit. C++ standard, N3000 we read "A source file together with all the headers and source files included via the preprocessing directive #include, less any source lines skipped by any of the conditional inclusion preprocessing directives, is called a translation unit." (this is mainly an example to show how vague are the terms we're relying on here, and that further yelling "my definition is teh truth" is pointless)
Kornel Kisielewicz
@STingRaySC, this whole discussion is pointless. Having vague terms like that, Secure argues with me that I "you should really care for the correct terminology" -- people, gimme a break.
Kornel Kisielewicz
Oh well, I gave you a do-it-yourself proof, you gave me -- what? It must be different because it is separately mentioned? I'm sure if there is a technical difference, then it will be explicitely described in the C or C++ Standard -- if not there, then where? Headers are only a concept to effectively organize code into libraries, given that the compiler can only work with a single translation unit a time. That's all there is about it. Keep going, nothing more to see here, really.
Secure
@Secure -- you can also typecast everything into void*, as well as write through a unallocated pointer. The standard doesn't allow it, but you can. That means that it's good, and the standard is bullshit. You gave me a proof that is based on an ill-formed C++ program, where you include a source file into another source file (no headers present). I gave you a passage from the C++ standard. EOT.
Kornel Kisielewicz
@Kornel: You should quit while you're ahead. What is an "unallocated pointer?" Every pointer has a value. Every pointer can be dereferenced. The standard **does** allow it. The language allows it. The behavior may be implementation-defined or undefined. But that is neither here nor there. `#include` ing a "source file" into another "source file" is **not** an "ill-formed C++ program." There are legitimate reasons to do it. Just stop speaking now. I've lost any interest in anything you may or may not say!
A: 

you compile and link your .h and .cpp to .obj. Then you give .h and .obj (your part) to your partner (your partner have no knowledge about the actual code), finally linker merge all the obj to a executable. .h is an well-known indicator to tell programmer that this file does not contain definition. we can use .xyz if the whole world accept it :-)

Tommy
A: 

Our big development projects #include cc files from cc file for classes with hundreds of methods. I didn't agree with it, but there were reasons.

Alex Brown
A: 

Moreover, when you have a makefile, its possible to say something like, compile all files ending in .c to object files, rather than specifying each separately. Now if you start naming you header files with .c extensions, then the make system may try to compile the header files into object files...

So to have separate *.h and *.c files keeps everything distinct and clear, not only for the programmer, but just as crucially for the make system, compiler and linker.

Ben
+1  A: 

I thought it might be worthwhile to expand the previous answer for Visual Studio-like IDEs.

For simplicity you should use naming conventions that are recognized by your programming IDE. The most important rules it has are the ones that tell it what compiler to use for which files. For example, .c will be compiled as C code, .cpp as C++, .cs as C#, .rc by the resource compiler and so on.

Naming something .h, or anything else not covered by one of the standard compiler selection rules, prevents a file being compiled on its own, which is what you want for header files. If you had tried your test of renaming your header to .c in Visual Studio, it would have been compiled for you unless you explicitly excluded it from the build.

There may be other tools available in your IDE - for example, tools to generate class diagrams, do source code analysis etc., and these may also have file naming conventions that you should stay compatible with.

Permaquid