473,788 Members | 3,030 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 #1
30 3219
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.
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.
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.
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.

--
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 5 '06 #2
Hi,

At 5 Jan 2006 05:12:32 -0800,
James Daughtry wrote:

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

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.


&array is a pointer to the pointer to the first element of array, it is
of type char**, not char*.
You can use
scanf ("%19s", array);
or
scanf ("%19s", &array[0]);
Regards,
Roland
--
Roland Csaszar ----------- \\\ /// -------------- +43 316 495 2129
Software Development ------ \\\ /// ----------- http://www.knapp.com
KNAPP Logistics Automation - \\V// - mailto:ro****** ******@knapp.co m
Jan 5 '06 #3
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
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.

#include <stdio.h>

int main(void)
{
char array[20];

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

return 0;
}

Like I said, he's a stubborn little bugger.
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. 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
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, then
ran an incorrect scanf example to prove that it worked the way he
expected, and repeated that scanf will do an implicit conversion
internally.
--
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 5 '06 #4

Roland Csaszar wrote:
&array is a pointer to the pointer to the first element of array, it is
of type char**, not char*.


Actually, it's of type char (*)[20]. The address-of operation is one of
the three cases where an array name isn't converted to a pointer to the
first element of the array.

Jan 5 '06 #5
"James Daughtry" <mo*******@hotm ail.com>
??????:11****** *************** @z14g2000cwz.go oglegroups.com. ..
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!


scanf does not (also, could not) read arguments by their real type, that why
it
need a format string. All arguments will be reinterpreted from its value.
Since
array and &array do have the same value, the scanf function will produce
same
results. It is okay to write such code, but you'd better remember that it is
a
hack way.

kaikai

Jan 5 '06 #6
"James Daughtry" <mo*******@hotm ail.com> wrote in message
news:11******** **************@ g49g2000cwa.goo glegroups.com.. .
Richard Heathfield wisely wrote:
> 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, then
ran an incorrect scanf example to prove that it worked the way he
expected, and repeated that scanf will do an implicit conversion
internally.


You can't prove something beyond proving it :) The simple fact that the
standard renders the behavior undefined is certainly proof enough that it's
plain wrong. As far as the C language is concerned, there is no "work" and
"not work", or "correct" and "incorrect" once you enter the domain of UB.
Anything at all can happen, including something that someone might think is
"correct" (but, as I said before, there is no "correct", so he's wrong again
:)

There really is no point in trying to go beyond a simple quote to the
relevant paragraphs of the standard.

--
Ivan Budiselic
ICQ# 104044323
IRC: buda @ #gamer.hr@quake net
remove 'remove' for reply
Jan 5 '06 #7
James Daughtry said:
Richard Heathfield wisely wrote:

&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
that array and &array result in the same address,


But they don't. What they result in is [SFX - takes huge breath] a sequence
of printable characters which, were it read back into scanf using a %p
format specifier, would allow the retrieval of a pointer value which would
refer to the same object as originally pointed to by the pointer value
passed to printf.
and the type doesn't
matter because scanf will treat the same address like a pointer to
char,
The Standard does not say this will happen, so what makes your friend so
sure?
and the type mismatch is irrelevant.
On the contrary, the type mismatch means the behaviour is undefined.
#include <stdio.h>

int main(void)
{
char array[20];

printf("%p\n%p\ n", (void*)&array, (void*)array);
This program doesn't actually demonstrate anything useful.
Unfortunately, he's the kind of person who uses the "it works for me"
argument.
Well, there's a certain amount to be said for such an argument! But I fail
to see what it gains him. He acknowledges that scanf requires a char *, and
he knows he's passing a char (*)[20] instead. He knows that omitting the &
is a simple enough operation which will make the code squeaky-clean, and
which is quicker to type than the wrong version. So he must have some very
powerful motivation for typing that &. Perhaps you would do better to ask
him what the & wins that pays for the type-wrongness of the code.

Please note that the "it means I don't have to worry about whether to put an
& on the front" is not a good-enough reason, because there are plenty of
cases where it matters a lot whether char * or char (*)[] is supplied (not
least when we start messing about with multi-dimensional arrays in argument
expressions), so he can't just think "always use a &"; as a paradigm it
doesn't work.

So - what does being wrong /buy/ him? Let him answer that.
he ran the program again and said that the addresses are the same, then
ran an incorrect scanf example to prove that it worked the way he
expected, and repeated that scanf will do an implicit conversion
internally.


What a trusting soul he is. Does he really think undefined behaviour will
manifest its nastiness at the most convenient moment for /him/? Hah! It
lurks. It waits in the background. It bides its time. And, when your boss
is proudly looking on as you demo the code to your best customer...

--
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 5 '06 #8
kaikai said:
Since
array and &array do have the same value,
But they don't. The values have different types, so how can they be the
same?

Are $3.14 and 3.14kg the same? Of course not.
Are 3.14% and 3.14km the same? Of course not.

The type /matters/.
It is okay to write such code,


No, it isn't.

--
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 5 '06 #9
Richard Heathfield wrote:
James Daughtry said:
Richard Heathfield wisely wrote:

&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
that array and &array result in the same address,


But they don't. What they result in is [SFX - takes huge breath] a sequence
of printable characters which, were it read back into scanf using a %p
format specifier, would allow the retrieval of a pointer value which would
refer to the same object as originally pointed to by the pointer value
passed to printf.


:-D
and the type doesn't
matter because scanf will treat the same address like a pointer to
char,


The Standard does not say this will happen, so what makes your friend so
sure?


Good question.
and the type mismatch is irrelevant.


On the contrary, the type mismatch means the behaviour is undefined.


To some people, "undefined" is just a word, and not even a scary word.
I'm sure that one day he'll get burned by UB and start to understand.
But until then, I have to work with the guy and suffer his "it works
for me" attitude.
#include <stdio.h>

int main(void)
{
char array[20];

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


This program doesn't actually demonstrate anything useful.


That's what I thought. Sure, when he ran it the same two values were
printed, but it in no way proves that a type mismatch doesn't cause
problems.
Unfortunately, he's the kind of person who uses the "it works for me"
argument.


Well, there's a certain amount to be said for such an argument! But I fail
to see what it gains him. He acknowledges that scanf requires a char *, and
he knows he's passing a char (*)[20] instead. He knows that omitting the &
is a simple enough operation which will make the code squeaky-clean, and
which is quicker to type than the wrong version. So he must have some very
powerful motivation for typing that &. Perhaps you would do better to ask
him what the & wins that pays for the type-wrongness of the code.

Please note that the "it means I don't have to worry about whether to put an
& on the front" is not a good-enough reason, because there are plenty of
cases where it matters a lot whether char * or char (*)[] is supplied (not
least when we start messing about with multi-dimensional arrays in argument
expressions), so he can't just think "always use a &"; as a paradigm it
doesn't work.

So - what does being wrong /buy/ him? Let him answer that.


I'll ask, that's a very good question.
he ran the program again and said that the addresses are the same, then
ran an incorrect scanf example to prove that it worked the way he
expected, and repeated that scanf will do an implicit conversion
internally.


What a trusting soul he is. Does he really think undefined behaviour will
manifest its nastiness at the most convenient moment for /him/? Hah! It
lurks. It waits in the background. It bides its time. And, when your boss
is proudly looking on as you demo the code to your best customer...


Indeed. :-) Thanks for your comments, they were very helpful.

Jan 5 '06 #10

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
26294
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
3792
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
10172
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
10110
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
9964
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
6749
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
5398
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
5535
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4069
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3670
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2894
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.