Request for comments - kgets()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • William L. Bahn

    #1

    Request for comments - kgets()

    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("Discard ed: %i\n", kgets(NULL, 20));
    printf("Discard ed: %i\n", kgets(name, 0));
    printf("Discard ed: %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.


  • Emmanuel Delahaye

    #2
    Re: Request for comments - kgets()

    William L. Bahn wrote on 13/08/04 :[color=blue]
    > #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))[/color]

    Note that you are reinventing the wheel. You have putchar() and
    getchar() for the purpose...
    [color=blue]
    > 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++);[/color]

    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...
    [color=blue]
    > 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++;[/color]

    I don't like the parameters to be changed (it makes debug harder).
    [color=blue]
    > return n;
    > }
    >
    > void PutS(const char *s)
    > {
    > while(*s != NUL)
    > PutC(*s++);
    > return;[/color]

    this 'return' is pointless.
    [color=blue]
    > }
    >
    > int main(void)
    > {
    > char name[10];
    >
    > PutS("Your Name? : ");[/color]

    The line being not terminated by a '\n', a fflush(stdout) is required
    here for portability.
    [color=blue]
    > kgets(name, 10);[/color]

    Instead of this magic 10, use sizeof name. It makes the code
    self-maintenable.
    [color=blue]
    > PutS("\nHello World, my name is ");[/color]

    Why in the word do you put the end-of-line character at the beginnig of
    the line?
    [color=blue]
    > PutS(name);
    > PutS(".\n");
    >
    > // Test Code - not part of actual program for students
    > printf("Discard ed: %i\n", kgets(NULL, 20));
    > printf("Discard ed: %i\n", kgets(name, 0));
    > printf("Discard ed: %i\n", kgets(name, 5));
    >
    > return EXIT_SUCCESS;
    > }[/color]

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

    "C is a sharp tool"

    Comment

    • Flash Gordon

      #3
      Re: Request for comments - kgets()

      On Fri, 13 Aug 2004 04:06:11 -0600
      "William L. Bahn" <william@toomuc hspam.net> wrote:

      <snip>
      [color=blue]
      > //=============== =============== ============
      >
      > #include <stdio.h> // putc(), getc(), EOF, NULL
      > #include <stdlib.h> // EXIT_SUCCESS[/color]

      Personally, I would avoid the use of // comments in C code. They are not
      valid in C89.
      [color=blue]
      > #define NUL ('\0')[/color]

      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.
      [color=blue]
      > #define LF ('\n')[/color]

      Again, I would not use this one, although I don't think it is as bad as
      using your NUL macro.
      [color=blue]
      > #define PutC(c) (putc((c), stdout))
      > #define GetC() (getc(stdin))[/color]

      <snip>
      [color=blue]
      > 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.[/color]

      I would always prefer more parenthesis than required to not enough.
      [color=blue]
      > 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?[/color]

      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.

      Comment

      • Mark McIntyre

        #4
        Re: Request for comments - kgets()

        On Fri, 13 Aug 2004 12:43:38 +0100, in comp.lang.c , Flash Gordon
        <spam@flash-gordon.me.uk> wrote:
        [color=blue]
        >On Fri, 13 Aug 2004 04:06:11 -0600
        >"William L. Bahn" <william@toomuc hspam.net> wrote:
        >
        ><snip>
        >[color=green]
        >> //=============== =============== ============
        >>
        >> #include <stdio.h> // putc(), getc(), EOF, NULL
        >> #include <stdlib.h> // EXIT_SUCCESS[/color]
        >
        >Personally, I would avoid the use of // comments in C code. They are not
        >valid in C89.[/color]

        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 =---

        Comment

        • William L. Bahn

          #5
          Re: Request for comments - kgets()


          "Emmanuel Delahaye" <emdel@YOURBRAn oos.fr> wrote in message
          news:mn.6b127d4 88e4d2864.15512 @YOURBRAnoos.fr ...[color=blue]
          > William L. Bahn wrote on 13/08/04 :[color=green]
          > > #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))[/color]
          >
          > Note that you are reinventing the wheel. You have putchar() and
          > getchar() for the purpose...[/color]

          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.
          [color=blue]
          >
          > for(n = 0; LF != GetC(); n++)
          > {
          > }
          >
          > Also you should consider to deal with EOF, in case of[/color]
          redirection from[color=blue]
          > a file...
          >[/color]

          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.
          [color=blue]
          >
          > I don't like the parameters to be changed (it makes debug[/color]
          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.
          [color=blue]
          >[color=green]
          > > return n;
          > > }
          > >
          > > void PutS(const char *s)
          > > {
          > > while(*s != NUL)
          > > PutC(*s++);
          > > return;[/color]
          >
          > this 'return' is pointless.[/color]

          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."
          [color=blue]
          >[color=green]
          > > }
          > >
          > > int main(void)
          > > {
          > > char name[10];
          > >
          > > PutS("Your Name? : ");[/color]
          >
          > The line being not terminated by a '\n', a fflush(stdout) is[/color]
          required[color=blue]
          > here for portability.[/color]

          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.
          [color=blue]
          >[color=green]
          > > kgets(name, 10);[/color]
          >
          > Instead of this magic 10, use sizeof name. It makes the code
          > self-maintenable.[/color]

          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.
          [color=blue]
          >[color=green]
          > > PutS("\nHello World, my name is ");[/color]
          >
          > Why in the word do you put the end-of-line character at the[/color]
          beginnig of[color=blue]
          > the line?[/color]

          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.



          Comment

          • jacob navia

            #6
            Re: Request for comments - kgets()


            "Flash Gordon" <spam@flash-gordon.me.uk> a écrit dans le message de
            news:j4muu1xb44 .ln2@brenda.mar kgordon.tele2.c o.uk...[color=blue]
            > On Fri, 13 Aug 2004 04:06:11 -0600
            > "William L. Bahn" <william@toomuc hspam.net> wrote:
            >
            > <snip>
            >[color=green]
            > > //=============== =============== ============
            > >
            > > #include <stdio.h> // putc(), getc(), EOF, NULL
            > > #include <stdlib.h> // EXIT_SUCCESS[/color]
            >
            > Personally, I would avoid the use of // comments in C code. They are not
            > valid in C89.[/color]

            That standard is obsolete
            The current standard allows // comments

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


            Comment

            • Flash Gordon

              #7
              Re: Request for comments - kgets()

              On Sat, 14 Aug 2004 15:59:38 +0200
              "jacob navia" <jacob@jacob.re mcomp.fr> wrote:
              [color=blue]
              > "Flash Gordon" <spam@flash-gordon.me.uk> a écrit dans le message de
              > news:j4muu1xb44 .ln2@brenda.mar kgordon.tele2.c o.uk...[color=green]
              > > On Fri, 13 Aug 2004 04:06:11 -0600
              > > "William L. Bahn" <william@toomuc hspam.net> wrote:
              > >
              > > <snip>
              > >[color=darkred]
              > > > //=============== =============== ============
              > > >
              > > > #include <stdio.h> // putc(), getc(), EOF, NULL
              > > > #include <stdlib.h> // EXIT_SUCCESS[/color]
              > >
              > > Personally, I would avoid the use of // comments in C code. They are
              > > not valid in C89.[/color]
              >
              > That standard is obsolete
              > The current standard allows // comments[/color]

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

              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.

              Comment

              • CBFalconer

                #8
                Re: Request for comments - kgets()

                jacob navia wrote:[color=blue]
                > "Flash Gordon" <spam@flash-gordon.me.uk> a écrit[color=green]
                >> "William L. Bahn" <william@toomuc hspam.net> wrote:
                >>
                >> <snip>
                >>[color=darkred]
                >>> > #include <stdio.h> // putc(), getc(), EOF, NULL
                >> > #include <stdlib.h> // EXIT_SUCCESS[/color]
                >>
                >> Personally, I would avoid the use of // comments in C code.
                >> They are not valid in C89.[/color]
                >
                > That standard is obsolete
                > The current standard allows // comments
                >
                > Besides, never saw a C compiler that would not accept them[/color]

                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 (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
                Available for consulting/temporary embedded and systems.
                <http://cbfalconer.home .att.net> USE worldnet address!


                Comment

                • Mark McIntyre

                  #9
                  Re: Request for comments - kgets()

                  On Sun, 15 Aug 2004 06:19:31 GMT, in comp.lang.c , CBFalconer
                  <cbfalconer@yah oo.com> wrote:
                  [color=blue]
                  >jacob navia wrote:[color=green]
                  >> "Flash Gordon" <spam@flash-gordon.me.uk> a écrit[color=darkred]
                  >>> "William L. Bahn" <william@toomuc hspam.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.[/color]
                  >>
                  >> That standard is obsolete
                  >> The current standard allows // comments
                  >>
                  >> Besides, never saw a C compiler that would not accept them[/color]
                  >
                  >I use one every day, called gcc.[/color]

                  No, you don't, unless you've customised gcc to remove support for them.
                  [color=blue]
                  >I run it with options to limit it to the C89 standard rather than the so-called GNU standard.[/color]

                  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.
                  [color=blue]
                  >In addition the use of // comments is not practical on newsgroups,[/color]

                  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 =---

                  Comment

                  • G. S. Hayes

                    #10
                    Re: Request for comments - kgets()

                    Mark McIntyre <markmcintyre@s pamcop.net> wrote in message news:<eqpuh0tbb bpp2q80i2emnmdh oi5mdql8bb@4ax. com>...
                    [color=blue]
                    > On Sun, 15 Aug 2004 06:19:31 GMT, in comp.lang.c , CBFalconer[/color]
                    [color=blue]
                    > <cbfalconer@yah oo.com> wrote:[/color]
                    [color=blue][color=green]
                    > > I use one every day, called gcc.[/color][/color]
                    [color=blue]
                    >[/color]
                    [color=blue]
                    > No, you don't, unless you've customised gcc to remove support for them.[/color]



                    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.

                    Comment

                    • Mark McIntyre

                      #11
                      Re: Request for comments - kgets()

                      On 15 Aug 2004 16:19:47 -0700, in comp.lang.c , sjdevnull@yahoo .com (G. S.
                      Hayes) wrote:
                      [color=blue]
                      >AFAICS gcc's behavior
                      >depends on the version of gcc you're using.[/color]

                      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 =---

                      Comment

                      Working...