Q: Line Counting, K&R sec. 1.5.3 on OS X

D

Dan Pop

In said:
I think you have run into some of the few failings in K&R.
Huh?!?

Replace "main()" with "int main(void)", and add "return 0;" before
the final '}'. This should avoid undefined behaviour everywhere.

Please engage your brain and explain to the rest of us why the program,
in its original form, invokes undefined behaviour.

And why would you expect the 'D' to go away after these *irrelevant*
changes.

Dan
 
D

Dan Pop

In said:
Just a side note about your program. If you do not specific a return type
for a function it defaults to int. It does not default to void as many
people seem to assume. This means your program assumes main() returns an
int but you have no return statement.

Which is *explicitly* allowed by the C standard. So what *exactly* is
your point?

Dan
 
D

Dan Pop

In said:
Yes and yes. Not in the errata as of roughly a year ago either.

What should be mentioned by the errata (in context) and why?

Engage your brain before replying, please.

Dan
 
D

Dan Pop

In said:
Just as a point of order, I sorta take K&R as being the equivalent of
"my grandfather's C textbook". It probably contains things in it that
are rather "old fashioned" as Falconer pointed out. Hence, most people
post about "K&R"-style C vs. ANSI C when talking about C compilers.

The OP made it perfectly clear to anyone not reading impaired that he is
using the second edition of K&R, i.e. what we usually call K&R2. This
book provides a reasonably accurate description of the language usually
and informally called ANSI C.

Dan
 
K

Keep it to Usenet please

[email protected] (Dan Pop) said:
The OP made it perfectly clear to anyone not reading impaired that
he is using the second edition of K&R, i.e. what we usually call
K&R2. This book provides a reasonably accurate description of the
language usually and informally called ANSI C.

I'm going to get a pedantic and say you have this backwards. ANSI C
is the defined standard, so I would say "formally called ANSI C".
Also, K&R2 is "reasonably accurate", which is not the same as
equivalent. So, even if gcc x.y.z on platform X is a perfect ANSI
implementation, it will differ from K&R2. Maybe things are different
in the US, or with the circle of programmers I deal with, but K&R2 is
irrelevant. The implementation is either ANSI or it's some platform
specific variation.

