Why this works???

T

Tomás Ó hÉilidhe

Coos Haak:
Just a question, what is the origin of your name, I've never seen
names in CamelCase ;-)


My name is Irish.

In English, think about how you have:

a dog
a cat
a tree

but when there's a vowel, you have:

an apple
an ostrich
an elephant


Well, in Irish, instead of "an apple", you'd have "a napple".

Now imagine if you had a book called "an apple" or "a napple". How would
you capitalise the words?

Well "an apple" would be "An Apple". "a napple" would be "A nApple".

That's exactly what's happening in my surname; you have "Ó" flowing into
"Éilidhe", so it becomes "Ó hÉilidhe".
 
K

Kenneth Brody

Tomás Ó hÉilidhe said:
(e-mail address removed) (Kenny McCormack) wrote in @news.xmission.com:


Forgetting for the moment that you're a troll -- a troll who's actually
not half-bad at C programming, albeit, it's a shame you don't contribute
your expertise -- we both already know why the C standard permits that
program to do whatever it likes.

I took it as an attempt at humor. Certainly we've all seen posts
like that before, along with the "English isn't my primary language"
type grammar? Rather than some "obscure" feature of C, why not ask
the same question with the quintessential C program?

[...]

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Kenneth Brody

Keith said:
Not entirely. C99 3.4.3p2:

NOTE Possible undefined behavior ranges from ignoring the
situation completely with unpredictable results, to behaving
during translation or program execution in a documented manner
characteristic of the environment (with or without the issuance of
a diagnostic message), to terminating a translation or execution
(with the issuance of a diagnostic message).

Well, at least the compiler can't reformat your hard drive simply by
attempting to compile such a program. Though, I suppose, if it were
to document such behavior in a "manner characteristic to the
environment", it would be allowed.

C:\> cl iplusplus.c
iplusplus.c(10): warning C12345: 'i=i++' encountered - reformatting
system disk.

C:\COMMAND.COM not found.
Enter full path to command interpreter:

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
P

pete

I took it as an attempt at humor. Certainly we've all seen posts
like that before, along with the "English isn't my primary language"
type grammar? Rather than some "obscure" feature of C, why not ask
the same question with the quintessential C program?

All programs which output anything else
besides newline characters to standard output,
are undefined.

The standard output stream is a text stream.
Whether the last line requires a terminating
new-line character is implementation-defined.
The byte output functions write characters to
the stream as if by successive calls to the fputc function.
Whether fputc('\n') returns ('\n') or (EOF) is unspecified,
because whether or not a write error occurs, is unspecified.
The behavior of the program is not limited by the standard.
 
C

CBFalconer

Kenneth said:
.... snip ...

Well, at least the compiler can't reformat your hard drive simply
by attempting to compile such a program. Though, I suppose, if it
were to document such behavior in a "manner characteristic to the
environment", it would be allowed.

Oh, it can. However it probably won't. Most users would consider
that as insufferable action on the part of the compiler. That
silly word, quality, arises.
 
K

Kaz Kylheku

All programs which output anything else
besides newline characters to standard output,
are undefined.

The standard output stream is a text stream.
Whether the last line requires a terminating
new-line character is implementation-defined.
The byte output functions write characters to
the stream as if by successive calls to the fputc function.

Cute. But of course what constitutes the ``last line'' is understood
to be determined at the time the stream is closed, not at any
arbitrary time. :)
 
P

pete

Kaz said:
Cute. But of course what constitutes the ``last line'' is understood
to be determined at the time the stream is closed, not at any
arbitrary time. :)

I think that the "last line"
is the last character output by the program
(whatever that character may be),
plus any and all non-newline characters that preceded it,
up to but not including the previous newline
(if there was a previous newline).
 
P

pete

pete said:
I think that the "last line"
is the last character output by the program
(whatever that character may be),
plus any and all non-newline characters that preceded it,
up to but not including the previous newline
(if there was a previous newline).

But now, I'm thinking that I may have misinterpreted:
"Whether the last line requires a terminating
new-line character is implementation-defined."

I had thought it to mean that

#include <stdio.h>
int main(void){printf("hello world"); return 0;}

was undefined, due to there not being a terminating
new-line character, on the last line.

