4 ms·
And that's how it's still taught nowadays. Both the C89 and the C99 standard draft contain the following: > The definition of the subscript operator [] is tha
by st_goliath 6y ago
And that's how it's still taught nowadays.
Both the C89 and the C99 standard draft contain the following:
> The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))
In fact the expressions a[b] *(a + b) and b[a] are equivalent.
Here is a perfectly valid snippet of C code that will print out 't':
putchar(3["test"]);
- mschuster91 6y agoI understand why that example works but I struggle finding a valid use-case, aside from code golfing...
- cat199 6y agospeculating, but don't think it's about use case so much as it is about it being a simple way to implement ('C is portable assembly') which probably carried through to our more current notion of this being a 'language level' thing
- charcircuit 6y agoNot everything needs a valid use case. It can exist just for fun.
- mschuster91 6y agoThe thing is, the more complex a spec is (or rather, how much stuff it allows that will never be used), the bigger the danger is that somewhen down the line, this will introduce a security or other issue.
- Koshkin 6y agoI think the assumption that addition is commutative in any context simplifies the spec rather than makes it more complex.
- mschuster91 6y agoIt however is not "natural" for someone who doesn't know the obscure bits of history in a standard written many decades ago. Someone writing, say, a static code analysis tool or an IDE may not assume that it is possible that in the expression `a[b]` a may be something else than a pointer / array.
- Koshkin 6y agoBut pointer arithmetic is not "obscure bits of history."
- chrisseaton 6y ago> Someone writing, say, a static code analysis tool or an IDE may not assume If you're writing a static analysis tool or an IDE then I think it's fine to expect you to read the spec.
- pessimizer 6y agoIt's not an array trick, it's a definition of arrays.
- kragen 6y agoIt isn't a use case; it is a drawback of the C array and pointer semantics: - Array values decay to pointers in rvalue contexts (though not as the argument of sizeof); - a[b] is syntactic sugar for *(a+b). — ⁂ — These two design decisions have some desirable results: - Arrays, including strings, can be in effect passed as arguments to functions without implementing a special parameter-passing mechanism for arrays. - Functions on arrays are implicitly generic over the array length, rather than that length being a part of their type. (When this isn't what you want you should probably be using a struct instead.) - Array iteration state can be represented as a pointer, preventing bugs in which you index the wrong array. In a sense a single pointer represents an array range or slice, as long as you have some way to identify the array end, like nul-termination in strings or a separate length argument. - You can change a variable (including a struct field) from being an embedded array to being a pointer to an array allocated elsewhere—or vice versa—without changing the code that uses it. (But if this had been a significant design consideration, -> wouldn't be a separate operator from . in C.) - It's easy to create new "arrays" at runtime: just return a pointer to some memory. — ⁂ — Like all design tradeoffs, these also have some drawbacks, which are so severe that no language of the current millennium has followed C's lead on this, although many of C's other design decisions are wildly popular: - Bounds checking is impossible. - Alias analysis for optimization is infeasible. - If you aren't using a sentinel, you have to pass in a separate argument containing the array length whenever you pass in an array pointer, or stuff these base and limit fields into a slice struct, or something. - Arguably, these decisions are hard to separate from the fact that C strings are terminated by a sentinel value and thus are not binary-safe. - 3["hello"] is legal C. — ⁂ — Of these five drawbacks, the fifth seems like it may not be as severe as the other four?
- kevincox 6y agoHow does this work in C++ with operator overloading. Are they still the same? That would make for some interesting obfuscated code.
- jcelerier 6y ago> How does this work in C++ with operator overloading. you can't overload int::operator[](...)
- Koshkin 6y agoI guess the question was whether the subscript operator is always assumed commutative in C++.
- edflsafoiewq 6y agoNo, they're not. It works by: if either a or b in a[b] is a class/enumeration type, call a.operator[](b).