First C Program, Problems getting serial data

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • regis

    #31
    Re: First C Program, Problems getting serial data

    Keith Thompson wrote:[color=blue]
    > regis <regis@dil.un iv-mrs.fr> writes:[color=green]
    >>Rod Pemberton wrote:[/color][/color]
    [color=blue][color=green][color=darkred]
    >>>Because of this, I'd posit that strcmp() is _essentially_ a boolean
    >>>function: zero equal, non-zero if different.[/color]
    >>
    >>It is a comparison function designed to work with qsort().
    >>
    >>If one want to easily detect multiple occurrences of strings
    >>in an array, one way is to use qsort() along with strcmp()
    >>so that these occurrences become contiguous,
    >>and then any behavior of strcmp() fits the job
    >>as long as it is a comparison function.[/color]
    >
    > I'm sure strcmp() was intended to be used directly with qsort() when
    > the functions were originally designed. However, qsort() expects a
    > comparison function that takes two arguments of type "const void*",
    > whereas strcmp() expects arguments of type "const char*". There are
    > some guarantees of compatibility between void* and char*, but I'm not
    > sure they extend to compatbility of functions taking them as
    > arguments.
    >
    > At worst, though, strcmp() can be used with qsort() with a very simple
    > wrapper.[/color]

    Oups. And to make things worse...

    Should this extension of compatibility have existed between
    functions taking "char*" and "void*" as arguments,
    this would not have worked either with the example I had in mind,
    that is, sorting an array of elements, each of type char *,
    because another level of indirection is introduced:

    The comparison function of qsort expects two pointers to the elements
    be compared, as opposed to the elements themselves,
    therefore here, behind the two "void *"
    it expects two "const char **" as opposed to two "const char *"

    int strcmp_wrapper (const void * a, const void * b)
    {
    return strcmp (* (const char **) a, * (const char **) b);
    }




    Comment

    • Barry Schwarz

      #32
      Re: First C Program, Problems getting serial data

      On Tue, 18 Apr 2006 22:02:21 +0200, regis <regis@dil.un iv-mrs.fr>
      wrote:
      [color=blue]
      >Rod Pemberton wrote:[color=green]
      >> "Keith Thompson" <kst-u@mib.org> wrote in message[/color]
      >[color=green]
      >> Determining if strings are equal or different is useful. However,
      >> determining if the last compared character in one string was above (>0) or
      >> below (<0) the last compared character in the other, is useless and heavily
      >> dependent on the nonportable and sometimes random ordering of the character
      >> set. Because of this, I'd posit that strcmp() is _essentially_ a boolean
      >> function: zero equal, non-zero if different.[/color]
      >
      >It is a comparison function designed to work with qsort().
      >[/color]

      strcmp is not designed to work with qsort. Passing strcmp to qsort as
      the fourth parameter requires a diagnostic.


      Remove del for email

      Comment

      • Richard Bos

        #33
        Re: First C Program, Problems getting serial data

        "Rod Pemberton" <do_not_have@so rry.bitbuck.cmm > wrote:
        [color=blue]
        > "Keith Thompson" <kst-u@mib.org> wrote in message
        > news:lnzmiify9k .fsf@nuthaus.mi b.org...[color=green]
        > > strcmp() gives a consistent ordering of string values. Sometimes an
        > > internally consistent ordering is all you need, for example if you
        > > want to build a search tree.
        > >
        > > strcmp() is not a boolean function.[/color]
        >
        > I never said it was. I said it is _essentially_ a boolean function. That's
        > because ordering of string values is a very low use situation...[/color]

        Speaking as someone who has dealt with databases containing names, I
        have to snigger a bit at your naivete.
        [color=blue][color=green]
        > > (Aside: I've never heard of a language called "ADA". I've programmed
        > > in Ada. It's a name, not an acronym.)[/color]
        >
        > True enough, although it is frequently found all capitalized.[/color]

        So? main() is also frequently declared void. Red lights are frequently
        driven through.

        Richard

        Comment

        • Richard Bos

          #34
          Re: First C Program, Problems getting serial data

          Keith Thompson <kst-u@mib.org> wrote:
          [color=blue]
          > rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:[color=green]
          > > jaysome <jaysome@spamco p.com> wrote:[color=darkred]
          > >> Keith, you are right on. A true Boolean variable should use Boolean
          > >> opeartors such as !, and never comparison operators such as ==. A
          > >> Boolean value by definition has a binary state, so the C standard
          > >> supports it quite nicely:
          > >>
          > >> /* The true condition */
          > >> if ( is_on )
          > >>
          > >> /* The false condition */
          > >> if ( !is_on )
          > >>
          > >> There is no reason whatsoever to compare a Boolean value to another
          > >> value like this:
          > >>
          > >> if ( is_on == TRUE )
          > >>
          > >> or like this:
          > >>
          > >> if ( is_on == FALSE )
          > >>
          > >> or like the myriad other variations of these.[/color]
          > >
          > > Imprimis, this is a style matter; if someone finds an explicit mention
          > > of TRUE or FALSE clearer than the presence or absence of a !, is that a
          > > problem?[/color]
          >
          > Yes, it's a problem. TRUE is presumably equal to 1, but *any*
          > non-zero value is considered true.
          >
          > Consider this:
          >
          > is_on = isalpha(c);
          > if (is_on == TRUE)
          >
          > This can fail if isalpha returns a value other than 0 or 1, which it's
          > allowed to do.
          >[color=green]
          > > Secundis, while I do agree with your style myself, there is one place
          > > where you can't escape using == on boolean values without jumping
          > > through silly hoops:
          > >
          > > if (left_valve_ope n == right_valve_ope n)[/color]
          >
          > Again, this fails if left_valve_open and right_valve_ope n have
          > differing non-zero values.[/color]

          Yes and yes, but then you're not talking about truly boolean values in
          the first place.

          Richard

          Comment

          • Keith Thompson

            #35
            Re: First C Program, Problems getting serial data

            rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:[color=blue]
            > Keith Thompson <kst-u@mib.org> wrote:[color=green]
            >> rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:[/color][/color]
            [...][color=blue][color=green][color=darkred]
            >> > Imprimis, this is a style matter; if someone finds an explicit mention
            >> > of TRUE or FALSE clearer than the presence or absence of a !, is that a
            >> > problem?[/color]
            >>
            >> Yes, it's a problem. TRUE is presumably equal to 1, but *any*
            >> non-zero value is considered true.
            >>
            >> Consider this:
            >>
            >> is_on = isalpha(c);
            >> if (is_on == TRUE)
            >>
            >> This can fail if isalpha returns a value other than 0 or 1, which it's
            >> allowed to do.
            >>[color=darkred]
            >> > Secundis, while I do agree with your style myself, there is one place
            >> > where you can't escape using == on boolean values without jumping
            >> > through silly hoops:
            >> >
            >> > if (left_valve_ope n == right_valve_ope n)[/color]
            >>
            >> Again, this fails if left_valve_open and right_valve_ope n have
            >> differing non-zero values.[/color]
            >
            > Yes and yes, but then you're not talking about truly boolean values in
            > the first place.[/color]

            What do you mean by "truly boolean values"? Prior to C99's
            introduction of _Bool, C had no such concept.

            Unless they're declared as _Bool, it's a bad idea to assume that
            left_valve_open and right_valve_ope n can only take on the values
            0 and 1. Even if you carefully design your program to use only 0 and
            1, there's always the risk that you (or a future maintainer) will
            introduce a call to isalpha() or something similar. The resulting bug
            could be very hard to track down.

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
            San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
            We must do something. This is something. Therefore, we must do this.

            Comment

            • Simon Biber

              #36
              Re: First C Program, Problems getting serial data

              regis wrote:[color=blue]
              > Oups. And to make things worse...
              >
              > Should this extension of compatibility have existed between
              > functions taking "char*" and "void*" as arguments,
              > this would not have worked either with the example I had in mind,
              > that is, sorting an array of elements, each of type char *,
              > because another level of indirection is introduced:
              >
              > The comparison function of qsort expects two pointers to the elements
              > be compared, as opposed to the elements themselves,
              > therefore here, behind the two "void *"
              > it expects two "const char **" as opposed to two "const char *"
              >
              > int strcmp_wrapper (const void * a, const void * b)
              > {
              > return strcmp (* (const char **) a, * (const char **) b);
              > }[/color]

              This function is badly named, it extends into the name space reserved
              for extensions. In general, try not to start functions with 'str'.

              You are also casting to the wrong type. The const is in the wrong
              location, so you are actually casting away the const qualifier in the
              original type.

              When programming, I always try to avoid casts whenever possible:

              #include <string.h>

              int wrap_strcmp(con st void * a, const void * b)
              {
              char * const * c = a;
              char * const * d = b;
              return strcmp(*c, *d);
              }

              Although this uses two extra temporary variables, I find the lack of
              casts to be an important indicator that there is less likely to be an
              erroneous conversion (such as yours).

              Simon.

              Comment

              • regis

                #37
                Re: First C Program, Problems getting serial data

                Simon Biber wrote:[color=blue]
                > regis wrote:[/color]
                [color=blue][color=green]
                >> int strcmp_wrapper (const void * a, const void * b)
                >> {
                >> return strcmp (* (const char **) a, * (const char **) b);
                >> }[/color]
                >
                > This function is badly named, it extends into the name space reserved
                > for extensions. In general, try not to start functions with 'str'.
                >
                > You are also casting to the wrong type. The const is in the wrong
                > location, so you are actually casting away the const qualifier in the
                > original type.
                >
                > When programming, I always try to avoid casts whenever possible:
                >
                > #include <string.h>
                >
                > int wrap_strcmp(con st void * a, const void * b)
                > {
                > char * const * c = a;
                > char * const * d = b;
                > return strcmp(*c, *d);
                > }
                >
                > Although this uses two extra temporary variables, I find the lack of
                > casts to be an important indicator that there is less likely to be an
                > erroneous conversion (such as yours).[/color]

                Thank you for the correction.
                If I had used the two temporary without cast, my compiler
                would have warned me about the misplaced const qualifier.

                --
                regis

                Comment

                Working...