But now I'm thinking, that what the standard might mean instead,
is that for the program shown above,
that on an implementation that requires a terminating
new-line character on the last line,
is that "hello world" would not be part of the last line
and that consequences on such an implementation,
are only that the above shown program
has no output lines and does nothing.
 
W

Walter Roberson

pete wrote:
But now, I'm thinking that I may have misinterpreted:
"Whether the last line requires a terminating
new-line character is implementation-defined."
I had thought it to mean that
#include <stdio.h>
int main(void){printf("hello world"); return 0;}
was undefined, due to there not being a terminating
new-line character, on the last line.

C89 2.1.1.2 Translation Phases

2. Each instance of a new-line character and an immediately
preceding backslash character is deleted, splicing physical
source lines to form logical source lines. A source file that
is not empty shall end in a new-line character, which shall
not be immediately preceded by a backslash character.
 
K

Kenneth Brody

CBFalconer said:
Oh, it can. However it probably won't. Most users would consider
that as insufferable action on the part of the compiler. That
silly word, quality, arises.

Perhaps this sort of implementation, instead?

http://www.xkcd.com/371/

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
P

pete

Walter said:
C89 2.1.1.2 Translation Phases

2. Each instance of a new-line character and an immediately
preceding backslash character is deleted, splicing physical
source lines to form logical source lines. A source file that
is not empty shall end in a new-line character, which shall
not be immediately preceded by a backslash character.

Regarding the terminating new-line character,
we were discussing the text stream output of C programs,
rather than the composition of source files.
 
K

Keith Thompson

pete said:
But now, I'm thinking that I may have misinterpreted:
"Whether the last line requires a terminating
new-line character is implementation-defined."

I had thought it to mean that

#include <stdio.h>
int main(void){printf("hello world"); return 0;}

was undefined, due to there not being a terminating
new-line character, on the last line.

But now I'm thinking, that what the standard might mean instead,
is that for the program shown above,
that on an implementation that requires a terminating
new-line character on the last line,
is that "hello world" would not be part of the last line
and that consequences on such an implementation,
are only that the above shown program
has no output lines and does nothing.

Here's my interpretation.

An implementation must specify in its documentation whether the last
line requires a terminating new-line character.

On an implementation that does not require it, the behavior of the
above program is well defined; its output is "hello world" with no
terminating new-line.

On an implementation that does require it, the behavior of the above
program is undefined by omission (the standard does not say, or even
hint, what its behavior should be in those circumstances). It would
have been nice, IMHO, if the standard had mentioned that the behavior
is undefined, but it's not required to. As with any undefined
behavior, an implementation is allowed, but not required, to document
what it actually does (the behavior is not defined by the standard,
but it *might* be defined by the implementation).

Plausible behaviors include not printing the final line and printing
the final line with an added new-line. A slightly less plausible
behavior is leaving the output device in an inconsistent state that
requires a manual reset before other programs can run.
 
P

pete

Keith said:
Here's my interpretation.

An implementation must specify in its documentation whether the last
line requires a terminating new-line character.

On an implementation that does not require it, the behavior of the
above program is well defined; its output is "hello world" with no
terminating new-line.

On an implementation that does require it, the behavior of the above
program is undefined by omission (the standard does not say, or even
hint, what its behavior should be in those circumstances). It would
have been nice, IMHO, if the standard had mentioned that the behavior
is undefined, but it's not required to. As with any undefined
behavior, an implementation is allowed, but not required, to document
what it actually does (the behavior is not defined by the standard,
but it *might* be defined by the implementation).

Plausible behaviors include not printing the final line and printing
the final line with an added new-line. A slightly less plausible
behavior is leaving the output device in an inconsistent state that
requires a manual reset before other programs can run.

Is new.c defined?
The standard doesn't specify whether putchar('X') returns 'X' or EOF.
The standard doesn't specify whether putchar('\n') returns '\n' or EOF.
Can this program be said to be guaranteed to do anything at all?

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
putchar('X');
putchar('\n');
return 0;
}

/* END new.c */
 
J

jameskuyper

