Velocity Reviews > SSCANF

# SSCANF

Chris Torek
Guest
Posts: n/a

 01-04-2006
In article <djNuf.70590\$(E-Mail Removed) >
Robert Harris <(E-Mail Removed)> wrote:
>... If mese is an array, then mese and &mese are the same thing.

In much the same way that 3 and 3.141592653589793 are "the same
thing", i.e., they compare equal when converted to some particular
common type (int, in this case).

The problem is that "&mese" has the wrong type. It is hard to
compare two values of different types (are 3 and 3.14 equal?); the
first step in such a comparison is to choose some additional type
-- perhaps one of the original two, or perhaps a third -- and
convert all the values to the same type, after which they can
finally be compared.

In the case of 3 and 3.14, if the type chosen for comparison is
"int", they are equal. If the type chosen for comparison is
"double", they are not equal. So 3 and 3.14 are equal, and yet
are also not equal.

I use the above example to make it clear that it is not sufficient
to find *a* type under conversion to which comparison shows the
original values as equal: while (int)3 == (int)3.14, I think most
people would say that 3 and 3.14 are *not* equal, and indeed,
(double)3 != (double)3.14.

You would have a much stronger case if you could prove that, for
some large set of C types \elem T, (T)mese == (T)&mese; but I think
this is impossible to prove in "Standard C Virtual Machine", due
to lack of information. (It actually happens to be true on many
real machines, if only because so many real machines have only one
hardware "pointer" type, or at least, only one that is used by C
compilers. The test is more interesting -- not a "degenerate case"
as a mathematician might put it -- when performed on machines with
actual different hardware pointer types, such as a Data General
MV/10000, or a 1960s PR1ME, or some such.)

In any case, Standard C permits an 80x86 C compiler to pass mese
(or &mese[0]) in a register, but put &mese on the stack (or vice
versa), simply because the types differ. If an 80x86 C compiler
did this, calls using the wrong type would in fact fail, even on
the ordinary 80x86. (In this particular case, &mese[0] has type
(char *), but &mese has type (char (*)[5]).)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
Reading email is like searching for food in the garbage, thanks to spammers.

Keith Thompson
Guest
Posts: n/a

 01-04-2006
Flash Gordon <(E-Mail Removed)> writes:
> Robert Harris wrote:
>> Superfox il Volpone wrote:
>>> Sorry people, what I posted it's part of a more large program and the
>>> printf with I verified it was wrong
>>>
>>> I solved but I don't understand one thing :
>>> the sscanf works with '&mese' and 'mese' in the correct manner : maybe
>>> it's the compiler (GCC) that does some correction ?

>> No. If mese is an array, then mese and &mese are the same thing.

>
> <snip>
>
> No they are not, they have different types. As a result of this,
> passing the wrong one as one of the varidac parameters to sscanf
> *could* cause it to fail, although I'm not aware of any
> implementations on which it would. The failure could occur if pointer
> to array of char used a different representation to pointer to char
> (say, an implementation encoded the size of the array in pointer to
> array of char but not in pointer to char). It will also cause the
> compiler to complain at you if you pass a pointer to array of char to
> a function expecting a pointer to char.

Perhaps more realistically, byte pointers could be bigger than word
pointers. This could happen on a system where native machine
addresses point to words, and the C implementation needs a word
pointer and an offset to refer to a byte within a word. (The C
implementation for Cray vector machines *almost* does this, but it
puts the offset into the otherwise unused high-order bits of the word
pointer, so a pointer to the first byte of a word still happens to
have the same representation as a pointer to the entire word.)

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <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.

Robert Harris
Guest
Posts: n/a

 01-04-2006
Flash Gordon wrote:
> Robert Harris wrote:
>
>
>>> <snip>
>>>
>>> No they are not, they have different types. As a result of this,
>>> passing the wrong one as one of the varidac parameters to sscanf
>>> *could* cause it to fail, although I'm not aware of any
>>> implementations on which it would. The failure could occur if pointer
>>> to array of char used a different representation to pointer to char
>>> (say, an implementation encoded the size of the array in pointer to
>>> array of char but not in pointer to char). It will also cause the
>>> compiler to complain at you if you pass a pointer to array of char to
>>> a function expecting a pointer to char.

>>
>> Yes they are. For the array mese passed as a parameter, paragraph
>> 6.3.2.1 of the C standard applies, and I quote:
>>
>> 'Except when it is used as an operand of the sizeof operator or the
>> unary & operator, or is a string literal used to initialize an array, an

>
> ^^^^^^^^^^^^^^^^
>
>> expression that has type "array of type" is convered to an expression
>> with type "pointer to type" that points to the initial element of the
>> array object ...'

>
>
> So it is still of array type when operated on by the & operator.
>
>> While for &mese passed as a parameter, paragraph 6.5.3.2 applies:
>>
>> 'The unary & operation returns the address of its operand. If the
>> operand has type "type", the result has type "pointer to type".'

>
>
> So the type above is array of whatever. So the type returned by & is
> pointer to array of whatever.
>
>> So they are the same (in the context of being passed as parameters to
>> a function).

>
>
> No, see above.
>
> The addresses are the same, but the types are not. So, for example, we
> get from gcc:
> markg@markgordon-lp ~
> \$ cat t.c
> void foo(char *s)
> {
> }
>
> int main(void)
> {
> char fred[10];
> foo(fred);
> foo(&fred);
> }
>
> markg@markgordon-lp ~
> \$ gcc -ansi -pedantic -O t.c
> t.c: In function `main':
> t.c:9: warning: passing arg 1 of `foo' from incompatible pointer type

Sorry, You're right.

Robert