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.
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/
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/
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/
"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.
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?
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
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)
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/
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Rvenkatesh |
last post by:
How to use array string in C#.Net to compare and replace
characters between strings using function.
|
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
|
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;
|
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...
|
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...
| |
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}
|
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...
|
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");
|
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,
|
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...
|
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...
| |
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...
|
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,...
|
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...
|
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...
|
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();...
|
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...
| |
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |