3 ms·
(Apoligies, HN is mangling my comment when I try to include C style comments, so I'm using C99/C++ style ones) You should include whatever .h files you need in
by gte910h 16y ago
(Apoligies, HN is mangling my comment when I try to include C style comments, so I'm using C99/C++ style ones)
You should include whatever .h files you need in every file that uses them (things like stdlib and stdio for sure when you're using them). This makes it so you have fewer interfile dependencies which keeps your compile times down. So you only include other .h files in .h files if you need the types in them (or put a blank prototype in for it, aka struct foo;). Otherwise you include .h files only in .c files.
Feels hairy, yes, but that's the correct way to do it. By doing it creative ways, you cause great pain down the road (especially compilation times, and hunting for simple bugs). If you're only using one or two functions, sometimes people just prototype the function:
// some people just would stick this prototype in their .c
//file they're writing if they need nothing else in math.h
double sqrt(double x);
I think you're missing something about C there though the way you talk about compiling things.
h files aren't really compiled at all. They are substituted into files where they're #included. You can actually write your entire project without them if you really want to (not suggested, but you can) by just putting prototypes for the functions you call at the top of the c files that need to copy them. That's actually why its important to put guard include statements at the beginning and end of h files to make sure they aren't included more than once. A properly written h file shouldn't cause compiler errors when you do this to it:
#include "foo.h"
#include "foo.h"
#include "foo.h"
#include "foo.h"
#include "foo.h"`
The way you make it proper is you do this the top:
#ifndef __FOO_H__
#define __FOO_H__
and this at the bottom
#endif // __FOO_H__
Many IDEs do this automatically and vim and emacs both have plugins you can get to do this. Robert Pike's piece is from 1989, when computers ran much slower. The lexical analysis time from this is not worth talking about anymore.
Structure:
Generally C is structured with a main .c file which has a few functions related to start up in it and includes of header files in other modules which are needed. Each of the .c files includes the header files it needs, from either internal project modules, or from system level header files (aka <thingsInAlligatorBrackets.h>). Generally each .c file is a module, although in Object Oriented C, you may find modules built up of several different c files with each "class family" in a single .c files. Modules are purely conceptual in C.
Some C people get macro happy. Do no do this. It is unclear to the rest of the C developing universe. Modern C compilers can do inline substitution quite well, often giving better performance than your macros. When people get macro happy, they end up making a file like "GlobalMacros.h" or even if they don't, they just have a lot of constants and end up with "LotsOfConstants.h" included in everything.
Resist the urge to put your .h includes in there but NOT in the files that actually depend on it. If you do that you break code if that .h file is ever taken out.
As far as final compilation goes: Every C file is compiled into an object file then linked using the linker. Alternatively, groups of .c files are compiled into .o files then linked into .a files (static libraries). These libraries are then linked in during the final compilation step.
- loup-vaillant 16y agoTo write code, skip 2 or more characters at the beginning of the line, Markdown style. #include "foobar.h" /* no mangling */ http://news.ycombinator.com/formatdoc http://news.ycombinator.com/formatdoc
- gte910h 16y agoThanks. I was trying to do the methods explained on daring fireball about markdown, but they weren't working so I just went C99 style.
- TheNewAndy 16y agoYour header guard is bad (but not horribly so). Identifiers with two underscores at the beginning are reserved in the C90 standard (as are identifiers with one underscore followed by an upper case letter). Your comments are also only valid in C99. Unless you have a really good reason, then you should use the block style comments (and I can't think of any good reason). (oh, maybe I should have read your very first sentence... yes that seems like a good reason :-)
- gte910h 16y ago>Your header guard is bad (but not horribly so). Identifiers with two underscores at the beginning are reserved in the C90 standard (as are identifiers with one underscore followed by an upper case letter). That's not actually the header guard that pops out when I put them in (as I do so automatically using vim code similar to that described below), however you are correct that you have a chance to clash with compiler dependent info macros (such as __LINE__) if you use a double underscore before a header guard. I'm going to see if I can edit the post for those who don't see this exchange below. http://yvan.seth.id.au/Entries/Technology/Code/Vim_Header_Guard_Trick.html http://yvan.seth.id.au/Entries/Technology/Code/Vim_Header_Gu... I was trying to simplify yet avoid the UTIL_H clash problem and made an error there.