Alright, thanks robert. I guess I've been trying to reconcile some odd
things today. Let me ask this:
#include <limits.h>
#include <limits.h>
...
Does only one copy of limits.h get pasted in at the top of the program?
Well, if you were including something other than a standard header (or
assert.h), and not making use of non-standard extensions, you would
certainly get two copies. It's a bit more complicated for the
standard headers.
The important thing is that limits.h, and the other standard headers
(again excepting assert.h), are written/implemented in such a way that
it doesn't make any difference that you included them twice.
Basically the most common approach is to put some sort of guard that
causes the second (and subsequent) includes to do nothing. The
typical guard macros:
#ifndef _LIMITS_H_GUARD
#define _LIMITS_H_GUARD
#define INT_MAX...
...
#endif _LIMITS_H_GUARD
are a common approach. Note that this *does* include two copies of
the header, but the second is hollowed out by the guard.
Some implementations have a non-standard extension like MSVC's #pragma
once, which causes subsequent inclusions of that file to be physically
suppressed. MSVC, for example, happens to use that in its
implementation of limits.h, although that what the implementation does
inside the standard headers is up to the implementation, and may
involve all sorts of implementation specific magic. Actually the MSVC
case is more complicated - the headers are coded in such a way that if
you run then through an old version of the compiler, they'll use the
traditional guard macros instead. Some other implementation specific
mechanism for making the second include have no effect might be used
as well.
But the point is that the behavior meet the rule that "Headers ...
each may be included more than once in a given scope, with no effect
different from being included only once ... (assert.h exception)".
As a side note, mucking about in forbidden ways may break that "as if
included only once behavior." For example, if you #undef the guard
macro between the two definitions (which you're not allowed to do
since the guard macro should always be in the reserved namespace, but
will be possible to do on most implementations anyway), the second
include may well do something odd. Or it may not.
But ignoring extensions like #pragma once, and the fact that the
implementation is allowed to handle the standard headers specially (as
I mentioned before, they don't actually have to be files like other
headers, just so long as the include does what's expected), an
#include just pastes the requested header file into the source code,
each and every time you ask.
As a general comment, using header guards is pretty common, even on
headers you write yourself.
Note the other rule about the standard headers is that you may include
them in any order, and it doesn't make any difference past the last
inclusion (obviously references to things in a header have to occur
after that header is included).