All inclusive header files?

J

James Kuyper

On 3/8/2011 10:23 AM, Kenneth Brody wrote: ....

APL. Since nobody can read it, nobody will detect any mistake
you may have made.

APL was my first programming language. If fit perfectly into my mindset.
I understood the basics of the language after just one pass through the
reference manual, before I'd written a single line of code (yes, that is
the way I normally did such things). Coming from that background, I
found C to be excessively verbose by comparison. :)

I wrote some APL code in the late 70's, which I happened to save. I came
across that code again in the late 90's, having written not a single
line of APL in 15 years. Modifying the code would have required
re-acquainting myself with the language, but I could read it without any
trouble.
 
M

Malcolm McLean

That's
much less of an issue now, though it hasn't disappeared completely: as
computers and compilers have gotten more powerful, headers have gotten
longer and more complex.
Some headers are very intricate documents, usually because they have
to do a lot of conditional defines to support various platforms.

This isn't good. A simple list of functions and structures in a module
is useful.
 
J

James Kuyper

Some headers are very intricate documents, usually because they have
to do a lot of conditional defines to support various platforms.

This isn't good. A simple list of functions and structures in a module
is useful.

While that's certainly true, I was mainly thinking of headers which get
more complex because the library's interfaces have become more complex,
and also of the fact that modern programs often make use of a larger
number of different libraries than older ones did.
 
B

BartC

James Kuyper said:
Inserting a #include for the proper header IS part of using those
functions;

An unnecessary part. Why can't someone write:

#include <stdheader.h>

or (my preference) write nothing at all, and still be able to use the 1000+
standard functions immediately without this palaver of adding and removing
#include lines?

(And to have it standardised so the code can be shared.)

I'm not opposed to reducing the number of standard headers needed; that
number was clearly influenced by the fact that, when the library was first
being developed, unnecessarily #including even just a few more definitions
than needed could significantly slow a compilation. That's much less of an
issue now, though it hasn't disappeared completely: as computers and
compilers have gotten more powerful, headers have gotten longer and more
complex. However, the optimum size of a header has definitely increased
substantially, possibly by orders of magnitude.

In gcc, the standard headers come to 5000 lines. In lcc-win, about 3000
lines.

When someone writes:

#include <windows.h>

(notice just one header to remember!), that could typically include 25000
lines. When you include headers belong to the application, the overhead of
the standard headers becomes even less significant.

And there are any number tricks the compiler can do to reduce the impact of
compiling that much stuff, especially the standard headers where the names
could be simply be part of the compiler.
 
K

Keith Thompson

BartC said:
An unnecessary part. Why can't someone write:

#include <stdheader.h>

or (my preference) write nothing at all, and still be able to use the 1000+
standard functions immediately without this palaver of adding and removing
#include lines?

(And to have it standardised so the code can be shared.)

Because <stdheader.h> doesn't exist and has not been standardized.

When C was first developed, including excessive headers was a big deal;
it could substantially slow down compilation times.

If the committee decided to add it to the standard tomorrow, it would
have no effect on programmers until enough implementers implemented it;
that would mean getting agreement from gcc, Microsoft, lcc{,-win}, and I
don't know how may other providers. And code written to depend on
<stdheader.h> would still fail to compile with older implementations
that don't yet support it (those won't go away any time soon).

It's easy enough to write a <stdheader.h> file (but note that <assert.h>
is a special case), either as part of an implementation or, as a
workaround, as part of a project. But that doesn't necessarily solve
the problem. If I want to compile something that uses <stdheader.h>,
and my system doesn't have it, I might not even have the ability to add
it to the location where the compiler searches for system headers; I
might have to manually edit the source to change <stdheader.h> to
"stdheader.h".

I am *not* aruguing that it's not a good idea, just trying to answer
your question.

I'm personally undecided on the issue, but if it existed I wouldn't
have any strong objection to using it. (One drawback is that,
currently, you can look at the top of a source file and get a
pretty good idea of what parts of the standard library it uses;
combining everything into <stdheader.h> would lose that ability.)
Also, most C code depends on system-specific headers; <stdheader.h>
wouldn't address that.

(And personally, I've never found getting the #include directives
right to be much of a burden.)
 
I

Ian Collins

An unnecessary part. Why can't someone write:

#include <stdheader.h>

or (my preference) write nothing at all, and still be able to use the
1000+ standard functions immediately without this palaver of adding and
removing #include lines?

(And to have it standardised so the code can be shared.)

How often do you write (or read) code that only requires standard
headers? Even if the were only one standard header, you would still
have to include system and project headers.

I'd wager the majority of code out there only uses the standard headers
<stdlib.h> and <stdio.h> along with considerably more local headers. So
combining standard headers wouldn't gain you much.
 
H

Heikki Kallasjoki

In gcc, the standard headers come to 5000 lines. In lcc-win, about 3000
lines.

When someone writes:

#include <windows.h>

(notice just one header to remember!), that could typically include 25000
lines. When you include headers belong to the application, the overhead of
the standard headers becomes even less significant.

