By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,795 Members | 1,660 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,795 IT Pros & Developers. It's quick & easy.

Request for comments - kgets()

P: n/a
I'm looking for a few kinds of feedback here.

First, there is a program at the end of this post that has a
function kgets() that I would like any feedback on - including
style.

Second, for those that are interested, I present an outline of
the approach I am looking at using in class this semester. I
would be very interesting in any feedback on that, but if you are
not interested, feel free to skip over it.

Third, I present a conceptual model of the input buffer to my
students and want to get feedback on whether or not it is
sufficiently accurate.

This is a long post - longer than what I had intended when I
started. I won't be offended if you skip the whole thing and move
on to the next person's post.

==================================================
Proposed Teaching Approach

Motive: It seems that when I follow the typical course syllabus
that starts with formatted I/O and treats all of the underlying
details as a black box for about two-thirds of the semester that
the students have an enormous struggle grasping pointers,
null-terminated strings, the difference between numbers stored as
ASCII strings and numbers stored as unformatted bytes,
structures, and a whole host of other "advanced" topics. A year
ago I tried starting with what I called a "Card Math" module
where I invented a fictitious microprocessor that had just a few
basic instructions and I spent two weeks walking them from the
most basic SET statement and showing what indirection is and how
to use it and progressed to how all of the basic flowchart
topologies for structured programming can be implemented using a
simple conditional SKP instruction combined with unconditional
JMP instructions. We then mapped these code fragments to the
different parts of all of the flow control devices available in
C. They wrote a couple of short programs in this pseudo assembly
language, including a selection sort routine, and had to
translate the assembly into OP codes manually and had to execute
the program manually with pencil and paper.

The results were mixed - about half the class seemed to grasp
what was going on and the other half really struggled. A few
students commented, some then and some at the end of the
semester, that the exercise was very enlightening and one student
said at the end of the first two weeks, "Now I understand
pointers!" - this particular student had a semester of Java, I
believe, before taking my course.

Even though the rest seemed, on the surface, not to grasp what
was going on, I noticed later in the semester that, overall,
there did seem to be quite a bit fewer problems working with
pointers and structures and the like. So I think I am on the
right track but think I need to find an exercise that will make a
better connection for the typical student.

Approach: I am starting out with some short programs that only
use putc() and getc() for everything.

The first one is, of course, Hello World! and only uses putc().
Even with so few elements in the program, I am able to walk down
the program element by element and discuss the "low level"
details of what is going on in the context of that element. So
the very first program I get to go into the #include directive,
function headers, prototypes (for the putc() function), passing
by value and by reference (since putc() uses both), bits, bytes,
unsigned binary, the ASCII code, character escape sequences, and
function return values. A pretty amazing range of topics for so
few high-level elements. My hope is that, with so few elements
(for instance, no strings, no flow control structures, and no
variables) to get lost in, they can do a better job focusing on
the details we are discussing.

