Re: Using &array with scanf




"James Daughtry" <mordock32@xxxxxxxxxxx> wrote in message
news:1136468408.906944.212590@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Richard Heathfield wisely wrote:
>> James Daughtry said:
>>
>> > 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.
>>
>> Yup. It's also wrong because it doesn't check the return value of scanf.
>>
>
> 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. ;-)
>
>> > I know that question 6.12 of the C FAQ says that it's wrong for that
>> > very
>> > reason.
>>
>> Yup.
>>
>> > What I don't know is where the standard tells me conclusively that it's
>> > wrong.
>>
>> 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.
>>
>
> 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

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

> that array and &array result in the same address,

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.

>and the type doesn't
> matter


According to the standard, it *does* matter, very much.

> because scanf will treat the same address like a pointer to
> char,

Nowhere does the language standard make this assertion.

> and the type mismatch is irrelevant.

It's *very* relevant, because it results in undefined behavior.

>
> #include <stdio.h>
>
> int main(void)
> {
> char array[20];
>
> printf("%p\n%p\n", (void*)&array, (void*)array);

This is valid because the types of the arguments being passed
have been converted to types which *are* valid for specifier
'%p'

>
> return 0;
> }
>
> Like I said, he's a stubborn little bugger.

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

>
>> > What I also don't know is somewhere that this type
>> > mismatch will break in practice.
>>
>> Irrelevant. A conforming implementation which breaks it could be released
>> tomorrow.
>>
>
> Unfortunately, he's the kind of person who uses the "it works for me"
> argument.

And I predict he'll be very surprised when suddenly it
ceases to work, and he has no idea why.

>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

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

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


He can run it until doomsday, yet that will still prove nothing,
except perhaps a few things about a particular implementation.

> then
> ran an incorrect scanf example to prove that it worked the way he
> expected,

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


> and repeated that scanf will do an implicit conversion
> internally.

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

-Mike


.



Relevant Pages

  • Re: why cannot assign to function call
    ... hypothetical C-like languages, ... sizeof business would still indicate that a pointer was being passed. ... talk about variables of an array type. ... the earlier version of the standard didn't have numbered ...
    (comp.lang.python)
  • Re: Rules for valid pointer deallocation
    ... Here, you pointer isn't ... the array section array_ref. ... The Fortran standard does not say that the whole array ...
    (comp.lang.fortran)
  • Re: multi dimensional arrays as one dimension array
    ... please - where does the standard say that such a conversion ... Pointer conversion yields a pointer to the same object as ... exist only where there are array declarations. ...
    (comp.lang.c)
  • Re: Using &array with scanf
    ... >> a pointer to char and gets a pointer to an array of 20 char. ... It's also wrong because it doesn't check the return value of scanf. ... and the type mismatch is irrelevant. ...
    (comp.lang.c)
  • Re: Out-of-bounds nonsense
    ... we've been discussing the accessing of array elements ... Both the C Standard and the C++ Standard necessitate that the four int's be ... 6.5.6p8 of the C standard says about C pointer arithmetic. ... is 'int' that contains the object it points at is the sub-array a. ...
    (comp.std.c)