{Follow-ups set because this really isn't a Mac OS issue.}
 
K

Keep it to Usenet please

Barry Margolin said:
I certainly have nothing against code being written properly, but I
don't believe in misleading posts. Although the standard allows
for arbitrary behavior of non-conforming programs, any experienced
programmer knows what kinds of misbehaviors are actually likely in
real systems.

True, but I've had to deal with more than my fair share of
programmers that learned their C on Windoze boxen. They very often
take the attitude that since their code, which worked on Windoze,
doesn't work in an ANSI environment means that the ANSI envoironment
is broken. Folks like this need to have the standard pointed out to
them, because they obliviously think they are coding to standard. In
many case it gets bad enough to be described as "arrogantly assume
that it's impossible for them to have made an error". You see the
same attitude, but to a much more often, and almost always to the
worse degree, dealing with Web developers that couldn't write
standards compliant code to save their lives.

Mostly because of the frequency and arrogance of the "well it works
as I intend under (IE for) Windows, therefore it's impossible for
there to be any errors in it" attitude, I tend not to give more than
a cursory glance at problems if I see too much non-standard code and
reply with some variation of, "I'm sorry but there's too much
non-standard and/or poor code in here for you to assert that the
problem is platform related. If you'll fix your code, then I'll
listen to complaints about a particular platform's implementation."

{Follow-ups set, because this isn't really a Mac OS issue.}
 
G

Guillaume

True, but I've had to deal with more than my fair share of
programmers that learned their C on Windoze boxen. They very often
take the attitude that since their code, which worked on Windoze,
doesn't work in an ANSI environment means that the ANSI envoironment
is broken.

I have also encountered this very attitude with MacOS programmers.
That was even worse with them: since in the earlier days of MacOS,
there was absolutely no memory protection of any sort, their code
was often filled with pointer bugs. That would never crash under
MacOS, but when ported to another platform with memory protection
(at the time, that was Windows), it would crash on a regular basis.
And guess what? In their head, of course, that was Windows' fault.

Some developers would even claim (some lame ones, I agree) that it
was impossible to develop proper software under Windows.
 
D

Dan Pop

In said:
I'm going to get a pedantic and say you have this backwards. ANSI C
is the defined standard, so I would say "formally called ANSI C".

Nope. The standard has a very precise name, currently ISO/IEC 9899:1999
as ammended by Technical Corrigendum 1, published on 2001-09-01. "ANSI C"
is and has always been an informal name.
Also, K&R2 is "reasonably accurate", which is not the same as
equivalent.

So what? Do you suggest that people should learn C from the C standard?
So, even if gcc x.y.z on platform X is a perfect ANSI
implementation, it will differ from K&R2.

In what respect? Even if K&R2 is not equivalent to the C standard, it
needs not be in conflict with it.
Maybe things are different
in the US, or with the circle of programmers I deal with, but K&R2 is
irrelevant.

Irrelevant for whom? It might be irrelevant for the C implementors, but
it's definitely not for the people interested in learning C.
The implementation is either ANSI or it's some platform
specific variation.

It can be both at the same time, but you're not expected to understand
this.

Dan
 
A

Alex Monjushko

I think you have run into some of the few failings in K&R.
Replace "main()" with "int main(void)", and add "return 0;" before
the final '}'. This should avoid undefined behaviour everywhere.

Which undefined behavior?

AFAIK, under C90, there is such a thing as implicit int. Additionally,
the lack of a return statement will result in an "undefined value"
being returned, not in "undefined behavior".
 
C

Christian Bau

True, but I've had to deal with more than my fair share of
programmers that learned their C on Windoze boxen. They very often
take the attitude that since their code, which worked on Windoze,
doesn't work in an ANSI environment means that the ANSI envoironment
is broken.

I have also encountered this very attitude with MacOS programmers.
That was even worse with them: since in the earlier days of MacOS,
there was absolutely no memory protection of any sort, their code
was often filled with pointer bugs. That would never crash under
MacOS, but when ported to another platform with memory protection
(at the time, that was Windows), it would crash on a regular basis.
And guess what? In their head, of course, that was Windows' fault.[/QUOTE]

My experience was quite the opposite. Since there was no memory
protection whatsoever, you were _very_ careful with your code. The code
that I helped porting to Windows (about 900,000 lines of C++) did
certainly not "crash on a regular basis".

Another major application of about one million or so lines that I ported
from MacOS 9 (no memory protection) to MacOS X had two accesses to
location zero when it was started after it compiled and linked for the
first time, and that was it. No crashes because of memory violations
after that.
Some developers would even claim (some lame ones, I agree) that it
was impossible to develop proper software under Windows.

I think there is plenty of empirical proof for this.
 
M

Mark Day

Mo said:
Here's my session running the program:
/****************************************/
G4:~/c jeff$ ./linecnt
jeff
tom
2D
G4:~/c jeff$
/****************************************/

After typing 'tom' I hit <return> then type CTRL-D. The '2' is correct
but what's with the 'D'??

When you typed CTRL-D, I'll bet the terminal echoed it as "^D", but
without moving the cursor. Then your program printed "2" on top of the
"^".
BTW, when I changed 'int' to 'float' and changed '%d' to '%f' the D
stopped showing up.

When printing it as a float, it probably printed out 2 or more digits,
which overwrote the "^D".

To confirm the theory, try changing your printf to:
printf("\n%d\n", nl);

so it will print the answer below the "^D".

-Mark
 
G

Guillaume

My experience was quite the opposite.

Well, always interesting to share different experiences.
Since there was no memory
protection whatsoever, you were _very_ careful with your code. The code
that I helped porting to Windows (about 900,000 lines of C++) did
certainly not "crash on a regular basis".

Good for you, but the claim that a lack of security makes you very
careful and that this is enough to make your code bug-free is a
wild assertion to say the least. So you've never made a single
mistake in your life? Again, good for you. But allow me to be
skeptical. Maybe we don't even need seat belts after all, because
if you drive carefully, nothing wrong can happen...
Another major application of about one million or so lines that I ported
from MacOS 9 (no memory protection) to MacOS X had two accesses to
location zero when it was started after it compiled and linked for the
first time, and that was it. No crashes because of memory violations
after that.

Again, good for you. One million of lines developed under a system with
no memory protection, and not a single access violation? I need to know
what company you're working for...
I think there is plenty of empirical proof for this.

Oh yeah? I've been making Windows software for years without ever
finding a single inherent problem in Windows that would prevent me from
writing "proper" software. I'm not even advocating Windows in any way,
it's just a fact. In my experience, the main issues that developers
would encounter while developing for Windows were: memory protection
and multithreaded programming. Mind you, the basic core of Windows
(I mean the NT-series, of course. 9x weren't worth shit, but that's
another debate) is extremely "mainstream" preemptive multithreading.
Nothing to fret about and no particular issues either.
 
C

Christian Bau

Guillaume said:
Again, good for you. One million of lines developed under a system with
no memory protection, and not a single access violation? I need to know
what company you're working for...

Think about it for a minute: What are the chances that an application
_that runs stable_ on a system without memory protection accesses memory
all over the place that it shouldn't touch?

I wasn't talking about development, I was talking about moving a stable,
mature application that is used in a production environment by thousands
of people to an environment with memory protection. You claimed such
applications would crash again and again, my experience was the
opposite.
 
C

CBFalconer

Alex said:
.... snip ...


Which undefined behavior?

AFAIK, under C90, there is such a thing as implicit int.
Additionally, the lack of a return statement will result in an
"undefined value" being returned, not in "undefined behavior".

Nobody said there WAS UB, nor that the compiler was C90. It could
have been C99. Making the minor changes ensures the source is
compliant under both standards, and simply eliminates some
possibilities. After that one can either expect the anomaly to go
away, or go looking for the cause without worrying about source
failings.

When a nut fails to fit a bolt, I normally check that I really
have the right thread to start with.

The actual problem has long since been solved, and the above had
nothing to do with it. However it does have something to do with
the methodology of solving problems.
 
C

Christian Bau

CBFalconer said:
Nobody said there WAS UB, nor that the compiler was C90. It could
have been C99. Making the minor changes ensures the source is
compliant under both standards, and simply eliminates some
possibilities. After that one can either expect the anomaly to go
away, or go looking for the cause without worrying about source
failings.

When a nut fails to fit a bolt, I normally check that I really
have the right thread to start with.

The actual problem has long since been solved, and the above had
nothing to do with it. However it does have something to do with
the methodology of solving problems.

In this case, the complaint was about the behavior observed in the
operating system after calling a C program. Returning an unspecified or
undefined value from main () to the operating system might very well
change how the OS displays the programs output, so returning 0 from main
might quite possibly have fixed the problem.

Maybe the code in the operating system looks like:

call_external_program (name, arguments, &error);
if (error == 0) {
if (outputline_incomplete ()) {
clear_to_endofline ();
gotonextline ();
}
}
 
D

Dan Pop

In said:
Nobody said there WAS UB,

Then, what *exactly* did you mean by the underlined statement above?
nor that the compiler was C90.

This is implied. The usage of K&R or C99 compilers must be explicitly
mentioned.
It could have been C99.

Then, a diagnostic was required.
Making the minor changes ensures the source is
compliant under both standards, and simply eliminates some
possibilities.

What possibilities, apart from a diagnostic from a C99 compiler? Which
is a non-issue in context, as conforming C99 compilers have not yet been
detected in the hands of the people struggling with the first chapter of
K&R2.

OTOH, what's the point in exposing a very green newbie (the program in
question is on page 19 of K&R2) to the specifics of C99? At this moment
he has a completely different set of priorities.
After that one can either expect the anomaly to go away,

Why? None of your changes did *anything* in the direction of suppressing
it!
or go looking for the cause without worrying about source failings.

You seemed to be the only one worrying about those completely irrelevant
issues.
The actual problem has long since been solved, and the above had
nothing to do with it. However it does have something to do with
the methodology of solving problems.

Yup, it shows how NOT to try solving problems. If the program actually
invoked undefined behaviour, e.g. by not including <stdio.h>, I agree that
removing undefined behaviour was the first priority, even if it was
extremely unlikely to change anything in the program's actual behaviour.
But suggesting purely cosmetic changes (in context) is sheer idiocy...

Dan
 
C

CBFalconer

Dan said:
.... snip ...


Yup, it shows how NOT to try solving problems. If the program
actually invoked undefined behaviour, e.g. by not including
<stdio.h>, I agree that removing undefined behaviour was the first
priority, even if it was extremely unlikely to change anything in
the program's actual behaviour. But suggesting purely cosmetic
changes (in context) is sheer idiocy...

Ah, so, according to you, failure to return a valid exit status
cannot possibly affect the action of a system on program exit. In
my abysmal ignorance I fail to follow this logic. We should all
bear in mind that the Pop is infallible.
 
D

Dan Pop

In said:
Ah, so, according to you, failure to return a valid exit status
cannot possibly affect the action of a system on program exit.

According to the C standard, *any* exit status is valid and has
implementation-defined semantics.

5 Finally, control is returned to the host environment. If the
value of status is zero or EXIT_SUCCESS, an implementation-defined
^^^^^^^^^^^^^^^^^^^^^^^^^
form of the status successful termination is returned. If the
^^^^
value of status is EXIT_FAILURE, an implementation-defined form
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
of the status unsuccessful termination is returned. Otherwise
the status returned is implementation-defined. ^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The exit status is implementation-defined (regardless of the actual
value of the exit argument). I can see no indication that the exit
status is allowed to interfere with the program behaviour.
In my abysmal ignorance I fail to follow this logic. We should all
bear in mind that the Pop is infallible.

Have the minimal decency to keep the cheap shots for the times when
you are right and I am wrong.

Dan
 

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

Similar Threads


Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,144
Latest member
KetoBaseReviews
Top