In the second program I only add an example of an object-like
macro and a function-like macro (the LF and PutC() macros below)
and cover them in some detail including the issues associated
with using parens to ensure proper evaluation (what I call the
"Golden Rules of Macros) and even the issue of macros that
evaluate an argument multiple times if that argument contains
side effects.

The third program we write the PutS() function that is included
below and now I can get into strings and string literals,
pointers, dereferencing pointers, pointer arithmetic, and how (at
least conceptually) a string literal is stored and converted to a
pointer constant and therefore not only why one can be used as an
argument to PutS() but also why it is a Bad Thing to modify one.

That brings us to the fourth program which is what is below. The
new element here is this function called kgets() - which will
also be the first time we are actually using getc(). By going
through the mechanics of reading in a string from the keyboard
character by character I can discuss a conceptual model of the
input buffer (a few questions on that later), one dimensional
arrays, the dangers of exceeding array bounds, how a string can
be read in such that it doesn't exceed the available memory,
determining if the string was completely read in, stripping the
newline character from a string, clearing out the input buffer,
and returning a value that can be used to tell how many, if any,
characters had to be read and discarded.

The fifth program will start with the question of how many
characters got discarded? Since we only have the ability to
output characters, we will have to write a function that takes an
integer value and converts it to character output one digit at a
time. We will then expand that to take a format string that
controls how the integer is displayed and will implement most of
the options that can used with the %i printf() format specifier.
We'll also write a simple function that can get a character or a
char, long, or long int from the keyboard. The hope here is that
they will gain a strong appreciation for the difference between a
character string representation of a number and the binary
representation of it. I also hope it will put them on a good
footing to understand the format string when we get to formatted
I/O and the importance of matching the specifiers to the
arguments properly.

The sixth program will get us to the printb() function I posted a
week or so ago that will let us examine the actual bit
representations of different objects and hence get into floating
point and IEEE representations.

At each stage I am making a point of mentioning what elements are
and are not implementation dependent. Most of their homework, up
to this point, will be implementing their versions of many of the
standard library functions from ctype.h, stdio.h, and string.h.

At about this point we will hit file I/O, including unformatted
I/O, and will start working with some type of standard file
format. Over the course of several weeks we will work towards a
reasonably complex goal. In the past I have done BMP (they wrote
a program to create a linked list that was used recursively to
create a Kock snowflake and the write an image to a bitmap file)
and WAV files (they wrote a program that could create a wave file
that, when played over a speaker with a phone handset nearby,
would dial the phone).

==================================================
Conceptual Model of Input Buffer (fast draft of the lesson)

First off - this is purely a conceptual model. The actual
implementations may not resemble this in any way. What we are
trying to accomplish here is an understandable description of how
the input buffer behaves as far as our program's interaction with
it is concerned.

FIFO Model - A block of memory having two pointers. The first
pointer (the READ pointer) points at the leading character in the
FIFO and the second pointer (the WRITE pointer) points at the
location where the next character will be written to the FIFO -
so it points to the spot just after the trailing character in the
FIF0. If the READ and WRITE pointers point at the same location,
then the FIFO is empty and cannot be read from. Whenever
something is written to the FIFO it is placed at the position of
the WRITE pointer and the WRITE pointer is incremented. Whenever
something is read, the value returned is the value at the
position pointed to by the READ pointer and the READ pointer is
incremented. For our purposes, we'll assume that the FIFO is
large enough that we never fill it up - meaning that we are
reading data out of it, on average, as fast as data is being
written to it and that we never get far enough behind at any time
to cause a problem.

Now imagine two FIFOs. One is controlled by the operating system
and the second is controlled by our program.

Every time a key is pressed its code is written to the system's
FIFO. This includes the newline code associated with hitting the
Enter key. These codes may or may not be ASCII - it doesn't
matter because, at some point before we interact with the data,
they will be converted to ASCII codes (since our implementation
uses ASCII as its character set).

The second FIFO is controlled by our program, but in a way that
we have very little control over. Whenever we request input from
the standard input device using functions such as getc(), gets(),
fgets(), scanf(), etc, etc, they read characters from the second
FIFO. If that FIFO is empty - or empties before we have read the
requested amount of data from it, then characters are transferred
from the first FIFO (by reading them from the first FIFO and
writing them to the second FIFO) until a newline character is
transferred. Hence data is transferred from the system's FIFO to
the program's FIFO one line - and an entire line - at a time.

It's important to note that whenever the program has to transfer
another line of data from the system's FIFO nothing else will
happen until that newline character is transferred. This means
that if you ask for just a single character but the program's
FIFO is empty and the system's FIFO doesn't have a newline
character in it, that the program will stall until the User
eventually hits the Enter key. It also means that if the User
enters more characters than we need on a given line, that the
remaining characters will remain in the program's FIFO and will
be read out the next time we ask for input. This applies to the
newline character as much as any other character. This may or may
not be the behavior we want but, regardless, it is our
responsibility to deal with it. Functions like scanf() make this
very difficult to do, which is why its use is strongly
discouraged by many programmers. If you do use scanf(), the fine
details of how the input characters are read and skipped becomes
vitally important if you are mixing numeric and character input
and great care must be taken to be sure that the program behaves
as desired.

/* At this point I run a program where the behavior is not as
expected and then walk through the code by hand using this
FIFO-based model on the board and show that what happens is would
actually is expected, just not what is wanted, when the input
doesn't match what was asked for or when numeric data and string
data are mixed without taking this into account. */

With the standard library functions, we have no way of knowing
whether anything is presently in the program's FIFO or the
system's FIFO, so we can't just check it and see because, if they
are empty, our program will hang until the User hits the Return
key. But, when we do get input from the program's FIFO, we can
take steps to keep track of whether we have seen the newline
character and, if we haven't, then we have the option of reading
characters one at a time until we do read the newline character.
What we do with these characters is completely up to is - the key
issue is that, at this point, we know that the program's FIFO is
empty and that any and all additional characters that have been
entered by the User are sitting in the system's FIFO.

Many implementations include functions that interact directly
with the system's FIFO. For us, that includes functions such as
kbhit() and getch() from the conio.h library. While these
functions give us capabilities that we can't achieve with the
standard library functions, they are not Standard C compliant. If
you are going to use them, especially if you are also using the
standard library functions as well, then it is important to
understand that a given character, once it is read from the
system's FIFO to the program's FIFO by one of the standard
library functions, is inaccessible to the conio functions.
Similarly, if a character is read from the system's FIFO by one
of the conio functions then that character will not be part of
the data that eventually gets transferred to the program's FIFO.
Hence, if you are going to mix these functions, you should be
very careful to ensure that both FIFO's are in an acceptable
state before you switch to the other type of input function.

/* At least up to this point, with our compiler, I haven't run
across any behavior that wasn't explained by this model - even
including when scanf() was intermixed with getch() from the
conio.h library. */

//==========================================

#include <stdio.h> // putc(), getc(), EOF, NULL
#include <stdlib.h> // EXIT_SUCCESS

#define NUL ('\0')
#define LF ('\n')
#define PutC(c) (putc((c), stdout))
#define GetC() (getc(stdin))

int kgets(char *s, int n)
{
// This function stores at most (n-1) characters
// from stdin to the string s. It does not retain
// the newline character. If necessary, it reads
// and discards any remaining characters in the
// input buffer. It returns the number of charcters
// discarded.

// Require non-NULL pointer AND space in string
// Discard entire string in input buffer if necessary.
if ( (NULL == s) || (n <= 0) )
{
for(n = 0; LF != GetC(); n++);
return n;
}

// Load max of n-1 characters
// Stop at but don't retain LF character

// The loop will terminate one of two ways:
// n=0: no LF was encountered
// n-1 characters read and stored
// s points one past last character stored
// set *s to NUL
// clear out rest of input buffer
// n>0: LF was encountered
// s points where LF is stored.
// set *s to NUL (strip LF from string)
// return 0

while ( (--n > 0) && (LF != (*s = GetC())) )
s++;
*s = NUL; // Add null terminator

// Count and discard unstored characters in input buffer
if (n)
n = 0; // No discarded characters
else
while (LF != GetC())
n++;

return n;
}

void PutS(const char *s)
{
while(*s != NUL)
PutC(*s++);
return;
}

int main(void)
{
char name[10];

PutS("Your Name? : ");
kgets(name, 10);
PutS("\nHello World, my name is ");
PutS(name);
PutS(".\n");

// Test Code - not part of actual program for students
printf("Discarded: %i\n", kgets(NULL, 20));
printf("Discarded: %i\n", kgets(name, 0));
printf("Discarded: %i\n", kgets(name, 5));

return EXIT_SUCCESS;
}

//=================================

One particular style point I would like to get feedback is the
use of parens in macros. This is my present approach and
reasoning:

Golden Rules for Macros:
#1) Surround each and every instance of each macro parameter
within the macro body with parens.
#2) Surround the macro as a whole with parens.

The above is expected to be done with all macros unless doing so
would cause a problem. Even if a particular macro doesn't need a
particular set of parens - such at the PutC() macro in the above
code, it is expected to follow these rules because it is too easy
to overlook a situation where, used a particular way, not
protecting the macro could cause problems. For me to change this
rule I'll probably need a fair amount of convincing.

What I'm sure will be more controversial - and it won't take as
much persuading to get me to change - is my requirement that even
object-like macros be surrounding by parens unless, again, doing
so would cause a problem. The reasoning here is that, if the
habit is developed that all #define macro bodies are
paren-enclosed by default, that it will be natural to do so when
writing a function-like macro. The fewer of these types of macros
you write, the more valuable it is to be in the happen of
throwing parens at macros in general.

Also, I generally #define the alphabetic escape sequences - such
as BEL, CR, LF - if I am going to be using them as character
constants more than once or twice. I do this purely for, what I
believe is, enhanced readability. Is this considered good
practice?

Looking forward to any comments and suggestions.
Nov 14 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
William L. Bahn wrote on 13/08/04 :
#include <stdio.h> // putc(), getc(), EOF, NULL
#include <stdlib.h> // EXIT_SUCCESS

#define NUL ('\0')
#define LF ('\n')
#define PutC(c) (putc((c), stdout))
#define GetC() (getc(stdin))
Note that you are reinventing the wheel. You have putchar() and
getchar() for the purpose...
int kgets(char *s, int n)
{
// This function stores at most (n-1) characters
// from stdin to the string s. It does not retain
// the newline character. If necessary, it reads
// and discards any remaining characters in the
// input buffer. It returns the number of charcters
// discarded.

// Require non-NULL pointer AND space in string
// Discard entire string in input buffer if necessary.
if ( (NULL == s) || (n <= 0) )
{
for(n = 0; LF != GetC(); n++);
This trailing ';' is really bad style. Better to use empty braces.

for(n = 0; LF != GetC(); n++)
{
}

Also you should consider to deal with EOF, in case of redirection from
a file...
return n;
}

// Load max of n-1 characters
// Stop at but don't retain LF character

// The loop will terminate one of two ways:
// n=0: no LF was encountered
// n-1 characters read and stored
// s points one past last character stored
// set *s to NUL
// clear out rest of input buffer
// n>0: LF was encountered
// s points where LF is stored.
// set *s to NUL (strip LF from string)
// return 0

while ( (--n > 0) && (LF != (*s = GetC())) )
s++;
*s = NUL; // Add null terminator

// Count and discard unstored characters in input buffer
if (n)
n = 0; // No discarded characters
else
while (LF != GetC())
n++;
I don't like the parameters to be changed (it makes debug harder).
return n;
}

void PutS(const char *s)
{
while(*s != NUL)
PutC(*s++);
return;
this 'return' is pointless.
}

int main(void)
{
char name[10];

PutS("Your Name? : ");
The line being not terminated by a '\n', a fflush(stdout) is required
here for portability.
kgets(name, 10);
Instead of this magic 10, use sizeof name. It makes the code
self-maintenable.
PutS("\nHello World, my name is ");
Why in the word do you put the end-of-line character at the beginnig of
the line?
PutS(name);
PutS(".\n");

// Test Code - not part of actual program for students
printf("Discarded: %i\n", kgets(NULL, 20));
printf("Discarded: %i\n", kgets(name, 0));
printf("Discarded: %i\n", kgets(name, 5));

return EXIT_SUCCESS;
}


--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html

"C is a sharp tool"

Nov 14 '05 #2

P: n/a
On Fri, 13 Aug 2004 04:06:11 -0600
"William L. Bahn" <wi*****@toomuchspam.net> wrote:

<snip>
//==========================================

#include <stdio.h> // putc(), getc(), EOF, NULL
#include <stdlib.h> // EXIT_SUCCESS
Personally, I would avoid the use of // comments in C code. They are not
valid in C89.
#define NUL ('\0')
I would not do this one since it is too easy to get it mixed up with
NULL. Also, I don't think it adds anything apart from making people
have to check that it is correct.
#define LF ('\n')
Again, I would not use this one, although I don't think it is as bad as
using your NUL macro.
#define PutC(c) (putc((c), stdout))
#define GetC() (getc(stdin))
<snip>
One particular style point I would like to get feedback is the
use of parens in macros. This is my present approach and
reasoning:

Golden Rules for Macros:
#1) Surround each and every instance of each macro parameter
within the macro body with parens.
#2) Surround the macro as a whole with parens.

The above is expected to be done with all macros unless doing so
would cause a problem. Even if a particular macro doesn't need a
particular set of parens - such at the PutC() macro in the above
code, it is expected to follow these rules because it is too easy
to overlook a situation where, used a particular way, not
protecting the macro could cause problems. For me to change this
rule I'll probably need a fair amount of convincing.
I would always prefer more parenthesis than required to not enough.
What I'm sure will be more controversial - and it won't take as
much persuading to get me to change - is my requirement that even
object-like macros be surrounding by parens unless, again, doing
so would cause a problem. The reasoning here is that, if the
habit is developed that all #define macro bodies are
paren-enclosed by default, that it will be natural to do so when
writing a function-like macro. The fewer of these types of macros
you write, the more valuable it is to be in the happen of
throwing parens at macros in general.

Also, I generally #define the alphabetic escape sequences - such
as BEL, CR, LF - if I am going to be using them as character
constants more than once or twice. I do this purely for, what I
believe is, enhanced readability. Is this considered good
practice?


I think that for a C programmer it decreases legibility where there is a
standard escape sequence. It also means that your students will be less
used to seeing them when looking at the bulk of the code in existence
which does not use your macros.

I also think you need to emphasise that the preprocessor language is a
completely separate language, possibly by running some code through the
preprocessor and looking at the output. This may help the students
understand why macros can behave in unexpected ways.
--
Flash Gordon
Sometimes I think shooting would be far too good for some people.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #3

P: n/a
On Fri, 13 Aug 2004 12:43:38 +0100, in comp.lang.c , Flash Gordon
<sp**@flash-gordon.me.uk> wrote:
On Fri, 13 Aug 2004 04:06:11 -0600
"William L. Bahn" <wi*****@toomuchspam.net> wrote:

<snip>
//==========================================

#include <stdio.h> // putc(), getc(), EOF, NULL
#include <stdlib.h> // EXIT_SUCCESS


Personally, I would avoid the use of // comments in C code. They are not
valid in C89.


Althouth to be fair, every C89 compiler I know of accepts them as an
extension. You have to turn on full ISO conformance to get them rejected.

Mind you, they're still an abhomination....
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #4

P: n/a

"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> wrote in message
news:mn***********************@YOURBRAnoos.fr...
William L. Bahn wrote on 13/08/04 :
#include <stdio.h> // putc(), getc(), EOF, NULL
#include <stdlib.h> // EXIT_SUCCESS

#define NUL ('\0')
#define LF ('\n')
#define PutC(c) (putc((c), stdout))
#define GetC() (getc(stdin))
Note that you are reinventing the wheel. You have putchar() and
getchar() for the purpose...


Yes - and that is part of the method to my madness. By limiting
them to just the two functions (well, okay, macros) from the
standard libraries and having them build up macros and functions
that perform the same tasks as quite a few of the other available
macros and functions (which they don't know about at the time
they do it - just the behavior that is trying to be achieved)
they hopefully learn a few things: (a) functions and macros are
not some deep dark mystery, (b) how significant capability can be
built up from simple foundations, and (c) functions and macros do
not have to be elaborate or complicated to be useful, even useful
enough to be included as part of the standard libraries.

for(n = 0; LF != GetC(); n++)
{
}

Also you should consider to deal with EOF, in case of redirection from a file...

Probably should - I'll have to think about that. At this point we
won't have discussed files. I'll probably leave it this way and
then perhaps revisit the function after we do talk about files.

I don't like the parameters to be changed (it makes debug harder).

I haven't really observed that too much, though I see where
you're coming from. I find the hard thing is when there is an
expression in the return statement such that you can't see what
it's doing before it exits the function.
return n;
}