FWIW, and somewhat non-topically, the fact that <windows.h> contains an
incredible amount of stuff (including cryptography, networking and
whatnot) means they have had to add some arguably ugly hacks, such as
putting large pieces of the header inside "#ifndef WIN32_LEAN_AND_MEAN"
blocks, primarily to make it possible to save on compile times. This
does not exactly make it a stellar example of how the "single header
file for everyhing" approach would be better. (There are also some
other problems, like the fact that <windows.h> includes <winsock.h>,
which is incompatible with the later <winsock2.h>...)

(Admittedly the standard C headers are quite a lot smaller set.)
 
J

James Kuyper

On 3/9/2011 6:06 AM, James Kuyper wrote:
[...]
I'm not opposed to reducing the number of standard headers needed; that
number was clearly influenced by the fact that, when the library was
first
being developed, unnecessarily #including even just a few more
definitions
than needed could significantly slow a compilation. That's much less
of an
issue now, though it hasn't disappeared completely: as computers and
compilers have gotten more powerful, headers have gotten longer and more
complex. However, the optimum size of a header has definitely increased
substantially, possibly by orders of magnitude.

I'm not sure if your use of "optimum" is correct here. I hereby propose
that the "optimum" size of a (standard) header is 1 line. For example,
<stdio.h> could consist solely of:

#pragma stdheader "stdio.h"

I didn't bother to specify what I was talking about in any detail,
because it isn't really worth the trouble of working out those details.

However, the "size" I was thinking was not in terms of the number of
lines of source code. It could be more accurately measured in terms of
the number of tokens that result from inclusion of the header after the
end of translation phase 4. On some systems, standard headers bypass
the standard's translation phases completely, and simply cause the
appropriate in-memory structures representing the appropriate symbol
tables to be populated, just as-if those phases had actually been
carried out. When that is the case, what I'm thinking of is a token
count of a equivalent header that actually did pass through translation
phase 4.

The optimization I was talking about takes into consideration the
trade-offs between the time wasted during every compilation processing
definitions and declarations that aren't actually used, and searching
past unused symbol table entries while looking of symbols that are
actually used, versus the time wasted during the writing of a program
inserting the appropriate #include directives; properly, that trade-off
should be evaluated taking into consideration that CPU time is a lot
less expensive than developer time.

I also consider name space pollution a significant issue for the
developer, and as such it's probably more important than the compiler's
processing time, but the "optimum" I was talking about was meant to be
determined without reference to that issue.
 
J

James Kuyper

An unnecessary part. ...

Try leaving it out, and see what happens. In C as it's currently
designed the #include is VERY necessary.
... Why can't someone write:

#include <stdheader.h>

or (my preference) write nothing at all, and still be able to use the
1000+ standard functions immediately without this palaver of adding and
removing #include lines?

They could, after a re-design of the language. Once that re-design has
been completed, it would be possible to say that you "know perfectly
well how to use" puts(), even if you were unaware of what standard
header it used to be declared in.

However, in the C language as it currently defined, if you don't know
which header that is, your knowledge of how to use puts() is less than
perfect (but no more so than my own).
 
G

Georg Bauhaus

James Kuyper said:
They could, after a re-design of the language. Once that re-design has
been completed, it would be possible to say that you "know perfectly well
how to use" puts(), even if you were unaware of what standard header it
used to be declared in.

What if I need a custom tailored run-time library.
A stdheader something contributes nothing to
which parts to include in this run-time library.
On the contrary.

An all inclusive header does prove that a programmer
is both not so skilled in using a good editor (which will
save all the typing through text templates) and that
he is unaware of software maintenance needs.
 
M

Malcolm McLean

How often do you write (or read) code that only requires standard
headers?  Even if the were only one standard header, you would still
have to include system and project headers.
All the time. That's because I separate code that does IO from code
that does calculations. Because of the types of programs I write, the
IO tends to be rather trivial, the calculations complex. However even
a video game usually has a non IO "world" embedded in it.
 
B

BartC

James Kuyper said:
Try leaving it out, and see what happens. In C as it's currently designed
the #include is VERY necessary.


They could, after a re-design of the language. Once that re-design has
been completed, it would be possible to say that you "know perfectly well
how to use" puts(), even if you were unaware of what standard header it
used to be declared in.

If the language was redesigned, it wouldn't have a concept of a 'header
file' to accompany every built-in function; you'd be able to use such
functions in the same way you'd use an if or for statement.

And there would be another mechanism to replace built-in functions with
user-defined ones.
However, in the C language as it currently defined, if you don't know
which header that is, your knowledge of how to use puts() is less than
perfect (but no more so than my own).

It's either stdio.h or stdlib.h. So I just include both, as I suspect do
many others...
 
J

James Kuyper

If the language was redesigned, it wouldn't have a concept of a 'header
file' to accompany every built-in function; you'd be able to use such
functions in the same way you'd use an if or for statement.

