Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Using &array with scanf

Reply
Thread Tools

Using &array with scanf

 
 
Keith Thompson
Guest
Posts: n/a
 
      01-05-2006
Mark McIntyre <(E-Mail Removed)> writes:
> On 5 Jan 2006 05:40:08 -0800, in comp.lang.c , "James Daughtry"
> <(E-Mail Removed)> wrote:
>>Unfortunately, he's the kind of person who uses the "it works for me"
>>argument.

>
> There's little point debating with such people. Give them the
> information, explain exactly once why its incorrect to do it
> otherwise, and walk away. If still they clean their gun while loaded,
> eventually Darwin will come to your rescue.


Natural selection is very much like undefined behavior; there's no
reason to assume it will work to your benefit. The gun he's cleaning
is just as likely to be pointed at your head. More relevantly, you're
like to have to use the code he writes.

Elsethread, I suggested several possibilities for demonstrating that
the "it works for me" approach doesn't work. If *those* don't work,
he may be impervious to reason. Deciding when to give up and accept
this, either by walking away or by somehow preventing his bad code
from affecting anything, is left as an exercise.

But people can sometimes surprise you by turning around becoming
reasonable when you least expect it (see "undefined behavior").

--
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.
 
Reply With Quote
 
 
 
 
Dik T. Winter
Guest
Posts: n/a
 
      01-06-2006
In article <(E-Mail Removed) .com> "James Daughtry" <(E-Mail Removed)> writes:
....
> 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.


Note the difference:

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

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


Here &array and array are cast to (void *). So although originally
&array and array may have had different representations, after the
cast they are the some. So this proves exactly nothing. The original
would have been correct if you had written:
scanf("%19s", (char *)&array);
I do not know whether there are, or have been, machines that use different
representations for char pointers and pointers to an array of chars, but
it is conceivable.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
 
Reply With Quote
 
 
 
 
Dik T. Winter
Guest
Posts: n/a
 
      01-06-2006
In article <(E-Mail Removed)> Keith Thompson <(E-Mail Removed)> writes:
....
> 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.)


The C compiler for the Data General did precisely what you wrote. That
is, a byte pointer would have the byte address in all 32 bits, a word
pointer would have a word address in the lowest 31 bits. And in a byte
pointer the lowest bit indicates the byte in a word.

And on both implementations when c is a char pointer, (char *)(int *)c
may lose information. (Ever tried to implement the original source of
the Bourne shell on such a machine?)

On the other hand, on both implementations a pointer to an array of
chars can not be a word pointer. (There are no padding bytes
between elements of an array.) So on those implementations the
representation of char * and char *[20] is the same. Consider
char a[5][5],
&(a[1]) must be a pointer to the array starting at the fifth byte, and so
can not be a word pointer. And it is the fifth byte because there is no
padding.

But this does *not* say that the pointers can not have different
representations, although I do not know of a system where that is
indeed the case.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
 
Reply With Quote
 
Dik T. Winter
Guest
Posts: n/a
 
      01-06-2006
In article <(E-Mail Removed)> Chris Torek <(E-Mail Removed)> writes:
....
> For a machine on which the type matters, find a 1960s era PR1ME, or
> perhaps even a 1980s Data General MV/10000 (aka Eclipse). (I am not
> sure whether the type "pointer to array N of char" on the Eclipse
> uses a word pointer, but if it does, the &array-with-scanf call will
> in fact fail.)


See my other article. It can not use a word pointer for a pointer to
array N of char, because there is no padding between elements of
arrays.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-06-2006
"Dik T. Winter" <(E-Mail Removed)> writes:
[snip]
> The C compiler for the Data General did precisely what you wrote. That
> is, a byte pointer would have the byte address in all 32 bits, a word
> pointer would have a word address in the lowest 31 bits. And in a byte
> pointer the lowest bit indicates the byte in a word.
>
> And on both implementations when c is a char pointer, (char *)(int *)c
> may lose information. (Ever tried to implement the original source of
> the Bourne shell on such a machine?)
>
> On the other hand, on both implementations a pointer to an array of
> chars can not be a word pointer. (There are no padding bytes
> between elements of an array.) So on those implementations the
> representation of char * and char *[20] is the same. Consider
> char a[5][5],
> &(a[1]) must be a pointer to the array starting at the fifth byte, and so
> can not be a word pointer. And it is the fifth byte because there is no
> padding.


You don't even have to resort to 2-dimensional arrays. Consider

char a[6];
typedef char (*array_ptr)[5];
array_ptr p0 = (array_ptr)a;
array_ptr p1 = (array_ptr)(a+1);

Both p0 and p1 are (I think!) valid pointers to arrays of 5 chars. p0
points to the array starting at element 0 of a; p1 points to the array
starting at element 1 of a (i.e., the last 5 of the 6 elements of a).

> But this does *not* say that the pointers can not have different
> representations, although I do not know of a system where that is
> indeed the case.


Agreed. Even if they happen to have the same representation on all
possible platforms, I wouldn't find it particularly convenient to be
able to make that assumption.

