Puzzling program

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

    #46
    Re: Puzzling program

    Kenneth Brody <kenbrody@spamc op.netwrites:
    Mark McIntyre wrote:
    >On Thu, 9 Aug 2007 00:26:19 +0100, in comp.lang.c , "Malcolm McLean"
    ><regniztar@bti nternet.comwrot e:
    >>
    >You could point out all the errors and nonportable assumptions in the code.
    >But you are not interviewing the interviewer, probably.
    >>
    >Euh, interviews are two-way. Do you really want to work for a company
    >which employs people who don't care about code errors?
    >
    Well, this may be more a case of "we're only coding for one specific
    platform, and don't care about portability". (Not that that's
    necessarily a good thing, but at least the code becomes "system
    specific behavior" rather than "errors". Of course, what happens
    when they decided to port to a similar, but 64-bit, platform?)
    Here's the original program:

    void main()
    {
    char *s = "abc";
    int *i = (int *) s;
    printf("%x", *i);
    }


    That's not just system-specific, it's *bad*. Even if you're assuming
    a particular set of characteristics for the platform, I can think
    of at least four corrections that should be made (add '#include
    <stdio.h>', use 'int main(void)', use unsigned int rather than int,
    and add a 'return 0;') Not caring about portability is no excuse
    for these errors.

    --
    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."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

    Comment

    • Charlton Wilbur

      #47
      Re: Puzzling program

      >>>>"KB" == Kenneth Brody <kenbrody@spamc op.netwrites:

      KBWell, this may be more a case of "we're only coding for one
      KBspecific platform, and don't care about portability". (Not
      KBthat that's necessarily a good thing, but at least the code
      KBbecomes "system specific behavior" rather than "errors". Of
      KBcourse, what happens when they decided to port to a similar,
      KBbut 64-bit, platform?)

      There are many valid reasons to write nonportable code, but by far the
      most common reason I've seen, and it's *not* a valid reason, is
      complete ignorance.

      If the company doesn't even realize they're writing nonportable code,
      it's not a company I want to work for.

      Charlton


      --
      Charlton Wilbur
      cwilbur@chromat ico.net

      Comment

      • Alan Curry

        #48
        Re: Puzzling program

        In article <46BC9073.33255 4FA@spamcop.net >,
        Kenneth Brody <kenbrody@spamc op.netwrote:
        >Rajeet Dalawal wrote:
        >void main()
        >{
        > char *s = "abc";
        > int *i = (int *) s;
        > printf("%x", *i);
        >}
        >>
        >The question is: why is the output 636261? I don't think I know enough
        >about C to understand how the conversions between pointer types are
        >occurring.
        >Answer the interviewer was probably looking for:
        >
        The implementation uses 32-bit integers, is little-endian, and
        uses the ASCII character set.
        How optimistic of you. The answer they were looking for could have been:

        Integers are laid out in memory with the least significant byte first.

        In other words, not just "this code is running on a little-endian platform"
        but "the whole world is little-endian, there is no such thing as big-endian,
        and no need for us to use or understand the descriptive term little-endian
        because there's no alternative from which it needs to be distinguished"

        --
        Alan Curry
        pacman@world.st d.com

        Comment

        • Keith Thompson

          #49
          Re: Puzzling program

          pacman@TheWorld .com (Alan Curry) writes:
          In article <46BC9073.33255 4FA@spamcop.net >,
          Kenneth Brody <kenbrody@spamc op.netwrote:
          >>Rajeet Dalawal wrote:
          >>void main()
          >>{
          >> char *s = "abc";
          >> int *i = (int *) s;
          >> printf("%x", *i);
          >>}
          >>>
          >>The question is: why is the output 636261? I don't think I know enough
          >>about C to understand how the conversions between pointer types are
          >>occurring.
          >
          >>Answer the interviewer was probably looking for:
          >>
          > The implementation uses 32-bit integers, is little-endian, and
          > uses the ASCII character set.
          >
          How optimistic of you. The answer they were looking for could have been:
          >
          Integers are laid out in memory with the least significant byte first.
          >
          In other words, not just "this code is running on a little-endian
          platform" but "the whole world is little-endian, there is no such
          thing as big-endian, and no need for us to use or understand the
          descriptive term little-endian because there's no alternative from
          which it needs to be distinguished"
          Maybe so. If that's really their position, I don't want to work for
          them. But if they seem willing to listen when I explain the facts, I
          might conclude "Hey, these guys really need me!".

          --
          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."
          -- Antony Jay and Jonathan Lynn, "Yes Minister"

          Comment

          • Francine.Neary@googlemail.com

            #50
            Re: Puzzling program

            On Aug 10, 8:11 pm, Keith Thompson <ks...@mib.orgw rote:
            use unsigned int rather than int,
            I believe it's undefined behavior to cast a char * to an unsigned *
            and then dereference it, no less than casting to an int * and then
            dereferencing.
            and add a 'return 0;') Not caring about portability is no excuse
            for these errors.
            >
            --
            Keith Thompson (The_Other_Keit h) ks...@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."
            -- Antony Jay and Jonathan Lynn, "Yes Minister"

            Comment

            • Richard Heathfield

              #51
              Re: Puzzling program

              Francine.Neary@ googlemail.com said:

              <snip>
              I believe it's undefined behavior to cast a char * to an unsigned *
              and then dereference it,
              Why do you believe this?

              <snip>

              --
              Richard Heathfield <http://www.cpax.org.uk >
              Email: -www. +rjh@
              Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
              "Usenet is a strange place" - dmr 29 July 1999

              Comment

              • Dave Vandervies

                #52
                Re: Puzzling program

                In article <AtmdnZElSYDTxS fb4p2dnAA@bt.co m>,
                Richard Heathfield <rjh@see.sig.in validwrote:
                >Rajeet Dalawal said:
                >
                >Good day group.
                >>
                >I was asked in an interview to explain the behavior of this program.
                >>
                >void main()
                >{
                > char *s = "abc";
                > int *i = (int *) s;
                > printf("%x", *i);
                >}
                >>
                >The question is: why is the output 636261?
                >
                >No, it isn't. The question is: why is the interviewer asking you this
                >question? Is it to test your understanding that the program is
                >bug-ridden?
                [snippage]
                >If, on the other hand, he or she looks puzzled or disbelieving as you
                >explain the problems, thank him or her for the sandwiches and coffee,
                >make your excuses, and leave. You don't want to work there.
                I think, if I ever get asked to interview a C programmer, I should use
                this code or something very much like it.
                The questions about it, of course, will be a little bit more detailed
                than the one the OP posted:
                (a) If you feed this to your favorite C implementation, what results will
                you get?
                (b) What information does this provide about the implementation?
                (c.i) Is there a better way to write a program to get this information?
                (c.ii) Is there a better way to get this information?

                It should provide an excellent opportunity to determine levels of Clue
                on both sides, and will also provide some information about how much
                the interviewee understands about some of the things to be aware of when
                moving between implementations .


                dave

                --
                Dave Vandervies dj3vande@csclub .uwaterloo.ca
                Why not make it valid Pascal, Perl, Java, Basic, and Lisp also? Does your
                employer know that your code will have to be completely rewritten when they
                decide they want to compile it as a Java program? --Kevin Goodsell in CLC

                Comment

                • Francine.Neary@googlemail.com

                  #53
                  Re: Puzzling program

                  On Aug 11, 1:18 am, Richard Heathfield <r...@see.sig.i nvalidwrote:
                  Francine.Ne...@ googlemail.com said:
                  >
                  <snip>
                  >
                  I believe it's undefined behavior to cast a char * to an unsigned *
                  and then dereference it,
                  >
                  Why do you believe this?
                  OK... I'm a beginner at the whole quoting the Standard thing, but here
                  goes:

                  6.3.4 ... A pointer to an object or incomplete type can be converted
                  to a pointer to a different object or a different incomplete type. The
                  resulting pointer might not be valid if it is improperly aligned for
                  the type pointed to. It is guaranteed, however, that a pointer to an
                  object of a given alignment can be converted to a pointer to an object
                  of the same alignment or less strict alignment, and back again. The
                  result is equal to the original pointer. (An object of character type
                  has the least strict alignment.)

                  So converting char * to unsigned * means converting from char (which
                  has the least strict alignment) to something else (which therefore has
                  the same or more strict alignment). So there might be undefined
                  behavior, depending on the alignments in question. And if you have no
                  way of knowing when you write a line of code whether or not it will
                  produce undefined behavior when the program is run, it might be
                  prudent to assume the worst.

                  On the other hand, converting an unsigned * to a char * would be
                  guaranteed to "work", at least in the weak sense that you get a valid
                  pointer out. And you could also convert a char * to an unsigned *,
                  but /only if you knew it had arisen by a previous conversion from
                  unsigned * to char *./
                  >From a common sense point of view, let's say a char is 8 bits and
                  unsigned 32 bits (in some strange and exotic implementation X that
                  most people will never encounter :) ). Then the following code:

                  char c='a';
                  unsigned *p=(unsigned *) &c;
                  unsigned u=*p;

                  produces undefined behavior for another reason, i.e. the dereferencing
                  will read three bytes beyond the memory allocated for storing c.
                  <snip>
                  >
                  --
                  Richard Heathfield <http://www.cpax.org.uk >
                  Email: -www. +rjh@
                  Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                  "Usenet is a strange place" - dmr 29 July 1999

                  Comment

                  • Army1987

                    #54
                    Re: Puzzling program

                    On Fri, 10 Aug 2007 13:39:49 +0000, Christopher Benson-Manica wrote:
                    Keith Thompson <kst-u@mib.orgwrote:
                    >
                    >But there are an infinite number of DS9K implementations . (They're
                    >not required to exist physically, are they?)
                    >
                    Now that I think about it, they DO exist physically,
                    >
                    http://en.wikipedia.org/wiki/Many-worlds_interpretation
                    How do you think qsort is implemented on the DS9K? Whereas it was
                    originally intended that the 'q' stands for 'quick', the
                    implementers of DS9K interpreted is as 'quantum bogo'.

                    [OT, but in line with all the discussion about sorting algorithms
                    in another thread: The Jargon File claims that this implementation
                    of bogo-sort requires O(N), but to shuffle a deck with quantum
                    random numbers, one needs lg(N!) bits of quantum entropy, which
                    should take O(log(N!)) time, which is O(N*log(N)). I'll send an
                    e-mail to ESR pointing out the problem.]
                    --
                    Army1987 (Replace "NOSPAM" with "email")
                    No-one ever won a game by resigning. -- S. Tartakower

                    Comment

                    • Army1987

                      #55
                      Re: Puzzling program

                      On Fri, 10 Aug 2007 12:11:52 -0700, Keith Thompson wrote:
                      >Well, this may be more a case of "we're only coding for one specific
                      >platform, and don't care about portability". (Not that that's
                      >necessarily a good thing, but at least the code becomes "system
                      >specific behavior" rather than "errors". Of course, what happens
                      >when they decided to port to a similar, but 64-bit, platform?)
                      >
                      Here's the original program:
                      >
                      void main()
                      {
                      char *s = "abc";
                      int *i = (int *) s;
                      printf("%x", *i);
                      }
                      >
                      >
                      That's not just system-specific, it's *bad*. Even if you're assuming
                      a particular set of characteristics for the platform, I can think
                      of at least four corrections that should be made (add '#include
                      <stdio.h>', use 'int main(void)', use unsigned int rather than int,
                      and add a 'return 0;') Not caring about portability is no excuse
                      for these errors.
                      Even a newline at the end of the output wouldn't hurt.
                      --
                      Army1987 (Replace "NOSPAM" with "email")
                      No-one ever won a game by resigning. -- S. Tartakower

                      Comment

                      • pete

                        #56
                        Re: Puzzling program

                        Francine.Neary@ googlemail.com wrote:
                        >
                        On Aug 11, 1:18 am, Richard Heathfield <r...@see.sig.i nvalidwrote:
                        Francine.Ne...@ googlemail.com said:

                        <snip>
                        I believe it's undefined behavior to cast a char * to an unsigned *
                        and then dereference it,
                        Why do you believe this?
                        >
                        OK... I'm a beginner at the whole quoting the Standard thing, but here
                        goes:
                        >
                        6.3.4 ... A pointer to an object or incomplete type can be converted
                        to a pointer to a different object or a different incomplete type. The
                        resulting pointer might not be valid if it is improperly aligned for
                        the type pointed to. It is guaranteed, however, that a pointer to an
                        object of a given alignment can be converted to a pointer to an object
                        of the same alignment or less strict alignment, and back again. The
                        result is equal to the original pointer. (An object of character type
                        has the least strict alignment.)
                        >
                        So converting char * to unsigned * means converting from char (which
                        has the least strict alignment) to something else (which therefore has
                        the same or more strict alignment). So there might be undefined
                        behavior, depending on the alignments in question. And if you have no
                        way of knowing when you write a line of code whether or not it will
                        produce undefined behavior when the program is run, it might be
                        prudent to assume the worst.
                        >
                        On the other hand, converting an unsigned * to a char * would be
                        guaranteed to "work", at least in the weak sense that you get a valid
                        pointer out. And you could also convert a char * to an unsigned *,
                        but /only if you knew it had arisen by a previous conversion from
                        unsigned * to char *./
                        >
                        From a common sense point of view, let's say a char is 8 bits and
                        unsigned 32 bits (in some strange and exotic implementation X that
                        most people will never encounter :) ). Then the following code:
                        >
                        char c='a';
                        unsigned *p=(unsigned *) &c;
                        unsigned u=*p;
                        >
                        produces undefined behavior for another reason, i.e. the dereferencing
                        will read three bytes beyond the memory allocated for storing c.
                        You can convert a (char *) to an (unsigned *),
                        in a correct C program, if you do what it takes
                        to make sure that the alignment issue is taken care of.
                        Chapter 8 of K&R shows how to use a union to force alignment.

                        --
                        pete

                        Comment

                        • Malcolm McLean

                          #57
                          Re: Puzzling program


                          "Charlton Wilbur" <cwilbur@chroma tico.netwrote in message
                          news:874pj9cj02 .fsf@mithril.ch romatico.net...
                          >
                          Fortunately, you have a DeathStation 2000. I ran it on my
                          DeathStation 3000, and I'm hoping my eyebrows grow back.
                          >
                          It's a good idea to unplug the main anti-planet beam generator before doing
                          debug runs.

                          --
                          Free games and programming goodies.


                          Comment

                          • Default User

                            #58
                            Re: Puzzling program

                            pete wrote:

                            You can convert a (char *) to an (unsigned *),
                            in a correct C program, if you do what it takes
                            to make sure that the alignment issue is taken care of.
                            Chapter 8 of K&R shows how to use a union to force alignment.

                            The unsigned verison of a datatype is guaranteed to have the same
                            alignment as the signed type.

                            From the C99 draft:

                            6.2.5 Types

                            [#6] For each of the signed integer types, there is a
                            corresponding (but different) unsigned integer type |
                            (designated with the keyword unsigned) that uses the same
                            amount of storage (including sign information) and has the
                            same alignment requirements.



                            Brian

                            Comment

                            • Walter Roberson

                              #59
                              Re: Puzzling program

                              In article <5i6h3rF37t2ljU 1@mid.individua l.net>,
                              Default User <defaultuserbr@ yahoo.comwrote:
                              >pete wrote:
                              >You can convert a (char *) to an (unsigned *),
                              >in a correct C program, if you do what it takes
                              >to make sure that the alignment issue is taken care of.
                              >The unsigned verison of a datatype is guaranteed to have the same
                              >alignment as the signed type.
                              Yes, but (unsigned *) is a synonym for (unsigned int *)
                              and char and int are not guaranteed to have the same alignment
                              (and often do not.)
                              --
                              "It is important to remember that when it comes to law, computers
                              never make copies, only human beings make copies. Computers are given
                              commands, not permission. Only people can be given permission."
                              -- Brad Templeton

                              Comment

                              • Richard Heathfield

                                #60
                                Re: Puzzling program

                                Francine.Neary@ googlemail.com said:
                                On Aug 11, 1:18 am, Richard Heathfield <r...@see.sig.i nvalidwrote:
                                > Francine.Ne...@ googlemail.com said:
                                >>
                                ><snip>
                                >>
                                I believe it's undefined behavior to cast a char * to an unsigned *
                                and then dereference it,
                                >>
                                >Why do you believe this?
                                >
                                OK... I'm a beginner at the whole quoting the Standard thing, but here
                                goes:
                                Skip it. I'm a beginner at this whole reading thing. I thought you said
                                "char * to an unsigned char *" - unsigned * is a completely different
                                animal. Sorry about that.

                                --
                                Richard Heathfield <http://www.cpax.org.uk >
                                Email: -www. +rjh@
                                Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                                "Usenet is a strange place" - dmr 29 July 1999

                                Comment

                                Working...