Using &array with scanf

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

    Using &array with scanf

    char array[20];
    scanf("%19s", &array);

    I know this is wrong because it's a type mismatch, where scanf expects
    a pointer to char and gets a pointer to an array of 20 char. I know
    that question 6.12 of the C FAQ says that it's wrong for that very
    reason. What I don't know is where the standard tells me conclusively
    that it's wrong. What I also don't know is somewhere that this type
    mismatch will break in practice.

    A peer asked me recently why it was wrong when I told him that it was
    wrong, and I was very uncomfortable because I know it's wrong and I had
    no good answer when he asked me to prove it. So how do I prove
    something this to an exceptionally stubborn programmer who wants to
    have black and white proof as well as a real example that fails?

    Thanks!

  • Richard Heathfield

    #2
    Re: Using &array with scanf

    James Daughtry said:
    [color=blue]
    > char array[20];
    > scanf("%19s", &array);
    >
    > I know this is wrong because it's a type mismatch, where scanf expects
    > a pointer to char and gets a pointer to an array of 20 char.[/color]

    Yup. It's also wrong because it doesn't check the return value of scanf.
    [color=blue]
    > I know that question 6.12 of the C FAQ says that it's wrong for that very
    > reason.[/color]

    Yup.
    [color=blue]
    > What I don't know is where the standard tells me conclusively that it's
    > wrong.[/color]

    The fscanf specification:

    s Matches a sequence of non-white-space characters. The corresponding
    argument shall be a pointer to the initial character of an array large
    enough to accept the sequence and a terminating null character, which
    will be added automatically.

    &array is not a pointer to the initial character of an array large enough to
    accept the sequence; it's a pointer to an entire array. Different type.
    That's a violation of a "shall" outside a constraint, so the behaviour is
    undefined.
    [color=blue]
    > What I also don't know is somewhere that this type
    > mismatch will break in practice.[/color]

    Irrelevant. A conforming implementation which breaks it could be released
    tomorrow.
    [color=blue]
    > A peer asked me recently why it was wrong when I told him that it was
    > wrong, and I was very uncomfortable because I know it's wrong and I had
    > no good answer when he asked me to prove it.[/color]

    Ask him to explain how he can possibly confuse a char (*)[20] and a char *,
    given that they are completely different types with completely different
    sizes.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999

    email: rjh at above domain (but drop the www, obviously)

    Comment

    • Roland Csaszar

      #3
      Re: Using &array with scanf

      Hi,

      At 5 Jan 2006 05:12:32 -0800,
      James Daughtry wrote:[color=blue]
      >
      > char array[20];
      > scanf("%19s", &array);
      >
      > A peer asked me recently why it was wrong when I told him that it was
      > wrong, and I was very uncomfortable because I know it's wrong and I had
      > no good answer when he asked me to prove it.[/color]

      &array is a pointer to the pointer to the first element of array, it is
      of type char**, not char*.
      You can use
      scanf ("%19s", array);
      or
      scanf ("%19s", &array[0]);


      Regards,
      Roland
      --
      Roland Csaszar ----------- \\\ /// -------------- +43 316 495 2129
      Software Development ------ \\\ /// ----------- http://www.knapp.com
      KNAPP Logistics Automation - \\V// - mailto:roland.c saszar@knapp.co m

      Comment

      • James Daughtry

        #4
        Re: Using &array with scanf

        Richard Heathfield wisely wrote:[color=blue]
        > James Daughtry said:
        >[color=green]
        > > char array[20];
        > > scanf("%19s", &array);
        > >
        > > I know this is wrong because it's a type mismatch, where scanf expects
        > > a pointer to char and gets a pointer to an array of 20 char.[/color]
        >
        > Yup. It's also wrong because it doesn't check the return value of scanf.
        >[/color]

        Yea, I didn't want to dilute the example with error checking.
        Fortunately, I have no intention of compiling that snippet, and I don't
        imagine it will do any harm when executed as a Usenet post. ;-)
        [color=blue][color=green]
        > > I know that question 6.12 of the C FAQ says that it's wrong for that very
        > > reason.[/color]
        >
        > Yup.
        >[color=green]
        > > What I don't know is where the standard tells me conclusively that it's
        > > wrong.[/color]
        >
        > The fscanf specification:
        >
        > s Matches a sequence of non-white-space characters. The corresponding
        > argument shall be a pointer to the initial character of an array large
        > enough to accept the sequence and a terminating null character, which
        > will be added automatically.
        >
        > &array is not a pointer to the initial character of an array large enough to
        > accept the sequence; it's a pointer to an entire array. Different type.
        > That's a violation of a "shall" outside a constraint, so the behaviour is
        > undefined.
        >[/color]

        Ah, now that's my problem. I made a beeline to that very paragraph to
        prove my point, and the result was a quickie program much like the
        following. He was trying to tell me through the output of the program
        that array and &array result in the same address, and the type doesn't
        matter because scanf will treat the same address like a pointer to
        char, and the type mismatch is irrelevant.

        #include <stdio.h>

        int main(void)
        {
        char array[20];

        printf("%p\n%p\ n", (void*)&array, (void*)array);

        return 0;
        }

        Like I said, he's a stubborn little bugger.
        [color=blue][color=green]
        > > What I also don't know is somewhere that this type
        > > mismatch will break in practice.[/color]
        >
        > Irrelevant. A conforming implementation which breaks it could be released
        > tomorrow.
        >[/color]

        Unfortunately, he's the kind of person who uses the "it works for me"
        argument. I know he's wrong, you know he's wrong, but he refuses to
        admit that he's wrong until I can write a program that proves him
        wrong. :-P
        [color=blue][color=green]
        > > A peer asked me recently why it was wrong when I told him that it was
        > > wrong, and I was very uncomfortable because I know it's wrong and I had
        > > no good answer when he asked me to prove it.[/color]
        >
        > Ask him to explain how he can possibly confuse a char (*)[20] and a char *,
        > given that they are completely different types with completely different
        > sizes.
        >[/color]

        I asking him almost the same question. I asked why it should work when
        pointers of different types aren't required to have the same
        representation even if they point to the same address, adding emphasis
        by pointing out the relevant parts of the standard. Holding his ground,
        he ran the program again and said that the addresses are the same, then
        ran an incorrect scanf example to prove that it worked the way he
        expected, and repeated that scanf will do an implicit conversion
        internally.
        [color=blue]
        > --
        > Richard Heathfield
        > "Usenet is a strange place" - dmr 29/7/1999
        > http://www.cpax.org.uk
        > email: rjh at above domain (but drop the www, obviously)[/color]

        Comment

        • James Daughtry

          #5
          Re: Using &amp;array with scanf


          Roland Csaszar wrote:[color=blue]
          > &array is a pointer to the pointer to the first element of array, it is
          > of type char**, not char*.[/color]

          Actually, it's of type char (*)[20]. The address-of operation is one of
          the three cases where an array name isn't converted to a pointer to the
          first element of the array.

          Comment

          • kaikai

            #6
            Re: Using &amp;array with scanf

            "James Daughtry" <mordock32@hotm ail.com>
            ??????:11364667 52.665300.82290 @z14g2000cwz.go oglegroups.com. ..[color=blue]
            > char array[20];
            > scanf("%19s", &array);
            >
            > I know this is wrong because it's a type mismatch, where scanf expects
            > a pointer to char and gets a pointer to an array of 20 char. I know
            > that question 6.12 of the C FAQ says that it's wrong for that very
            > reason. What I don't know is where the standard tells me conclusively
            > that it's wrong. What I also don't know is somewhere that this type
            > mismatch will break in practice.
            >
            > A peer asked me recently why it was wrong when I told him that it was
            > wrong, and I was very uncomfortable because I know it's wrong and I had
            > no good answer when he asked me to prove it. So how do I prove
            > something this to an exceptionally stubborn programmer who wants to
            > have black and white proof as well as a real example that fails?
            >
            > Thanks!
            >[/color]

            scanf does not (also, could not) read arguments by their real type, that why
            it
            need a format string. All arguments will be reinterpreted from its value.
            Since
            array and &array do have the same value, the scanf function will produce
            same
            results. It is okay to write such code, but you'd better remember that it is
            a
            hack way.

            kaikai



            Comment

            • Ivan Budiselic

              #7
              Re: Using &amp;array with scanf

              "James Daughtry" <mordock32@hotm ail.com> wrote in message
              news:1136468408 .906944.212590@ g49g2000cwa.goo glegroups.com.. .[color=blue]
              > Richard Heathfield wisely wrote:[color=green][color=darkred]
              >> > A peer asked me recently why it was wrong when I told him that it was
              >> > wrong, and I was very uncomfortable because I know it's wrong and I had
              >> > no good answer when he asked me to prove it.[/color]
              >>
              >> Ask him to explain how he can possibly confuse a char (*)[20] and a char
              >> *,
              >> given that they are completely different types with completely different
              >> sizes.
              >>[/color]
              >
              > I asking him almost the same question. I asked why it should work when
              > pointers of different types aren't required to have the same
              > representation even if they point to the same address, adding emphasis
              > by pointing out the relevant parts of the standard. Holding his ground,
              > he ran the program again and said that the addresses are the same, then
              > ran an incorrect scanf example to prove that it worked the way he
              > expected, and repeated that scanf will do an implicit conversion
              > internally.
              >[/color]

              You can't prove something beyond proving it :) The simple fact that the
              standard renders the behavior undefined is certainly proof enough that it's
              plain wrong. As far as the C language is concerned, there is no "work" and
              "not work", or "correct" and "incorrect" once you enter the domain of UB.
              Anything at all can happen, including something that someone might think is
              "correct" (but, as I said before, there is no "correct", so he's wrong again
              :)

              There really is no point in trying to go beyond a simple quote to the
              relevant paragraphs of the standard.

              --
              Ivan Budiselic
              ICQ# 104044323
              IRC: buda @ #gamer.hr@quake net
              remove 'remove' for reply


              Comment

              • Richard Heathfield

                #8
                Re: Using &amp;array with scanf

                James Daughtry said:
                [color=blue]
                > Richard Heathfield wisely wrote:[color=green]
                >>
                >> &array is not a pointer to the initial character of an array large enough
                >> to accept the sequence; it's a pointer to an entire array. Different
                >> type. That's a violation of a "shall" outside a constraint, so the
                >> behaviour is undefined.
                >>[/color]
                >
                > Ah, now that's my problem. I made a beeline to that very paragraph to
                > prove my point, and the result was a quickie program much like the
                > following. He was trying to tell me through the output of the program
                > that array and &array result in the same address,[/color]

                But they don't. What they result in is [SFX - takes huge breath] a sequence
                of printable characters which, were it read back into scanf using a %p
                format specifier, would allow the retrieval of a pointer value which would
                refer to the same object as originally pointed to by the pointer value
                passed to printf.
                [color=blue]
                > and the type doesn't
                > matter because scanf will treat the same address like a pointer to
                > char,[/color]

                The Standard does not say this will happen, so what makes your friend so
                sure?
                [color=blue]
                > and the type mismatch is irrelevant.[/color]

                On the contrary, the type mismatch means the behaviour is undefined.
                [color=blue]
                > #include <stdio.h>
                >
                > int main(void)
                > {
                > char array[20];
                >
                > printf("%p\n%p\ n", (void*)&array, (void*)array);[/color]

                This program doesn't actually demonstrate anything useful.
                [color=blue]
                > Unfortunately, he's the kind of person who uses the "it works for me"
                > argument.[/color]

                Well, there's a certain amount to be said for such an argument! But I fail
                to see what it gains him. He acknowledges that scanf requires a char *, and
                he knows he's passing a char (*)[20] instead. He knows that omitting the &
                is a simple enough operation which will make the code squeaky-clean, and
                which is quicker to type than the wrong version. So he must have some very
                powerful motivation for typing that &. Perhaps you would do better to ask
                him what the & wins that pays for the type-wrongness of the code.

                Please note that the "it means I don't have to worry about whether to put an
                & on the front" is not a good-enough reason, because there are plenty of
                cases where it matters a lot whether char * or char (*)[] is supplied (not
                least when we start messing about with multi-dimensional arrays in argument
                expressions), so he can't just think "always use a &"; as a paradigm it
                doesn't work.

                So - what does being wrong /buy/ him? Let him answer that.
                [color=blue]
                > he ran the program again and said that the addresses are the same, then
                > ran an incorrect scanf example to prove that it worked the way he
                > expected, and repeated that scanf will do an implicit conversion
                > internally.[/color]

                What a trusting soul he is. Does he really think undefined behaviour will
                manifest its nastiness at the most convenient moment for /him/? Hah! It
                lurks. It waits in the background. It bides its time. And, when your boss
                is proudly looking on as you demo the code to your best customer...

                --
                Richard Heathfield
                "Usenet is a strange place" - dmr 29/7/1999

                email: rjh at above domain (but drop the www, obviously)

                Comment

                • Richard Heathfield

                  #9
                  Re: Using &amp;array with scanf

                  kaikai said:
                  [color=blue]
                  > Since
                  > array and &array do have the same value,[/color]

                  But they don't. The values have different types, so how can they be the
                  same?

                  Are $3.14 and 3.14kg the same? Of course not.
                  Are 3.14% and 3.14km the same? Of course not.

                  The type /matters/.
                  [color=blue]
                  > It is okay to write such code,[/color]

                  No, it isn't.

                  --
                  Richard Heathfield
                  "Usenet is a strange place" - dmr 29/7/1999

                  email: rjh at above domain (but drop the www, obviously)

                  Comment

                  • James Daughtry

                    #10
                    Re: Using &amp;array with scanf

                    Richard Heathfield wrote:[color=blue]
                    > James Daughtry said:
                    >[color=green]
                    > > Richard Heathfield wisely wrote:[color=darkred]
                    > >>
                    > >> &array is not a pointer to the initial character of an array large enough
                    > >> to accept the sequence; it's a pointer to an entire array. Different
                    > >> type. That's a violation of a "shall" outside a constraint, so the
                    > >> behaviour is undefined.
                    > >>[/color]
                    > >
                    > > Ah, now that's my problem. I made a beeline to that very paragraph to
                    > > prove my point, and the result was a quickie program much like the
                    > > following. He was trying to tell me through the output of the program
                    > > that array and &array result in the same address,[/color]
                    >
                    > But they don't. What they result in is [SFX - takes huge breath] a sequence
                    > of printable characters which, were it read back into scanf using a %p
                    > format specifier, would allow the retrieval of a pointer value which would
                    > refer to the same object as originally pointed to by the pointer value
                    > passed to printf.
                    >[/color]

                    :-D
                    [color=blue][color=green]
                    > > and the type doesn't
                    > > matter because scanf will treat the same address like a pointer to
                    > > char,[/color]
                    >
                    > The Standard does not say this will happen, so what makes your friend so
                    > sure?
                    >[/color]

                    Good question.
                    [color=blue][color=green]
                    > > and the type mismatch is irrelevant.[/color]
                    >
                    > On the contrary, the type mismatch means the behaviour is undefined.
                    >[/color]

                    To some people, "undefined" is just a word, and not even a scary word.
                    I'm sure that one day he'll get burned by UB and start to understand.
                    But until then, I have to work with the guy and suffer his "it works
                    for me" attitude.
                    [color=blue][color=green]
                    > > #include <stdio.h>
                    > >
                    > > int main(void)
                    > > {
                    > > char array[20];
                    > >
                    > > printf("%p\n%p\ n", (void*)&array, (void*)array);[/color]
                    >
                    > This program doesn't actually demonstrate anything useful.
                    >[/color]

                    That's what I thought. Sure, when he ran it the same two values were
                    printed, but it in no way proves that a type mismatch doesn't cause
                    problems.
                    [color=blue][color=green]
                    > > Unfortunately, he's the kind of person who uses the "it works for me"
                    > > argument.[/color]
                    >
                    > Well, there's a certain amount to be said for such an argument! But I fail
                    > to see what it gains him. He acknowledges that scanf requires a char *, and
                    > he knows he's passing a char (*)[20] instead. He knows that omitting the &
                    > is a simple enough operation which will make the code squeaky-clean, and
                    > which is quicker to type than the wrong version. So he must have some very
                    > powerful motivation for typing that &. Perhaps you would do better to ask
                    > him what the & wins that pays for the type-wrongness of the code.
                    >
                    > Please note that the "it means I don't have to worry about whether to put an
                    > & on the front" is not a good-enough reason, because there are plenty of
                    > cases where it matters a lot whether char * or char (*)[] is supplied (not
                    > least when we start messing about with multi-dimensional arrays in argument
                    > expressions), so he can't just think "always use a &"; as a paradigm it
                    > doesn't work.
                    >
                    > So - what does being wrong /buy/ him? Let him answer that.
                    >[/color]

                    I'll ask, that's a very good question.
                    [color=blue][color=green]
                    > > he ran the program again and said that the addresses are the same, then
                    > > ran an incorrect scanf example to prove that it worked the way he
                    > > expected, and repeated that scanf will do an implicit conversion
                    > > internally.[/color]
                    >
                    > What a trusting soul he is. Does he really think undefined behaviour will
                    > manifest its nastiness at the most convenient moment for /him/? Hah! It
                    > lurks. It waits in the background. It bides its time. And, when your boss
                    > is proudly looking on as you demo the code to your best customer...
                    >[/color]

                    Indeed. :-) Thanks for your comments, they were very helpful.

                    Comment

                    • Mike Wahler

                      #11
                      Re: Using &amp;array with scanf


                      "James Daughtry" <mordock32@hotm ail.com> wrote in message
                      news:1136468408 .906944.212590@ g49g2000cwa.goo glegroups.com.. .[color=blue]
                      > Richard Heathfield wisely wrote:[color=green]
                      >> James Daughtry said:
                      >>[color=darkred]
                      >> > char array[20];
                      >> > scanf("%19s", &array);
                      >> >
                      >> > I know this is wrong because it's a type mismatch, where scanf expects
                      >> > a pointer to char and gets a pointer to an array of 20 char.[/color]
                      >>
                      >> Yup. It's also wrong because it doesn't check the return value of scanf.
                      >>[/color]
                      >
                      > Yea, I didn't want to dilute the example with error checking.
                      > Fortunately, I have no intention of compiling that snippet, and I don't
                      > imagine it will do any harm when executed as a Usenet post. ;-)
                      >[color=green][color=darkred]
                      >> > I know that question 6.12 of the C FAQ says that it's wrong for that
                      >> > very
                      >> > reason.[/color]
                      >>
                      >> Yup.
                      >>[color=darkred]
                      >> > What I don't know is where the standard tells me conclusively that it's
                      >> > wrong.[/color]
                      >>
                      >> The fscanf specification:
                      >>
                      >> s Matches a sequence of non-white-space characters. The corresponding
                      >> argument shall be a pointer to the initial character of an array large
                      >> enough to accept the sequence and a terminating null character, which
                      >> will be added automatically.
                      >>
                      >> &array is not a pointer to the initial character of an array large enough
                      >> to
                      >> accept the sequence; it's a pointer to an entire array. Different type.
                      >> That's a violation of a "shall" outside a constraint, so the behaviour is
                      >> undefined.
                      >>[/color]
                      >
                      > Ah, now that's my problem. I made a beeline to that very paragraph to
                      > prove my point, and the result was a quickie program much like the
                      > following. He was trying to tell me through the output of the program[/color]

                      Someone who tries to prove program correctness (as defined by
                      the language standard) by using the behavior of a particular
                      implementation as evidence, is imo not really worthy of the
                      title 'programmer'.
                      [color=blue]
                      > that array and &array result in the same address,[/color]

                      Yes, the same 'value', but certainly not the same type.
                      Also note that while the 'value' might be the same,
                      the representation is not required to be the same.
                      [color=blue]
                      >and the type doesn't
                      > matter[/color]


                      According to the standard, it *does* matter, very much.
                      [color=blue]
                      > because scanf will treat the same address like a pointer to
                      > char,[/color]

                      Nowhere does the language standard make this assertion.
                      [color=blue]
                      > and the type mismatch is irrelevant.[/color]

                      It's *very* relevant, because it results in undefined behavior.
                      [color=blue]
                      >
                      > #include <stdio.h>
                      >
                      > int main(void)
                      > {
                      > char array[20];
                      >
                      > printf("%p\n%p\ n", (void*)&array, (void*)array);[/color]

                      This is valid because the types of the arguments being passed
                      have been converted to types which *are* valid for specifier
                      '%p'
                      [color=blue]
                      >
                      > return 0;
                      > }
                      >
                      > Like I said, he's a stubborn little bugger.[/color]

                      Taking your description as valid, he seems to be to be
                      both ignorant and arrogant. Very dangerous combination.
                      I sincerely hope he's not involved in creating critical
                      software (e.g. that controlling hospital equipment, etc.).
                      [color=blue]
                      >[color=green][color=darkred]
                      >> > What I also don't know is somewhere that this type
                      >> > mismatch will break in practice.[/color]
                      >>
                      >> Irrelevant. A conforming implementation which breaks it could be released
                      >> tomorrow.
                      >>[/color]
                      >
                      > Unfortunately, he's the kind of person who uses the "it works for me"
                      > argument.[/color]

                      And I predict he'll be very surprised when suddenly it
                      ceases to work, and he has no idea why.
                      [color=blue]
                      >I know he's wrong, you know he's wrong, but he refuses to
                      > admit that he's wrong until I can write a program that proves him
                      > wrong. :-P[/color]

                      That's a losing battle. No program can prove him right or wrong,
                      since it's not implementations that define the language, but the
                      ISO standard document (ISO 9899).
                      [color=blue]
                      >[color=green][color=darkred]
                      >> > A peer asked me recently why it was wrong when I told him that it was
                      >> > wrong, and I was very uncomfortable because I know it's wrong and I had
                      >> > no good answer when he asked me to prove it.[/color]
                      >>
                      >> Ask him to explain how he can possibly confuse a char (*)[20] and a char
                      >> *,
                      >> given that they are completely different types with completely different
                      >> sizes.
                      >>[/color]
                      >
                      > I asking him almost the same question. I asked why it should work when
                      > pointers of different types aren't required to have the same
                      > representation even if they point to the same address, adding emphasis
                      > by pointing out the relevant parts of the standard. Holding his ground,
                      > he ran the program again and said that the addresses are the same,[/color]


                      He can run it until doomsday, yet that will still prove nothing,
                      except perhaps a few things about a particular implementation.
                      [color=blue]
                      > then
                      > ran an incorrect scanf example to prove that it worked the way he
                      > expected,[/color]

                      That only proves that a particular implementation worked the
                      way he expected. It proves nothing at all about the correctness
                      of the code.

                      [color=blue]
                      > and repeated that scanf will do an implicit conversion
                      > internally.[/color]

                      Ask him to cite from where a guarantee of such a conversion
                      comes. Certainly not from ISO 9899.

                      -Mike


                      Comment

                      • Mike Wahler

                        #12
                        Re: Using &amp;array with scanf


                        "Roland Csaszar" <roland.csaszar @knapp.com> wrote in message
                        news:87lkxukdrr .wl%roland.csas zar@knapp.com.. .[color=blue]
                        > Hi,
                        >
                        > At 5 Jan 2006 05:12:32 -0800,
                        > James Daughtry wrote:[color=green]
                        >>
                        >> char array[20];
                        >> scanf("%19s", &array);
                        >>
                        >> A peer asked me recently why it was wrong when I told him that it was
                        >> wrong, and I was very uncomfortable because I know it's wrong and I had
                        >> no good answer when he asked me to prove it.[/color]
                        >
                        > &array is a pointer to the pointer[/color]

                        It is not. It is simply a pointer.
                        [color=blue]
                        > to the first element of array,[/color]

                        No. It's a pointer to the entire array.
                        [color=blue]
                        > it is
                        > of type char**, not char*.[/color]

                        No. It's type is char(*)[[20] (pointer to array of 20 char).
                        [color=blue]
                        > You can use
                        > scanf ("%19s", array);
                        > or
                        > scanf ("%19s", &array[0]);[/color]

                        Correct, since both expressions 'array' and '&array[0]'
                        yield the same type object.

                        -Mike


                        Comment

                        • Keith Thompson

                          #13
                          Re: Using &amp;array with scanf

                          "James Daughtry" <mordock32@hotm ail.com> writes:[color=blue]
                          > Richard Heathfield wisely wrote:[/color]
                          [snip][color=blue][color=green]
                          >> Ask him to explain how he can possibly confuse a char (*)[20] and a char *,
                          >> given that they are completely different types with completely different
                          >> sizes.[/color]
                          >
                          > I asking him almost the same question. I asked why it should work when
                          > pointers of different types aren't required to have the same
                          > representation even if they point to the same address, adding emphasis
                          > by pointing out the relevant parts of the standard. Holding his ground,
                          > he ran the program again and said that the addresses are the same, then
                          > ran an incorrect scanf example to prove that it worked the way he
                          > expected, and repeated that scanf will do an implicit conversion
                          > internally.[/color]

                          scanf doesn't do a conversion, implicit or otherwise. It takes
                          whatever bits you give it and *assumes* that they constitute a valid
                          representation of an object of the correct type. There are
                          open-source/freeware implementations of scanf; ask him to show you the
                          code that does this "implicit conversion".

                          On a machine where hardware addresses point to words, it's plausible
                          that a byte pointer (char*) will have a different representation than
                          a word pointer (such as int*); a word pointer could be a machine
                          address, while a byte pointer could be a machine address plus an
                          offset specifying one byte within the word. (The C compilers on Cray
                          vector machines almost do this, but they put the offset into the
                          otherwise unused high-order bits of the word pointer.)

                          He ran the program again *on the same platform* and claimed that he
                          had proven that it works correctly. Pick a platform that he doesn't
                          have access to and ask him to "prove" that his code works correctly on
                          that platform.

                          Show him the following program:

                          #include <stdio.h>
                          int main(void)
                          {
                          int before[10];
                          int array[10];
                          int after[10];
                          array[-1] = array[10] = 42;
                          printf("array[-1] = %d\n", array[-1]);
                          printf("array[10] = %d\n", array[10]);
                          return 0;
                          }

                          You and I know that it invokes undefined behavior. On most systems,
                          I'd be surprised if the manifestation of that undefined behavior were
                          something other than producing the following output:

                          array[-1] = 42
                          array[10] = 42

                          Compile and run the program several times, showing him the consistent
                          output each time. Ask him if this "proves" that accessing elements
                          outside an array is valid.

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

                          • Keith Thompson

                            #14
                            Re: Using &amp;array with scanf

                            Roland Csaszar <roland.csaszar @knapp.com> writes:[color=blue]
                            > At 5 Jan 2006 05:12:32 -0800,
                            > James Daughtry wrote:[color=green]
                            >>
                            >> char array[20];
                            >> scanf("%19s", &array);
                            >>
                            >> A peer asked me recently why it was wrong when I told him that it was
                            >> wrong, and I was very uncomfortable because I know it's wrong and I had
                            >> no good answer when he asked me to prove it.[/color]
                            >
                            > &array is a pointer to the pointer to the first element of array, it is
                            > of type char**, not char*.[/color]

                            Nope. Time to re-read section 6 of the comp.lang.c FAQ.

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

                            • Keith Thompson

                              #15
                              Re: Using &amp;array with scanf

                              Keith Thompson <kst-u@mib.org> writes:
                              [snip][color=blue]
                              > He ran the program again *on the same platform* and claimed that he
                              > had proven that it works correctly. Pick a platform that he doesn't
                              > have access to and ask him to "prove" that his code works correctly on
                              > that platform.[/color]

                              I suggest the IBM AS/400, especially if he's not familiar with it.
                              I'm not very familiar with it myself, but it seems to be a canonical
                              example of a system with a conforming C implementation that breaks a
                              lot of assumptions if you don't carefully stick to what the standard
                              actually guarantees; it's second only to the DS9K.

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

                              Working...