From: Charles Richmond on
Joe Pfeiffer wrote:
> Charles Richmond <frizzle(a)tx.rr.com> writes:
>> ... but do *not* forget that when an integer is added to a pointer,
>> that integer is "scaled" by the length associated with that
>> pointer. So if "a" is a pointer to a four byte integer, then "a+1"
>> actually adds *four* to the pointer. The integer "1" is scaled by the
>> length of the object pointed to by "a".
>
> That fact took me several painful days to learn. I had (in a project I
> don't remember, for reasons I don't remember) used the + syntax
> dereferencing a buffer of integers, and had scaled it myself. Which
> meant, of course, that everything seemed fine for a ways into the
> buffer, then mysteriously segfaulted.
>
> Hmmm... I've got quite a few like that, with vividly remembered bugs in
> totally forgotten projects.

This scaling of an integer when added to a pointer... is
fundamental to the way C arrays and the array operator works.

--
+----------------------------------------+
| Charles and Francis Richmond |
| |
| plano dot net at aquaporin4 dot com |
+----------------------------------------+
From: Charles Richmond on
Ahem A Rivet's Shot wrote:
> On Sun, 7 Mar 2010 18:59:43 +0000 (UTC)
> johnf(a)panix.com (John Francis) wrote:
>
>> In article <20100307143020.fcc7e3df.steveo(a)eircom.net>,
>> Ahem A Rivet's Shot <steveo(a)eircom.net> wrote:
>>> On Sun, 07 Mar 2010 07:48:01 -0500
>>> Greg Menke <gusenet(a)comcast.net> wrote:
>>>
>>>> Ahem A Rivet's Shot <steveo(a)eircom.net> writes:
>>>>> The C subscript operator does do nothing other than adding
>>>>> two numbers and dereferencing the result, that last action is rather
>>>>> important. The validity of constructs like 2[a] and *(2+a) make this
>>>>> clear - as does the equivalence of a and &(a[0]) or of *a and a[0]
>>>>> where a is a pointer.
>>>> Yet when dereferencing arrays of rank >= 2, dimensions are
>>>> automatically incorporated into the effective address, so its not
>>>> quite equivalent to a simple addition of pointer and offset.
>>> There is a way to regard it as such - consider a[x][y] as being
>>> equivalent to *(a[x] + y) where we regard a[x] as devolving into a
>>> pointer to a row of the array. But yes multidimensional array support is
>>> a little more involved than single dimensional array support. It's still
>>> not a proper type though.
>> That's all very well, but in fact no C implementation of which I am
>> aware uses dope vectors when allocating multidimensional arrays. (I
>
> Indeed they don't - it is simply a matter of how you interpret the
> partial construct a[x] when a is declared as a two dimensional array - one
> way of interpreting it is as a pointer to an array row even though it is
> not a valid construct on it's own.
>
> There is a clear extension of the one dimentsional case a declaration
> int a[5] leaves future references to a as being equivalent to &(a[0]) so
> it is reasonable to regard a declaration int a[4][5] as leaving future
> references like a[i] as equivalent to &(a[i][0]).
>

One important point is: a two-dimensional array is a double
indirection. The construct "x[5][8]" is equivalent to
"*(*(x+5)+8)". Each of those two "*" does a dereference.

>> have come across the practice in other languages). In fact C has to
>> perform different calculations to evaluate the address of an element
>> a[i][j], depending on how a was defined (int a[4][5], or int** a).
>> The sizeof operator also knows something about array types.
>
> If a is defined as int **a then a[i][j] is not valid at all.
>

*Not* completely true. If a is a pointer to a pointer, it can be
dereference with **a:

x = **a;

equivalently, this can be written:

x = a[0][0];

since it is equivalent to:

x = *(*(a+0)+0);


--
+----------------------------------------+
| Charles and Francis Richmond |
| |
| plano dot net at aquaporin4 dot com |
+----------------------------------------+
From: Anssi Saari on
Charles Richmond <frizzle(a)tx.rr.com> writes:

> Yes, "2[c]" does work in C as well as "c[2]", and yields the same
> results. The definition of "c[x]" is "*(c+x)", where the array "c"
> becomes a pointer to the first element, and the integer value "x" is
> scaled by the length associated with the pointer "c". "*(c+x)" will
> give the same result as "*(x+c)", so it's logical.

Just curious, but why is it that "2[c]" doesn't seem to work as an
argument to printf? This simple example gives an error at compile, for
example:

#include <stdio.h>

int main()
{
char c[] = "12345678";
printf("%c\n", [2]c);
}

gcc says:

array_fun_mini_example.c: In function 'main':
array_fun_mini_example.c:6: error: expected expression before '[' token

I'm using gcc 4.3.2. Assignment like 2[c] = '1' and reading a value
like tmp = 2[c] seem to work fine, though.
From: Joe Pfeiffer on
Anssi Saari <as(a)sci.fi> writes:

> Charles Richmond <frizzle(a)tx.rr.com> writes:
>
>> Yes, "2[c]" does work in C as well as "c[2]", and yields the same
>> results. The definition of "c[x]" is "*(c+x)", where the array "c"
>> becomes a pointer to the first element, and the integer value "x" is
>> scaled by the length associated with the pointer "c". "*(c+x)" will
>> give the same result as "*(x+c)", so it's logical.
>
> Just curious, but why is it that "2[c]" doesn't seem to work as an
> argument to printf? This simple example gives an error at compile, for
> example:
>
> #include <stdio.h>
>
> int main()
> {
> char c[] = "12345678";
> printf("%c\n", [2]c);
> }
>
> gcc says:
>
> array_fun_mini_example.c: In function 'main':
> array_fun_mini_example.c:6: error: expected expression before '[' token
>
> I'm using gcc 4.3.2. Assignment like 2[c] = '1' and reading a value
> like tmp = 2[c] seem to work fine, though.

Possibly because your program uses [2]c, not 2[c].
--
As we enjoy great advantages from the inventions of others, we should
be glad of an opportunity to serve others by any invention of ours;
and this we should do freely and generously. (Benjamin Franklin)
From: Michael Wojcik on
Peter Flass wrote:
> Michael Wojcik wrote:
>> Peter Flass wrote:
>>> Hey! C's finally caught up to PL/I. Only took them 50 years, and then
>>> of course all the features are just tacked-on in true C fashion, instead
>>> of thought-through.
>>
>> Well, that's rather insulting to the members of WG14, who spent a
>> decade designing those features. Fortunately, they published the
>> Rationale showing that, in fact, they were thought through.[1] And a
>> great deal of documentation describing the process is available in the
>> archives.[2]
>>
>> If you'd care to show why you think otherwise, perhaps there would be
>> some grounds for debate.
>
> "The flexible array must be last"?

Doing otherwise would break existing code. WG14's remit is to maintain
upward compatibility.

> "sizeof applied to the structure ignores the array but counts any
> padding before it"?

I have no idea what you're quoting there. That phrase doesn't seem to
be present in my copy of the standard.

> C is a collection of ad-hoc ideas. WG14 may have put a great deal of
> thought into how to extend it without breaking the existing mosh, but
> that's my point, it's still a mosh.

If that was your point, then I have to say it was rather ill-expressed.

--
Michael Wojcik
Micro Focus
Rhetoric & Writing, Michigan State University