I was only talking about the standard library, which has headers, but
not necessarily header files. I would hope, for the sake of backwards
compatibility, that it would retain the concept of standard headers,
even if they're rendered unnecessary. Otherwise essentially all legacy
code is going to have syntax errors.

Header files are a different issue; if you're going to abandon the whole
concept of #include, what alternative mechanism do you propose for
sharing source code between different translation units? Must shared
code be physically duplicated, or are you proposing to do away with
translation units, instead treating the combination of all source code
files as a single translation unit?
It's either stdio.h or stdlib.h. So I just include both, as I suspect do
many others...

My code uses an average of between three or four standard headers per
source code file - it probably makes more use of <math.h> and less use
of <stdio.h> than your code.
 
M

Malcolm McLean

Or are you proposing to do away with
translation units, instead treating the combination of all source code
files as a single translation unit?
The model of physical file equals translation unit works well for
medium-sized programs, but it doesn't scale.

Imagine I'm doing a lot of string handling. Obviously I'm going to
need a strdup().

Now if the program is medium sized, I can declare strdup as a static
and copy and paste the code to each .c file that depends on it. Or I
can write a "stringutils.c" file and #include the header in all my
string units. Either way works acceptably.
But neither solution scales. Copy and paste only works for a few
trivial functions. Declaring functions global pollutes the namespace
and creates a web of dependencies - strdup ends up depending on some
customised memory allocation routine which pulls in the page caching
library which pulls in manufacturers' custom micro-code, all to
duplicate one silly filename.
 
I

ImpalerCore

The model of physical file equals translation unit works well for
medium-sized programs, but it doesn't scale.

Imagine I'm doing a lot of string handling. Obviously I'm going to
need a strdup().

Now if the program is medium sized, I can declare strdup as a static
and copy and paste the code to each .c file that depends on it. Or I
can write a "stringutils.c" file and #include the header in all my
string units. Either way works acceptably.

I disagree. In general copy and paste is the more evil of those two
options, particularly when multiple people maintain source code with
different levels of knowledge and expertise with the code base. For
small projects with one maintainer, you can get away with it. If you
want to do it in a larger project, you better have documentation
preferably in ALL CAPS at every function definition referencing the
file location of every other copy, and even then I'd be very nervous.
And hopefully "stringutils.c" is linked via a library so you don't
have multiple versions of that file floating around.
But neither solution scales. Copy and paste only works for a few
trivial functions. Declaring functions global pollutes the namespace
and creates a web of dependencies - strdup ends up depending on some
customised memory allocation routine which pulls in the page caching
library which pulls in manufacturers' custom micro-code, all to
duplicate one silly filename.

Agree with what you say, but what would the alternative would be.

Best regards,
John D.
 
B

BartC

James Kuyper said:
On 03/10/2011 05:44 AM, BartC wrote:
Header files are a different issue; if you're going to abandon the whole
concept of #include, what alternative mechanism do you propose for sharing
source code between different translation units?

No, '#include' would still be in, being part of the preprocessor, it just
doesn't need to be a prerequisite for the use of built-in functions. In fact
built-in functions could be defined as those not requiring an explicit
header or library to be declared.

(Of course if a redesign was radical, it might well do away with the
preprocessor. I don't think that would be popular though.)
 
M

Malcolm McLean

And hopefully "stringutils.c" is linked via a library so you don't
have multiple versions of that file floating around.
The problem is that the scripting team is working on a basic
interpreter, whilst the AI teeam is working on a command line parser.
Eventually we'll put the projects together in an adventure game - the
parser collects input from the user, the basic interpreter allows the
games designers to soft code object behaviour.

Now both are probably going to need a strdup(). The problem with the
stringutils.c solution is that the teams need to talk to each other to
make sure that the file is kept in synch.
It's easier to copy and paste a static strdup().

However strdup is an exceptional case - really it's a missing standard
library function, and it's very trivial. We don't want to create a
dependency just so we can take a copy of a string.
 
T

Tim Rentsch

Malcolm McLean said:
I notice that there are a lot of header files eg. <stdio.h>,
stdlib.h> and <conio.h> which a programmer must include
in order to use certain commands. Is there a all-inclusive
file?
No.
If we were designing C from scratch we'd probably just [snip]

His Majesty McLean employs a majestic plural (also called
a "royal 'we'") -

http://en.wikipedia.org/wiki/Majestic_plural

(<ot>I was amused by the Admiral Rickover quote.</ot>)
 
T

Tim Rentsch

Bartc said:
[snip]

So like I said, it's an annoyance than an all-inclusive header file is not
standardised.

If it is an annoyance (which personally I don't think it is),
it is so far down the priority list that you'd need a
telescope to see it.
 
M

Malcolm McLean

No.
If we were designing C from scratch we'd probably just [snip]

His Majesty McLean employs a majestic plural (also called
a "royal 'we'") -
Strictly it should be "If one were to design C from scratch ..."

However even I can't aspire to such heights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,085
Messages
2,570,597
Members
47,220
Latest member
AugustinaJ

Latest Threads

Top