Do we need to continue to include stdio.h in C files ?

  • Thread starter karthikbalaguru
  • Start date
C

CBFalconer

Bartc said:
.... snip ...

Is there any program, that does any useful work, that doesn't
need stdio.h?

I don't know, but there can be. Write routines that read a
keyboard, and write chars to a display. That is sufficient to
communicate with the program. I imagine you will find such systems
in the embedded world. Note that the keyboard may be only two push
buttons.
 
L

lawrence.jones

Ben Bacarisse said:
I am not sure when the function call operator switched to taking a
pointer, but it simplified a few things in semantics.

C89, for precisely that reason. (And besides, everyone already knew
that functions are really called by address anyway.)
 
D

Dik T. Winter

> In the category of "if only they had" is if only they had put all
> of an include file's identifiers in a struct name space pollution
> wouldn't have been nearly as much of a problem. I grant that
> writing io.printf rather than printf or math.cos rather that cos
> takes more characters, but so what.

And before very long a statement like the Pascal with statement would have
been invented:
with io; with math;...
Would including "math." in with every math function make a floating-point
expression that uses a few functions make any clearer?
 
D

Dik T. Winter

> news:[email protected]... ....
>
> Don't know too many recent languages, but from what I remember of Fortran,
> Algol, Cobol and Pascal, they didn't seem to need all this business of
> having to declare things that are considered part of the language. And this
> was on machines not much more advanced that what C was developed on.

But in Algol 68 it was good that the compiler had the declarations of
everything in front of itself and compiled it in a way similar to everything
similar.

All operators could be defined with their assigned priorities. That made
it possible that when the compiler saw an operator it ony had to use a
single method to find priority and meaning of the operator. So if a
programmer redefined the priorities of "+" and "*" the compiler had only
to follow the standard search path to find how to parse the expression:
"a + b * c".
And when it saw the expression 5 + 8 it could follow the standard search
path to find what operator was actually used.

Note that the standard operators and standard functions are *defined* in
the standard environment in Algol 68 in pseudo-Algol 68 according to the
standard. In the compiler I used, the standard environment was indeed
written in Algol 68 with only two extensions:
(1) Allowing the letter "aleph".
(2) Allowing inline pseudo assembly for operators (which also could be used
in user programs).
and so pretty literally followed the standard.

(The pseudo-assembly meant that the operations were defined without assigning
registers, so the compiler could assign any register it needed and could
force flushing registers when there were not enough. The operands where
either one of the arguments, the result of a preceding pseudo-assembly
instruction or a constant.)
 
C

CBFalconer

Dik T. Winter said:
.... snip ...

And before very long a statement like the Pascal with statement
would have been invented:
with io; with math;...
Would including "math." in with every math function make a
floating-point expression that uses a few functions make any
clearer?

I sorely miss the 'with' statement in C, especially when using
complex structures, possibly accessed via pointers.
 
D

Dik T. Winter

>
> I sorely miss the 'with' statement in C, especially when using
> complex structures, possibly accessed via pointers.

The with statement in Pascal is horrible when you use it. It suddenly
may hide variables you are using, which may make it difficult for the
readers of the code to see what is going on. Yes, I did use it a lot
when writing my text editor in Pascal (about 8000 lines of code). But
it did not clarify things at all, it made it only easier to write things.
 
G

Guest

 > I sorely miss the 'with' statement in C, especially when using
 > complex structures, possibly accessed via pointers.

The with statement in Pascal is horrible when you use it.  It suddenly
may hide variables you are using, which may make it difficult for the
readers of the code to see what is going on.  Yes, I did use it a lot
when writing my text editor in Pascal (about 8000 lines of code).  But
it did not clarify things at all, it made it only easier to write things.

It is sometimes said every great computer language contains an
experimental feature that turned out to be a mistake

Pascal: with
C: declaration mirrors use
C++ exception specification
 
C

CBFalconer

Dik T. Winter said:
The with statement in Pascal is horrible when you use it. It
suddenly may hide variables you are using, which may make it
difficult for the readers of the code to see what is going on.
Yes, I did use it a lot when writing my text editor in Pascal
(about 8000 lines of code). But it did not clarify things at
all, it made it only easier to write things.

I never had that difficulty, although I have heard it from others.
I suspect the reason is the locality of my usage. My with
statements were generally short.
 
S

Stephen Sprunk

James said:
As long as <stdio.h> was the only header required by the entire standard
library, I think that was a legitimate question. I can't remember being
aware of the fact that additional headers were added later. As a result,
I was surprised when pete pointed out that K&R c only used <stdio.h>.
However, I checked my copy of K&R I, and he's right.

Interesting; I didn't start with C until after C89 came out, so I wasn't
aware that K&R had only one standard header.
I now believe that using multiple headers for a sufficiently large
library was a good idea for two different reasons, one that is obsolete,
and one that is not.