pete wrote:
....
Is new.c defined?
The standard doesn't specify whether putchar('X') returns 'X' or EOF.
The standard doesn't specify whether putchar('\n') returns '\n' or EOF.
Can this program be said to be guaranteed to do anything at all?

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
putchar('X');
putchar('\n');
return 0;
}

/* END new.c */

It is not guaranteed that either 'X' or '\n' will make it to the
standard output. However, this program is guaranteed to return an
implementation-defined form of the status _successful termination_.
 
C

CBFalconer

pete said:
.... snip ...

The standard doesn't specify whether putchar('X') returns 'X'
or EOF. The standard doesn't specify whether putchar('\n')
returns '\n' or EOF. Can this program be said to be guaranteed
to do anything at all?

/* BEGIN new.c */
#include <stdio.h>
int main(void) {
putchar('X');
putchar('\n');
return 0;
}
/* END new.c */

Yes. It is guaranteed to attempt to output 'X', followed by an
attempt to output a '\n'. Since you never check for errors in the
putchar calls, the existance of an error will not affect the
programs sequence. After all that it will exit, and signal full
success.
 
K

Keith Thompson

pete wrote:
...

I think you mean to ask whether its behavior is undefined. In some
circumstances, I believe it is.
It is not guaranteed that either 'X' or '\n' will make it to the
standard output. However, this program is guaranteed to return an
implementation-defined form of the status _successful termination_.

Not quite. If the implementation requires a terminating new-line
character on the last line of a textstream, *and* if the putchar('\n')
call fails (regardless of whether putchar('X') fails or not), then the
behavior is undefined.

For example, it could create a malformed output file, or leave an
output device in an inconsistent physical state. This is true even if
the program tried *really hard* to terminate the file properly.
 
K

Kaz Kylheku

Here's my interpretation.

An implementation must specify in its documentation whether the last
line requires a terminating new-line character.

On an implementation that does not require it, the behavior of the
above program is well defined

It's a well-defined program of that implementation's dialect, not a
well-defined ISO C program.

On an implementation where division by zero is safe and predictable
(and documented as such), programs which divide by zero are also well-
defined. That doesn't make them well-defined standard C programs, just
well-defined programs of that dialect.
 
K

Kaz Kylheku

Is new.c defined?
The standard doesn't specify whether putchar('X')  returns  'X' or EOF..
The standard doesn't specify whether putchar('\n') returns '\n' or EOF.
Can this program be said to be guaranteed to do anything at all?

You have an interesting point. A program may be required to write a
terminating newline as the last character of a text stream. However,
an I/O error may prevent it from meeting that requirement.

So there is no way to write the program so that it is completely
reliable (as a maximally-portable ISO C program, that is, without
resorting to dialect-specific reasoning).
 
P

pete

Kaz said:
You have an interesting point. A program may be required to write a
terminating newline as the last character of a text stream. However,
an I/O error may prevent it from meeting that requirement.

So there is no way to write the program so that it is completely
reliable (as a maximally-portable ISO C program, that is, without
resorting to dialect-specific reasoning).

My other interpretation of what

could possibley mean:
is that the below shown program,
for an implementation which requires
a terminating new-line character on the last line,
that "hello, world\n" is the last line, and that "Good bye" isn't.

#include <stdio.h>
int main(void) {
printf("hello, world\n");
printf("Good bye");
return 0;
}

If "hello, world\n" is considered to be the last output line
of the above program, on implementations which require
a terminating new-line character on the last line,
then the behavior of the program is merely implementation defined,
rather than undefined, as I originally claimed in the subject line.
 
K

Keith Thompson

Kaz Kylheku said:
It's a well-defined program of that implementation's dialect, not a
well-defined ISO C program.

On an implementation where division by zero is safe and predictable
(and documented as such), programs which divide by zero are also well-
defined. That doesn't make them well-defined standard C programs, just
well-defined programs of that dialect.

That's a poor analogy. The behavior on division by zero is entirely
undefined. Whether a text stream requires a trailing new-line is
implementation-defined, and must be documented by each implementation.

A better analogy might be:

int main(void) { int i = 40000; return 0; }

This has well defined behavior for an implementation with
INT_MAX >= 40000, and undefined behavior for an implementation
with INT_MAX < 40000. I wouldn't call such implementations "dialects";
they're merely common variations of C.
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top