How to print "\n" or '\0'

K

Keith Thompson

Harald van Dijk said:
Keith Thompson wrote: [...]
And on the requirements in any particular case, unless you have a very
narrow definition of "correct". For example, the following program is
perfectly legal (in fact, I believe it's strictly conforming), but
it's not "correct".

#include <stdio.h>

#define SIX 1+5
#define NINE 8+1

int main(void)
{
printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
return 0;
}

Here's what I meant by correct:

If this is intended to print "6 * 9 = 54", the standard doesn't say that it
does (in fact, it says that it doesn't), so it is then not correct.

If this is intended to print "6 * 9 = 42", the standard says that it does,
so it is then correct.

I think this is not very different from what you mean, but please tell me if
I'm misunderstanding what you consider correct.

I had forgotten that the standard uses the word "correct" in a sense
that differs from the way I've been using it here; thanks to pete for
reminding us.

A program that is correct in all other aspects, operating on
correct data, containing unspecified behavior shall be a correct
program and act in accordance with 5.1.2.3.

(Note that this isn't presented as a definition of the word "correct"
I presume that a program doesn't *have* to contain unspecified
behavior to be considered correct.)

I've been trying to draw a strong distinction between programs that
don't violate the standard and programs that, in addition, actually
work the way they're supposed to.

Going back to what started this, using
#include "stdio.h"
is legal and "correct" in the sense that the standard uses the term,
but it's almost certainly not *right* unless the author actually
intends to allow the program to use a stdio.h header other than the
one provided by the implementation.

It's important to point out that using
#include "stdio.h"
rather than
#include <stdio.h>
is almost certainly a mistake.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Keith said:
[snip]
Going back to what started this, using
#include "stdio.h"
is legal and "correct" in the sense that the standard uses the term,
but it's almost certainly not *right* unless the author actually
intends to allow the program to use a stdio.h header other than the
one provided by the implementation.

It's important to point out that using
#include "stdio.h"
rather than
#include <stdio.h>
is almost certainly a mistake.

I have to disagree here. Since until you get to the point where creating a
file named stdio.h is a good idea, there is no difference between the two
forms, I don't think the first form is a mistake at all. If you mix
the "..." and <...> forms, there are many cases where it's not clear which
form is most appropriate and whether the answer may change. If you always
use the "..." form, you can't go wrong. So why not always use the "..."
form?
 
K

Keith Thompson

Harald van Dijk said:
Keith said:
[snip]
Going back to what started this, using
#include "stdio.h"
is legal and "correct" in the sense that the standard uses the term,
but it's almost certainly not *right* unless the author actually
intends to allow the program to use a stdio.h header other than the
one provided by the implementation.

It's important to point out that using
#include "stdio.h"
rather than
#include <stdio.h>
is almost certainly a mistake.

I have to disagree here. Since until you get to the point where creating a
file named stdio.h is a good idea, there is no difference between the two
forms, I don't think the first form is a mistake at all. If you mix
the "..." and <...> forms, there are many cases where it's not clear which
form is most appropriate and whether the answer may change. If you always
use the "..." form, you can't go wrong. So why not always use the "..."
form?

Using the "..." form tells a knowledgeable reader that the directive
might refer to some arbitrary file other than the standard header. It
tells me that either (a) the author might have inserted his own
stdio.h file for some reason, and I'd better figure out why if I want
to understand the code, or (b) the author doesn't really know what
he's doing, and he's just wasted my time.

Using the <...> form *for the standard headers* cannot go wrong.
Using the "..." form can go wrong if there happens to be a file named
"stdio.h" (or with whatever name the implementation maps "stdio.h" to)
anywhere in some set of directories that varies from one
implementation to another.

There are legitimate reasons to use either the "..." form or the <...>
form for headers other than the ones defined by the standard. None of
those reasons apply to stdio.h.

(Do you use #include "stdio.h" in your own code?)
 
T

Thomas Dickey

Keith Thompson said:
Using the <...> form *for the standard headers* cannot go wrong.

There are exceptions to that rule,
as you would realize on a moment's reflection.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Keith said:
Harald van Dijk said:
Keith said:
[snip]
Going back to what started this, using
#include "stdio.h"
is legal and "correct" in the sense that the standard uses the term,
but it's almost certainly not *right* unless the author actually
intends to allow the program to use a stdio.h header other than the
one provided by the implementation.

It's important to point out that using
#include "stdio.h"
rather than
#include <stdio.h>
is almost certainly a mistake.

I have to disagree here. Since until you get to the point where creating
a file named stdio.h is a good idea, there is no difference between the
two forms, I don't think the first form is a mistake at all. If you mix
the "..." and <...> forms, there are many cases where it's not clear
which form is most appropriate and whether the answer may change. If you
always use the "..." form, you can't go wrong. So why not always use the
"..." form?

Using the "..." form tells a knowledgeable reader that the directive
might refer to some arbitrary file other than the standard header. It
tells me that either (a) the author might have inserted his own
stdio.h file for some reason, and I'd better figure out why if I want
to understand the code, or (b) the author doesn't really know what
he's doing, and he's just wasted my time.

It's different to me. If "stdio.h" is included, I assume the standard
header, or a user header with the same effect, is included. If the
user-supplied stdio.h file does not behave like the standard stdio.h
header, that's what I consider wasting time.
Using the <...> form *for the standard headers* cannot go wrong.
Using the "..." form can go wrong if there happens to be a file named
"stdio.h" (or with whatever name the implementation maps "stdio.h" to)
anywhere in some set of directories that varies from one
implementation to another.

Using the <...> form for the standard headers can also go wrong in almost
the same situations, except worse as far as the standard is concerned. If a
file named stdio.h exists in any of the standard locations when <stdio.h>
is included, the behaviour is undefined. In practice, many implementations
will happily include the user header.
There are legitimate reasons to use either the "..." form or the <...>
form for headers other than the ones defined by the standard. None of
those reasons apply to stdio.h.

What if the programmer wants to deal with a system where <stdio.h>
unconditionally declares a function named read(), which conflicts with a
valid use of read as a global variable in the project, and supplying a
custom stdio.h header is less work than renaming the variable name
everywhere?
(Do you use #include "stdio.h" in your own code?)

Personally, I use "..." for source files in my project directories, and
<...> for source files outside my project directories. In the event that it
could be either (suppose I use libfoo, and bundle it with my application,
but also support the system's libfoo if it's installed already -- or
suppose I optionally use my own stdio.h header for one specific
implementation to deal with a problem in the system's header), I use the
<...> form, even though officially, in the second case, the behaviour is
undefined. So no, I would not use #include "stdio.h" in my own code.
 
T

Thomas Dickey

Thomas Dickey said:
Richard Tobin said:
cut/paste time (though a waste since the knowledgable readers of this
newsgroup should know this offhand):

6.10.2 Source file inclusion

2 A preprocessing directive of the form

# include <h-char-sequence> new-line

searches a sequence of implementation-defined places for a header
identified uniquely by the specified sequence between the < and >
delimiters, and causes the replacement of that directive by the
entire contents of the header. How the places are specified or the
header identified is implementation-defined.
Using the <...> form *for the standard headers* cannot go wrong.

Note that there's nothing that ensures that a bracketed include necessarily
refers to a "standard header" nor that giving the name of a standard
header will yield the expected file. It's implementation-defined (and
subject to how the user may/may not specify the places).

Several counter-examples came to mind on viewing that "Using" statement,
but those are from experience...

regards.
 
W

Walter Roberson

Thomas Dickey said:
Richard Tobin said:
6.10.2 Source file inclusion
2 A preprocessing directive of the form
# include <h-char-sequence> new-line
searches a sequence of implementation-defined places for a header
identified uniquely by the specified sequence between the < and >
delimiters, and causes the replacement of that directive by the
entire contents of the header. How the places are specified or the
header identified is implementation-defined.
Note that there's nothing that ensures that a bracketed include necessarily
refers to a "standard header" nor that giving the name of a standard
header will yield the expected file. It's implementation-defined (and
subject to how the user may/may not specify the places).

C89 4.1.2 Standard Headers

Each library function is declared in a header, whose contents are
made available by the #include preprocessing directive. The header
declares a set of related functions, plus any necessary types and
additional macros needed to facilitate their use.

The standard headers are:

<assert.h> <locale.h> <sstddef.h>
[etc]

If a file with the same name as one of the above < and > delimited
sequences, not provied as part of the implementation, is placed in
any of the standard places for a source file to be included,
the behavior is undefined.


This plus plenty of Usage statements in C89 enshrine the above token
sequences as being *the* way to refer to the standard headers.

I believe this leaves only your point that using the <...> form
for standard headers could go wrong because some idjit might have
replaced one of the standard headers with non-standard content.
 
T

Thomas Dickey

Walter Roberson said:
I believe this leaves only your point that using the <...> form
for standard headers could go wrong because some idjit might have
replaced one of the standard headers with non-standard content.

heh. All you're asserting is that if the standard doesn't apply then
it's undefined behavior, and that since the standard only describes
defined behavior then KT's claim that using the standard form cannot
go wrong is always correct since we're forbidden to contemplate any
other result.

Given your other recent followups, I don't suppose I could expect much.

bye.
 
W

Walter Roberson

heh. All you're asserting is that if the standard doesn't apply then
it's undefined behavior, and that since the standard only describes
defined behavior then KT's claim that using the standard form cannot
go wrong is always correct since we're forbidden to contemplate any
other result.

I made no such assertion. In your earlier posting, you gave
multiple reasons for a particular viewpoint; I refuted one of the
reasons with reference to the C89 standard, and summarized the
reason that remained, without making comment as to whether that
reason was correct or incorrect.

If you wish to point out that one should not say that something
"can never" go wrong, on the grounds that the implementation might
be broken, or a hardware error may occur, or a Finite Improbability
Generator might be operating nearby and might translate all of
the program's undergarments simultaneously 3 feet to the left,
then I would agree

Given your other recent followups, I don't suppose I could expect much.

I can never remember which emoticon encodes "Raises Eyebrows".
 
T

Thomas Dickey

Walter Roberson said:
I made no such assertion. In your earlier posting, you gave
multiple reasons for a particular viewpoint; I refuted one of the
reasons with reference to the C89 standard, and summarized the
reason that remained, without making comment as to whether that
reason was correct or incorrect.

I'm afraid you missed the point. All you accomplished was reminding
the dwindling audience that in the absence of the standard's
permissable but unspecified implementation-specific behavior
that an include will get the expected header.

That's obvious (and the extra cut/paste wasn't needed, since it
adds no information).
 
W

Walter Roberson

I'm afraid you missed the point. All you accomplished was reminding
the dwindling audience that in the absence of the standard's
permissable but unspecified implementation-specific behavior
that an include will get the expected header.

No, I pointed out a section of the C89 standard that overrides
the "implementation-specific" clause you quoted, for the
case of the standard headers (which were the ones in question).
For non-standard headers, the implementation-specific clause holds.


Every conforming implementation must, for example, support

#include <string.h>

If any implementation that said, "But the association between
token strings in <...> and files is implementation defined, so
*I'm* going to require that the programs use

#include <#$&F* 9 =>

instead!", then that implementation would be breaking a great
many clauses in the standard.

Implementations are not even required to store the standard
headers -as- files or in any readable format: all that is required
of them is that when the standard header names are used, that the
defined interfaces and types become available to be used from that
pointed down in that translation unit. It is considered perfectly
fine for the standard headers to be "precompiled" into some
intermediate format and that format loaded in when the standard header
names are recognized; it is also considered perfectly acceptable
for the standard header contents to be literally built into the
compiler and just "turned on" by recognition of the appropriate
#include (that has not been discarded due to conditional compilation.)
 
K

Keith Thompson

Harald van Dijk said:
Keith Thompson wrote: [...]
Using the <...> form *for the standard headers* cannot go wrong.
Using the "..." form can go wrong if there happens to be a file named
"stdio.h" (or with whatever name the implementation maps "stdio.h" to)
anywhere in some set of directories that varies from one
implementation to another.

Using the <...> form for the standard headers can also go wrong in almost
the same situations, except worse as far as the standard is concerned. If a
file named stdio.h exists in any of the standard locations when <stdio.h>
is included, the behaviour is undefined. In practice, many implementations
will happily include the user header.

This kind of error can occur only if the implementation is broken
(non-conforming). If the implementation is broken, then you can't
assume *anything*. There may be good reasons to work around specific
breakages, but they're rare in my experience.

[...]
What if the programmer wants to deal with a system where <stdio.h>
unconditionally declares a function named read(), which conflicts with a
valid use of read as a global variable in the project, and supplying a
custom stdio.h header is less work than renaming the variable name
everywhere?

Then the implementation is non-conforming.
Personally, I use "..." for source files in my project directories, and
<...> for source files outside my project directories. In the event that it
could be either (suppose I use libfoo, and bundle it with my application,
but also support the system's libfoo if it's installed already -- or
suppose I optionally use my own stdio.h header for one specific
implementation to deal with a problem in the system's header), I use the
<...> form, even though officially, in the second case, the behaviour is
undefined. So no, I would not use #include "stdio.h" in my own code.

But you seem to be advising others to do so. I'm confused.
 
K

Keith Thompson

Thomas Dickey said:
There are exceptions to that rule,
as you would realize on a moment's reflection.

Chapter and verse, please.

Assuming a conforming implementation, I know of no cases where using
the <...> form can "go wrong" in the sense we're discussing. Please
clarify.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Keith said:
Harald van Dijk said:
Keith Thompson wrote: [...]
Using the <...> form *for the standard headers* cannot go wrong.
Using the "..." form can go wrong if there happens to be a file named
"stdio.h" (or with whatever name the implementation maps "stdio.h" to)
anywhere in some set of directories that varies from one
implementation to another.

Using the <...> form for the standard headers can also go wrong in almost
the same situations, except worse as far as the standard is concerned. If
a file named stdio.h exists in any of the standard locations when
<stdio.h> is included, the behaviour is undefined. In practice, many
implementations will happily include the user header.

This kind of error can occur only if the implementation is broken
(non-conforming). If the implementation is broken, then you can't
assume *anything*. There may be good reasons to work around specific
breakages, but they're rare in my experience.

No, the implementation does not have to be non-conforming for this to
happen. The standard locations may include project-specific locations, and
often do (depending on user configuration).
[...]
What if the programmer wants to deal with a system where <stdio.h>
unconditionally declares a function named read(), which conflicts with a
valid use of read as a global variable in the project, and supplying a
custom stdio.h header is less work than renaming the variable name
everywhere?

Then the implementation is non-conforming.

True, but it's nice to make the same code work for specific non-conforming
systems that works for the conforming systems.
But you seem to be advising others to do so. I'm confused.

I'm advising others to do so, only if they wish both to have the option to
use or switch to a custom stdio.h file, and to have 100% strictly
conforming code. If either the code doesn't have to be 100% strictly
conforming, or there is no possibility that a user stdio.h will be used in
the future, I'm advising others use whichever form they are most
comfortable with, whether that's the <...> form or the "..." form.
 
T

Thomas Dickey

Chapter and verse, please.
Assuming a conforming implementation, I know of no cases where using
the <...> form can "go wrong" in the sense we're discussing. Please
clarify.

Harald's been telling you also, but since you've used cut/paste replies
to his postings without evidencing any comprehension of the discussion,
it'd be a waste of my time.
 
T

Thomas Dickey

Walter Roberson said:
No, I pointed out a section of the C89 standard that overrides
the "implementation-specific" clause you quoted, for the
case of the standard headers (which were the ones in question).
For non-standard headers, the implementation-specific clause holds.

huh. You appear to be claiming that a standard-conforming implementation
doesn't allow a user to have his own header for <stdio.h>.

I'm afraid I don't recall seeing any that enforce that.

It's certainly none of the Unix/etc compilers, nor any of Microsoft's
or their competitors. They all quite happily provide me with the
contents of the files (or not) according to the implementation-defined
search mechanism. Granted that the standard does not guarantee that
there _is_ a mechanism for searching in multiple locations, it is
assumed by all of those compiler-implementers that they're doing
something that follows the standard.

Perhaps you should followup and get their certification revoked.
 
F

Francine.Neary

huh. You appear to be claiming that a standard-conforming implementation
doesn't allow a user to have his own header for <stdio.h>.

I'm afraid I don't recall seeing any that enforce that.

But in what does an implementation consist? Surely not just a
compiler, but the preprocessor plus compiler plus standard library
functions plus headers (plus other stuff probably) all together
constitute a single implementation.
 
K

Keith Thompson

Harald van Dijk said:
Keith said:
Harald van Dijk said:
Keith Thompson wrote: [...]
Using the <...> form *for the standard headers* cannot go wrong.
Using the "..." form can go wrong if there happens to be a file named
"stdio.h" (or with whatever name the implementation maps "stdio.h" to)
anywhere in some set of directories that varies from one
implementation to another.

Using the <...> form for the standard headers can also go wrong in almost
the same situations, except worse as far as the standard is concerned. If
a file named stdio.h exists in any of the standard locations when
<stdio.h> is included, the behaviour is undefined. In practice, many
implementations will happily include the user header.

This kind of error can occur only if the implementation is broken
(non-conforming). If the implementation is broken, then you can't
assume *anything*. There may be good reasons to work around specific
breakages, but they're rare in my experience.

No, the implementation does not have to be non-conforming for this to
happen. The standard locations may include project-specific locations, and
often do (depending on user configuration).

Hmm. Here's what C99 7.1.2 says:

p2 The standard headers are
[list deleted]

p3 If a file with the same name as one of the above < and >
delimited sequences, not provided as part of the
implementation, is placed in any of the standard places that
are searched for included source files, the behavior is
undefined.

I suppose that means that any attempt to provide your own stdio.h,
even if you do so by placing the file in a location searched by
#include "..." but not by #include <...>, invokes undefined behavior.
It seems to me to be a bit excessive, but if you mess around with that
kind of thing, you're on your own.

Placing your own stdio.h file in a location searched by #include <...>
is just messing with the implementation; it's just like replacing the
executable that implements the preprocessor, or replacing the object
code that implements stdio. I would have said that it just breaks the
implementation, rendering it non-conforming. I guess that saying "the
behavior is undefined" has the same effect.

[...]
I'm advising others to do so, only if they wish both to have the
option to use or switch to a custom stdio.h file, and to have 100%
strictly conforming code. If either the code doesn't have to be 100%
strictly conforming, or there is no possibility that a user stdio.h
will be used in the future, I'm advising others use whichever form
they are most comfortable with, whether that's the <...> form or the
"..." form.

For the standard headers (the ones listed in C99 7.1.2), I advise
everyone to use the <...> form, always. If that doesn't work, it's
because the implementation is broken; there's no reason to think that
using "..." will unbreak it. The very few people who are
knowledgeable enough to replace chunks of their implementation will
know that my advice doesn't apply to them.
 

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

No members online now.

Forum statistics

Threads
474,434
Messages
2,571,691
Members
48,796
Latest member
Greg L.

Latest Threads

Top