The obsolete reason is that it reduced the compilation time by a
significant amount if you only #included the headers that you actually
needed. Computers have gotten a lot faster since then, and I doubt that
many people compile code on machines with such severe limitations. I
believe that some people do compile code for such machines, but that
they usually use a cross-compiler to do so.

It's still enough of an issue today that, even with fast machines, many
compilers support have to pre-compiled headers to keep build times down.
The reason that still applies is name space pollution. As libraries
(standard and otherwise) continue to proliferate, I shouldn't have to be
aware of the hundreds (or even thousands) of different identifiers that
are in use by all of those libraries, so I can avoid using them in a
conflicting way in my program. I should only have to worry about the
identifiers used by the parts of those libraries that I'm actually using.

You touch upon the third reason here: the proliferation of libraries.
Even when C had only one standard header, lots of people have been busy
writing other libraries, and one certainly wouldn't want the compiler to
include the headers for every library on the system. If you only
include standard headers by default, that breaks a fundamental point of
symmetry between standard and third-party functions that has long been a
hallmark of C.

I think much of this would have been different if C (and various
implementations' object file formats) were designed so that one could
specify a library by name and automatically import declarations for all
the associated functions, variables, types, etc. that it contained.
However, the division between compiling and linking has served C fairly
well for other reasons, and it's far too late to change now...

S
 
R

Richard Bos

James Kuyper said:
The reason that still applies is name space pollution. As libraries
(standard and otherwise) continue to proliferate, I shouldn't have to be
aware of the hundreds (or even thousands) of different identifiers that
are in use by all of those libraries, so I can avoid using them in a
conflicting way in my program. I should only have to worry about the
identifiers used by the parts of those libraries that I'm actually using.

IMO this reason applies to second-party libraries, not to the Standard
library. As you wrote, no program can portably redefine any external
Standard identifier, anyway; and if you ask me, no well-written program
redefines any other part of the Standard, either, because though it may
be allowed, it's still confusing and needlessly complicating. Therefore,
no sane program should need to forget any part of the Standard library,
and there is now no non-historical reason for separate headers for it.

Richard
 
R

Richard Bos

On Mon, 09 Mar 2009 13:11:39 GMT, James Kuyper


In the category of "if only they had" is if only they had put all
of an include file's identifiers in a struct name space pollution
wouldn't have been nearly as much of a problem. I grant that
writing io.printf rather than printf or math.cos rather that cos
takes more characters, but so what.

It makes code needlessly verbose, that's what. There's no reason
whatsoever to keep being reminded that printf() is in the io part of the
library, every single time we use it.

Richard
 
N

Nate Eldredge

Stephen Sprunk said:
It's still enough of an issue today that, even with fast machines,
many compilers support have to pre-compiled headers to keep build
times down.

It's my impression that this is mainly for the benefit of C++, where, on
account of templates, inline functions, etc, there can be a significant
amount of complex code in headers. As far as C, I think that system
headers, GUI toolkits, and headers specific to the project contribute a
lot more to build time than the ISO standard headers.

For comparison, I tried preprocessing tiny programs that #include
various headers and counting the number of nonblank lines in the output
not starting with "#" (to exclude line markers left by the
preprocessor).

The 24 ISO C headers: 1216 lines
The X11 headers included by the "xlogo" example program: 6604 lines
The 32 standard C++ headers (per Wikipedia): 30764 lines
<QtGui> only: 59406 lines

I don't think the effect of merging all the standard C headers into one
would be significant performance-wise these days.

On most systems, depending on how the linking is done, any global
identifier defined by any part of a library will be unavailable for a
program's use, even if the program does not include the header where
that identifier is declared, and in some cases even if the identifier in
question is not referenced by the program nor the portion of the library
that it does use. So splitting up a library's headers doesn't really
address this issue either. Of course, it does help with macro
proliferation.
 
S

Stephen Sprunk

Richard said:
It makes code needlessly verbose, that's what. There's no reason
whatsoever to keep being reminded that printf() is in the io part of the
library, every single time we use it.

Hence C++'s handy "using namespace foo;" construct so you can type "bar"
instead of "foo::bar" every time. Presumably, if name spaces had been
included in C, something similar would have been added to make them just
as easy to work with.

The real issue with namespaces is that you have to somehow include the
namespace of the function or variable in its name to distinguish them at
link time, and some systems have/had rather severe limits on the length
of function and variable names. C can be made to work on such systems,
while C++ (with all its name spaces and name mangling) often can't.

S
 
C

CBFalconer

Stephen said:
Interesting; I didn't start with C until after C89 came out, so I
wasn't aware that K&R had only one standard header.

Consider what happens if you write a program that doesn't use
printf and its various formatting abilities. All you want is
routines to input chars, detect char ready, and to output chars or
strings. It is also convenent to be able to control the length of
strings, and the space for a numerical output. You can do all this
with a very few routines, and avoid all the load of the standard
library.
 
S

Stephen Sprunk

CBFalconer said:
Consider what happens if you write a program that doesn't use
printf and its various formatting abilities. All you want is
routines to input chars, detect char ready, and to output chars or
strings. It is also convenent to be able to control the length of
strings, and the space for a numerical output. You can do all this
with a very few routines, and avoid all the load of the standard
library.

I understand the rationale for having multiple headers; that's not the
issue.

My surprise was more that the _other_ standard headers in C89 weren't
"standard" in the K&R days (as much as the term meant then). I know
that <malloc.h> became <stdlib.h> and <varargs.h> became <stdarg.h>, but
why weren't they considered "standard"? Where did <stddef.h>,
<ctype.h>, etc. come from? Were they simply "common" ones that ANSI
decided to "standardize" them for the first time, or did ANSI make them
out of whole cloth?

S
 
E

Eric Sosman

Stephen said:
My surprise was more that the _other_ standard headers in C89 weren't
"standard" in the K&R days (as much as the term meant then). I know
that <malloc.h> became <stdlib.h> and <varargs.h> became <stdarg.h>, but
why weren't they considered "standard"? Where did <stddef.h>,
<ctype.h>, etc. come from? Were they simply "common" ones that ANSI
decided to "standardize" them for the first time, or did ANSI make them
out of whole cloth?

Both. <ctype.h> was in already in circulation when the ANSI
committee wrote the first Standard and regularized what was (in
20-20 hindsight) a bad design. <stddef.h> and <stdlib.h> were
invented by the committee, filling gaps for which no other homes
seemed suitable. <stdarg.h> replaced <varargs.h> because the
committee saw the need, but also believed that <varargs.h> was
insuperably difficult for some platforms to implements. Even the
familiar headers like <stdio.h> existed in many variants prior to
standardization, and the committee nailed down what should and
should not be in them.

(Source for the above assertions: PJ Plauger "The Standard C
Library.")

And then we get to the mighty debate of <string.h> versus
<strings.h> ... In my opinion, that first committee cleaned
the Augean stables, and we are greatly in their debt.
 
S

Stephen Sprunk

Eric said:
Both. <ctype.h> was in already in circulation when the ANSI
committee wrote the first Standard and regularized what was (in
20-20 hindsight) a bad design. <stddef.h> and <stdlib.h> were
invented by the committee, filling gaps for which no other homes
seemed suitable. <stdarg.h> replaced <varargs.h> because the
committee saw the need, but also believed that <varargs.h> was
insuperably difficult for some platforms to implements. Even the
familiar headers like <stdio.h> existed in many variants prior to
standardization, and the committee nailed down what should and
should not be in them.

That makes sense. But, if there were many variants of all of those
headers, why the assertion that <stdio.h> was the only "standard" header
in the K&R days -- and what exactly can that word actually mean when
there was no formal standard document?

S
 
K

Keith Thompson

Stephen Sprunk said:
That makes sense. But, if there were many variants of all of those
headers, why the assertion that <stdio.h> was the only "standard"
header in the K&R days -- and what exactly can that word actually mean
when there was no formal standard document?

<stdio.h> is the only "standard" header mentioned in K&R1.

I don't know when <ctype.h> first appeared, but there was plenty of
time between the publication of K&R1 in 1978 and the first ANSI C
standard in 1989.

(Chapter 8 of K&R1, The UNIX System Interface, mentions several
non-standard headers, including <sys/types.h>, <sys/dir.h>, and
<sys/stat.h>.)
 
F

Flash Gordon

Stephen said:
That makes sense. But, if there were many variants of all of those
headers, why the assertion that <stdio.h> was the only "standard" header
in the K&R days -- and what exactly can that word actually mean when
there was no formal standard document?

When K&R1 was published that could reasonably be considered to be the
document defining the language. This includes the following text:

7.1 Access to the Standard Library

Each source file that refers to a standard library function must
contain the line

#include <stdio.h>

near the beginning.
 
R

Richard Bos

Stephen Sprunk said:
Hence C++'s handy "using namespace foo;" construct so you can type "bar"
instead of "foo::bar" every time.

That, too, would be very useful for third-party libraries, but not for
the Standard functions. There is no way that printf() or isalnum() can
ever cause a namespace clash in a wisely-written program, so there is no
need to have them in separate namespaces.
Things are different for tr_add (which adds an element, from the tree
library) and tr_add (from the address management library, which
translates one to another format). Since no library writer knows all
other libraries out there, clashes between them are inevitable. But
everybody knows the Standard library.

Richard
 

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
473,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top