SSCANF

  • Thread starter Superfox il Volpone
  • Start date
C

Chris Torek

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

Keith Thompson

Flash Gordon said:
<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.)
 
R

Robert Harris

Flash said:
Robert Harris wrote:

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top