Note that the code snippet above doesn't assume anything about the
representations of the various types of pointers. It uses casts
(explicit conversions), so the compiler will take care of any change
of representation necessary to convert from one pointer type to
another. The original question was about arguments to scanf, for
which no such conversion takes place.

--
Keith Thompson (The_Other_Keith) (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.
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      01-06-2006
On 2006-01-06, Dik T. Winter <(E-Mail Removed)> wrote:
> In article <(E-Mail Removed)> Chris Torek <(E-Mail Removed)> writes:
> ...
> > For a machine on which the type matters, find a 1960s era PR1ME, or
> > perhaps even a 1980s Data General MV/10000 (aka Eclipse). (I am not
> > sure whether the type "pointer to array N of char" on the Eclipse
> > uses a word pointer, but if it does, the &array-with-scanf call will
> > in fact fail.)

>
> See my other article. It can not use a word pointer for a pointer to
> array N of char, because there is no padding between elements of
> arrays.


What about padding at the end of an array? Is a pointer to char
guaranteed to be convertible to a pointer to an array of chars?
 
Reply With Quote
 
eerok
Guest
Posts: n/a
 
      01-06-2006
Richard Heathfield wrote:
> eerok said:


>> Just to illustrate that it's *not* okay to get sloppy with
>> types, here's an example that I discovered the other day.


> The example you give doesn't fail because of a type issue, but because you
> attempt to write to storage that you're not supposed to write to. Had t1
> been pointing at writeable storage, you'd have had no segfault. For
> example, if you'd done this:
>
>> #include <stdio.h>
>>
>> char *t1 = "This can produce a segfault";
>> char t2[] = "Best to do it this way ....";

>
> char s[] = "This won't produce a segfault";
> t1 = s;
>
> you'd have had no problem, even though the type of t1 hasn't changed.


Thanks for your response, which forced me to do some reading.
If my understanding is correct now, my problem was caused by
trying to write to a string literal, resulting in UB.

I'm trying to scrape the rust off my C skills, which were
learned long ago on a PDP-11 ... between the things I've
forgotten and the things that have changed, I'm pretty much a
newbie again

--
"The secret of being boring is to say everything." - Voltaire



 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      01-06-2006
eerok said:

> Thanks for your response, which forced me to do some reading.
> If my understanding is correct now, my problem was caused by
> trying to write to a string literal, resulting in UB.


Correct.

> I'm trying to scrape the rust off my C skills, which were
> learned long ago on a PDP-11 ... between the things I've
> forgotten and the things that have changed, I'm pretty much a
> newbie again


You appear to learn reasonably quickly. Stick around clc, read more (much
more) than you write, and ask when you have to. If you do that, then within
a few months you should be sufficiently back up to speed to consider
answering questions here (which, if it can be done regularly without
getting your rear end handed to you on a platter, is almost enough to
qualify you as an "expert").

--
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)
 
Reply With Quote
 
Dik T. Winter
Guest
Posts: n/a
 
      01-06-2006
In article <(E-Mail Removed)> Jordan Abel <(E-Mail Removed)> writes:
> On 2006-01-06, Dik T. Winter <(E-Mail Removed)> wrote:

....
> > See my other article. It can not use a word pointer for a pointer to
> > array N of char, because there is no padding between elements of
> > arrays.

>
> What about padding at the end of an array?


No. The size of an array is the product of the number of elements and
the size of an element.

> Is a pointer to char
> guaranteed to be convertible to a pointer to an array of chars?


I do not think it is guaranteed that way. It *is* guaranteed the
other way.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
 
Reply With Quote
 
eerok
Guest
Posts: n/a
 
      01-06-2006
Richard Heathfield wrote:
> eerok said:


[...]

>> I'm trying to scrape the rust off my C skills, which were
>> learned long ago on a PDP-11 ... between the things I've
>> forgotten and the things that have changed, I'm pretty much a
>> newbie again


> You appear to learn reasonably quickly. Stick around clc, read more (much
> more) than you write, and ask when you have to. If you do that, then within
> a few months you should be sufficiently back up to speed to consider
> answering questions here (which, if it can be done regularly without
> getting your rear end handed to you on a platter, is almost enough to
> qualify you as an "expert").


Thanks, Richard. This newsgroup has been an enormous help to
me in the short time that I've been visiting here. Keep up
the good work

--
"The secret of being boring is to say everything." - Voltaire



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
difference between scanf("%i") and scanf("%d") ??? perhaps bug inVS2005? =?ISO-8859-1?Q?Martin_J=F8rgensen?= C Programming 18 05-02-2006 10:53 AM
scanf (yes/no) - doesn't work + deprecation errors scanf, fopen etc. =?ISO-8859-1?Q?Martin_J=F8rgensen?= C Programming 185 04-03-2006 02:49 PM
Re: Can I detect "enter" key using scanf? bd C Programming 0 08-07-2003 02:03 AM
Re: Can I detect "enter" key using scanf? Dan Pop C Programming 0 08-06-2003 11:32 AM
Re: Can I detect "enter" key using scanf? Ben Pfaff C Programming 0 08-05-2003 09:49 PM



Advertisments