* The dependencies (includes) of the implentation
* A list of function signatures, data structures it provides, etc
* Any constant definition specific to the module
Another "feature" of separating the header file from the implementation is that it guards against recursive includes, as the commenter above suggested.
So your calc.h and calc.c should look something like this: https://gist.github.com/jdiez17/2f093b2c8cc2913bb890
Main problem with dependencies in the headers is that if any header of your library include headers from the different libraries the user will have have to (1) have those headers, (2) probably configure their build to use them, even if they bring zero useful information for them.
Besides, in my mind it's the logical place to put it: the header file is almost like the "spec" or the "coversheet" of a .c. It includes the name, the authors, possibly a description of what it does, a list of functions and datatypes, so why not a list of dependencies as well?
Another reason is namespace pollution (if only for better autocomplete), and another is that you don't walk yourself into a situation where editing one header file suddenly gives you a zillion name lookup errors (because that's mildly annoying).
In C++, the biggest and most substantial benefit can be the effect on compile times.
It may just be that this is the specific way in which my mind works, but I find it easier to get a clearer picture of the file if I just read the .h. It would have a summary (in terms of comments and code, like function declarations) and a list of includes.
>it is often very useful if you can immediately see a short list of .c files that could possibly access the interface exposed by a particular header file.
If you wanted to see which files use the interface in that header file directly, you can scan your headers for ones that include it explicitly, instead of working backward from the header. And a similar thing with the autocomplete problem: only load the header files mentioned in thing.h (assuming you're editing thing.c).
The increased compilation time is a good argument. I don't know any good way to mitigate it, but all these three problems sound like engineering problems to me, rather than a problem intrinsic to this approach.
Your .c files that use the interface will often be including it implicitly though, projects very quickly drift in that direction.