Path: utzoo!utgpu!utstat!jarvis.csri.toronto.edu!mailrus!uflorida!beach.cis.ufl.edu!thoth From: thoth@beach.cis.ufl.edu (Robert Forsman) Newsgroups: comp.lang.c Subject: Re: pointers to arrays Message-ID: <19797@uflorida.cis.ufl.EDU> Date: 19 Feb 89 02:35:49 GMT References: <19784@uflorida.cis.ufl.EDU> <1042@auspex.UUCP> Sender: news@uflorida.cis.ufl.EDU Reply-To: thoth@beach.cis.ufl.edu () Organization: UF CIS Department Lines: 73 in article 13339 guy@auspex.UUCP writes > > Pointers are usually used to modify things, and you can definitely > modify an array by assigning to elements of that array: > > int (*foo)[13]; > int bar[13]; > > foo = &bar; > (*foo)[7] = 666; > > should work in an ANSI C program once ANSI C exists and programs can be > written in it and compiled by ANSI C-conformant compilers. > AUUUGH! what happens if you say (*foo) = muck (where muck is int muck[13]) Help! somebody's screwing with my stack. OK, lets assume this is a C compiler of the usual flavor (meaning one I can understand) and that foo and bar are local variables. For illustration purposes let's declare another pointer to int (int *intptr;) Now the stack might look like this. +-----+-----+-----+----------------+-----+-----+-----+ | NULL| 0 | 0 | (9 more ints) | 0 | 0 | NULL| +-----+-----+-----+----------------+-----+-----+-----+ foo ^--bar-------------------------------^ intptr When we modify foo the compiler generates code like MOVE_INTO_MEMORY_ADDR BasePointer+0, 424242 When we modify an element of bar it generates MOVE_INTO_MEMORY_ADDR BasePointer+8, 666 /* bar[7]=666; */ When we modify some element that intptr (it could point to an array) points to MOVE_MEMORY_INTO_REG REG, BasePointer+14 /* grab intptr */ MOVE_INTO_MEMORY REG+7, 666 /* intptr[7]=666; */ Note that the compiler knows where the array bar is -vs- it has to figure out where intptr is. You can say bar[7] and intptr[7] but the code is slightly different. bar is a CONSTANT (BasePointer+1), intptr is a VARIABLE! (data at memory location BasePointer+14). Using *(&intptr) you can modify the memory at Basepointer+14 but trying *(&bar) would be trying to modify the constant BasePointer+1. When you say bar the comiler knows EXACTLY where the elements are. When you use intptr the code has to go into memory to get the address of the elements. Since this address is stored in memory you can take its address and modify it. You take &bar 'cause you CANNOT modify bar AT ALL.. You can say bar[7]=4 all you want but if you say bar=intptr I'M GOING TO SHOOT YOU! :)- this is a tongue ^ Now messing with pointers can screw with your mind (I claim immunity) but the point (and I know I'm going to get flamed on this) is that bar is a constant and intptr is a variable. I KNOW bar[7] IS A VARIABLE, BUT bar IS NOT. Try changing it sometime. Any of you wizards out there who have managed to make it this far PLEASE support me and help stomp out the pointer/array debate, otherwise I'll gladly let you guys rot in hell and occasionally send you a letter with SEGMENTATION VIOLATION written on it. One of these days I'm going to try some of this stuff and really look at the assembler it generates to see how correct I am ( 0, 1, .643 who knows?). /* Sorry if there were any typos 'cause I don't know how to use emacs-yank- news-posting or whatever and had to copy it by hand. Frankly I think they should invent a version of C with training wheels, no pointers, no arrays just ints, chars and reals and say UNSUPPORTED on the other version. */ /* Of course my opinions are my own, I haven't recieved a word of support yet on this issue */ Just say maybe to .signature