473,799 Members | 3,111 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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!

Jan 5 '06
30 3221
Mark McIntyre <ma**********@s pamcop.net> writes:
On 5 Jan 2006 05:40:08 -0800, in comp.lang.c , "James Daughtry"
<mo*******@hotm ail.com> 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_Keit h) ks***@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.
Jan 6 '06 #21
In article <11************ **********@g49g 2000cwa.googleg roups.com> "James Daughtry" <mo*******@hotm ail.com> 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/
Jan 6 '06 #22
In article <ln************ @nuthaus.mib.or g> Keith Thompson <ks***@mib.or g> 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/
Jan 6 '06 #23
In article <dp*********@ne ws2.newsguy.com > Chris Torek <no****@torek.n et> 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/
Jan 6 '06 #24
"Dik T. Winter" <Di********@cwi .nl> 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_Keit h) ks***@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.
Jan 6 '06 #25
On 2006-01-06, Dik T. Winter <Di********@cwi .nl> wrote:
In article <dp*********@ne ws2.newsguy.com > Chris Torek <no****@torek.n et> 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?
Jan 6 '06 #26
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

Jan 6 '06 #27
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)
Jan 6 '06 #28
In article <sl************ **********@rand om.yi.org> Jordan Abel <ra*******@gmai l.com> writes:
On 2006-01-06, Dik T. Winter <Di********@cwi .nl> 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/
Jan 6 '06 #29
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

Jan 6 '06 #30

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2012
by: Rvenkatesh | last post by:
How to use array string in C#.Net to compare and replace characters between strings using function.
5
3027
by: Oeleboele | last post by:
OK, I can't understand this exactly: I have this function: int howdy(void *) I first past this to the function &aCharArray I realized later that this should be aCharArray but... the former version also worked ? I can't understand why that worked. The only thing I can come up with is that the compiler gave me a break (although I did not receive any
6
26300
by: obdict | last post by:
Hello, I used scanf() in a while loop, which ensures that user input is valid (must be an integer no greater than 21 or less than 3). If user enters a number out of the range, or enters non-number, he/she will be asked to retry. /* start */ int n;
1
2991
by: nel | last post by:
hi.. i want to know how to insert data using array in mysql where the data stored in field given? this field_name i taken from database.... thanks a lot...
2
2573
by: palani12kumar | last post by:
Hi i've implemented a linear Queue using array. But i've been struck up with a doubt!!!!! Let me tell my problem with an example so that it can be clear. Size of the Queue(array) is 5. im initializing the front and rear to 0. I continously add five elements to the Queue, so that now the rear points to the 4th position of the array and now the queue is full. Now i delete all the five elements and now the Front and the Rear points at...
1
3681
shoonya
by: shoonya | last post by:
i am using array as a data type in my db .... ( sequence integer ) ; and it stores a value let {1,2,3,4,5}
2
5217
by: berrylthird | last post by:
This question was inspired by scripting languages such as JavaScript. In JavaScript, I can access members of a class using array syntax as in the following example: var myInstance:myClass = new myClass(); myInstance.member_0 = memberValue_0; // absolute notation myInstance = memberValue_0; // relative notation myInstance = memberValue_0; // nominal notation You can initialize a struct in C/C++ like you would an array, as with the...
5
3793
by: ryuchi311 | last post by:
In C++ using arrays. I need to create a C Program that will ask for five integers input from the user, then store these in an array. Then I need to find the lowest and highest integers inside that array and add them together. The output will be the result in this format: LOWEST+HIGHEST=SUM #include<stdio.h> void main (){ int r, low, hig, ans, index; for(index=0, index<4, index++){ printf("Enter number");
3
3286
by: theprofoundgeek | last post by:
Hi, I am writing a C code to add two matrices. I want to take input with a feel of real martice, some thing like 1 2 3 4 5 6 7 8 9 but the Scanf function automatically enter EOL and hence my input looks some thing like this,
0
9688
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10490
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10260
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10243
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10030
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9078
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6809
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5467
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5590
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.