On Fri, Sep 20, 2024 at 11:17 AM Dave Horsfall <dave(a)horsfall.org> wrote:
On Fri, 20 Sep 2024, Paul Winalski wrote:
On Thu, Sep 19, 2024 at 7:52 PM Rich Salz
<rich.salz(a)gmail.com> wrote:
In my first C programming job I saw the source to V7 grep which
had a "foo[-2]" construct.
That sort of thing is very dangerous with modern compilers. Does K&R C
require that variables be allocated in the order that they are declared? If
not, you're playing with fire. To get decent performance out of modern
processors, the compiler must perform data placement to maximize cache
efficiency, and that practically guarantees that you can't rely on
out-of-bounds array references.
[...]
Unless I'm mistaken (quite possible at my age), the OP was referring to
that in C, pointers and arrays are pretty much the same thing i.e.
"foo[-2]" means "take the pointer 'foo' and go back two
things" (whatever
a "thing" is).
Where I've usually seen this idiom is in things like:
char foo[10];
char *p = foo + 5;
p[-2] = 'a'; /* set foo[3] to 'a' */
But as Paul pointed out, a) this relies on aliasing the bytes in
`foo`, and b) is UB if the (negative) index falls below the beginning
of the underlying object (e.g., the array `foo`).
C is just a high level assembly language; there is no
such object as a
"string" for example: it's just an "array of char" with the last
element
being "\0" (viz: "strlen" vs. "sizeof".
Sadly, this hasn't been true for a few decades; arguably since
optimizing compilers for C started to become common in the 70s. Trying
to treat C as a high-level macro assembler is dangerous, as Paul
pointed out, even though a lot of us feel like we can "see" the
assembly that a line of C code will likely emit. While in many cases
we are probably right (or close to it), C _compiler writers_ don't
think in those terms, but rather think in terms of operations
targeting the abstract virtual machine loosely described by the
language standard. Caveat emptor, there be dragons.
What's the length of "abc" vs. how many
bytes are needed to store it?
Things were much simpler when V7 was written.
Giggle... In a device driver I wrote for V6, I used the expression
"0123"[n]
and the two programmers whom I thought were better than me had to ask me
what it did...
Fortunately, this is still legal. :-)
- Dan C.