void PutS(const char *s)
{
while(*s != NUL)
PutC(*s++);
return;
this 'return' is pointless.


Agreed - at least from a functional standpoint. I guess I've just
come to see it as saying, "No, I didn't just run out of code, I
really am finished."
}

int main(void)
{
char name[10];

PutS("Your Name? : ");
The line being not terminated by a '\n', a fflush(stdout) is

required here for portability.
I thought an input forced a flush - but maybe I'm just
remembering that wrong. I just looked in the standard and I guess
if this were the case it would have to be described in the
sections on the behaviors of the output functions, so I'm
probably remembering it wrong. Never-the-less, it's a good point
and I have generally neglected to discuss flushing the buffer -
as almost all the C texts do. I'm obviously negligent about it in
my coding so this is a good time for me to get in the practice of
dealing with it consistently instead of just when I have
problems. I'll make a point of including that.
kgets(name, 10);
Instead of this magic 10, use sizeof name. It makes the code
self-maintenable.


Agreed. That was quickly thrown in to test the function and I
used several different values there and neglected to key it to
the declared size when I was finished.
PutS("\nHello World, my name is ");
Why in the word do you put the end-of-line character at the

beginnig of the line?


To add a blank line after the input - and of course I do not want
an end-of-line character at the end of this string. My option
would be to put it in a function call by itself - either PutC()
or PutS() - prior to this one and increase the overhead - but
that's not much of an issue with screen output.

Nov 14 '05 #5

P: n/a

"Flash Gordon" <sp**@flash-gordon.me.uk> a écrit dans le message de
news:j4************@brenda.markgordon.tele2.co.uk. ..
On Fri, 13 Aug 2004 04:06:11 -0600
"William L. Bahn" <wi*****@toomuchspam.net> wrote:

<snip>
//==========================================

#include <stdio.h> // putc(), getc(), EOF, NULL
#include <stdlib.h> // EXIT_SUCCESS


Personally, I would avoid the use of // comments in C code. They are not
valid in C89.


That standard is obsolete
The current standard allows // comments

Besides, never saw a C compiler that would not accept them
Nov 14 '05 #6

P: n/a
On Sat, 14 Aug 2004 15:59:38 +0200
"jacob navia" <ja***@jacob.remcomp.fr> wrote:
"Flash Gordon" <sp**@flash-gordon.me.uk> a écrit dans le message de
news:j4************@brenda.markgordon.tele2.co.uk. ..
On Fri, 13 Aug 2004 04:06:11 -0600
"William L. Bahn" <wi*****@toomuchspam.net> wrote:

<snip>
//==========================================

#include <stdio.h> // putc(), getc(), EOF, NULL
#include <stdlib.h> // EXIT_SUCCESS
Personally, I would avoid the use of // comments in C code. They are
not valid in C89.


That standard is obsolete
The current standard allows // comments


Compliant C99 compilers are few and far between so most people don't
have them.
Besides, never saw a C compiler that would not accept them


Try almost any compiler in its ANSI/ISO conforming mode and it will be
rejected.

By using // comments you are limiting portability and don't get much in
return that I can see.
--
Flash Gordon
Sometimes I think shooting would be far too good for some people.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #7

P: n/a
jacob navia wrote:
"Flash Gordon" <sp**@flash-gordon.me.uk> a écrit
"William L. Bahn" <wi*****@toomuchspam.net> wrote:

<snip>
> #include <stdio.h> // putc(), getc(), EOF, NULL
> #include <stdlib.h> // EXIT_SUCCESS


Personally, I would avoid the use of // comments in C code.
They are not valid in C89.


That standard is obsolete
The current standard allows // comments

Besides, never saw a C compiler that would not accept them


I use one every day, called gcc. I run it with options to limit
it to the C89 standard rather than the so-called GNU standard. I
do not wish to accept extensions that make my code less portable.
In addition the use of // comments is not practical on newsgroups,
where arbitrary line wrapping often occurs. So avoiding them here
is simply a matter of both practicality and elementary politeness.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #8

P: n/a
On Sun, 15 Aug 2004 06:19:31 GMT, in comp.lang.c , CBFalconer
<cb********@yahoo.com> wrote:
jacob navia wrote:
"Flash Gordon" <sp**@flash-gordon.me.uk> a écrit
"William L. Bahn" <wi*****@toomuchspam.net> wrote:

<snip>

> #include <stdio.h> // putc(), getc(), EOF, NULL
> #include <stdlib.h> // EXIT_SUCCESS

Personally, I would avoid the use of // comments in C code.
They are not valid in C89.
That standard is obsolete
The current standard allows // comments

Besides, never saw a C compiler that would not accept them


I use one every day, called gcc.


No, you don't, unless you've customised gcc to remove support for them.
I run it with options to limit it to the C89 standard rather than the so-called GNU standard.
You use a compiler that /does/ accept them, but you choose to turn off that
extension. There's an important difference. Nobody said that a compiler in
strict C89 mode would accept them.
In addition the use of // comments is not practical on newsgroups,


Absolutely. Personally I dislike them anyway, but lets not get silly.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #9

P: n/a
Mark McIntyre <ma**********@spamcop.net> wrote in message news:<eq********************************@4ax.com>. ..
On Sun, 15 Aug 2004 06:19:31 GMT, in comp.lang.c , CBFalconer <cb********@yahoo.com> wrote:
I use one every day, called gcc.

No, you don't, unless you've customised gcc to remove support for them.


CBFalconer was using options to force c89, but AFAICS gcc's behavior
depends on the version of gcc you're using.

running "gcc testcomment.c -o testcomment" for a minimal test case of:

int main(void)

{

return 0; //done

}

gives:

testcomment.c: In function `main':

testcomment.c:3: parse error before `/'"

on my gcc 2.5.8 installation. I seem to recall that 2.7.2 behaved the
same way. egcs1.1+ and gcc 2.96+ seem to accept // comments happily.
Nov 14 '05 #10

P: n/a
On 15 Aug 2004 16:19:47 -0700, in comp.lang.c , sj*******@yahoo.com (G. S.
Hayes) wrote:
AFAICS gcc's behavior
depends on the version of gcc you're using.


True but uninteresting - you can say the same about absolutely anything.

"Windows doesn't support resizable windows".
"what? are you mad?",
"Well, Windows 2.0 doesn't, QED"
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.