7 ms·
TIL the C variable declaration syntax is meant to evoke how you would use the variable. For instance, int *x[3] means that to get an int, I type *x[3]
by jlebar 7y ago
TIL the C variable declaration syntax is meant to evoke how you would use the variable. For instance,
int *x[3]
means that to get an int, I type
*x[3]
(well ok, 3 would be a poor choice). Whereas if I have
int (*x)[3]
I'd dereference it as
(*x)[0]
meaning, it's a pointer to array of ints, while the first is an array of int pointers.
This is mildly life-changing.
- ensiferum 7y agoYou got an off by one bug in your first example ;-)
- jlebar 7y agoYou mean "(well ok, 3 would be a poor choice)"?
- wruza 7y agoIf we used languages with 1-based arrays, then the first element was 1, the last was n, and find(x) could return 0 as an “item not found” marker instead of returning -1 or worse uint_max. Reasoning about counting from the end could be off-by-one easier: n+1-i instead of n-i-1, n-1-i or n-(i+1), whichever nonsense you like better. Looping: i=1, i<=n. Setting next: a[n+1]=x, where the capacity allows. But when you mention one of these languages, you get a bunch of “oh, 1-based arrays, so uncool, not an option”.
- cyphar 7y agoThe downside of 1-based indexing is that pointer arithmetic stops being consistent with array indexing. Both approaches have downsides.
- wruza 7y agoAnd one may see that as a nice way of ditching pointer calculus completely to the machine level where it belongs.
- jstimpfle 7y agofact is, array indexing is pointer arithmetic. And how do you for example index an array of 256 elements with one byte, with 1-based indexing?
- wruza 7y ago257, 300, 100k elements? You do not index it with one byte, that simple. If that is a hard requirement (8-bit chip, low ram, etc), leave it to C or a special syntax. __ptr_offset(p, n), p+n, p: array[0..n] of x, option base 0, you name it. I mean, we can ask ourselves tens of such in-the-box questions for any feature that doesn’t fit it, but out-of-box world doesn’t really crave all of that by default.
- jstimpfle 7y agoNo, I'm trying to show is that offset-indexing is the right way to do it: because it makes sense, mathematically. If you need more and better arguments, have a look at Dijkstra's "Why numbering should start at zero" (it also argues why we should have left-inclusive and right-exclusive bounds).
- wruza 7y ago>...unnatural by the time the sequence has shrunk to the empty one. That is ugly, ... I reread his article for clarity. He first makes the “ugly” argument, which originates from 1) natural number domain definition issues, and 2) only then he goes to the range definition argument based on 1). It may be valid when you’re working in your mind on math problems of natural numbers starting* with 0, which is a self-referential argument btw. But it doesn’t have to be applied to software arrays of items. Dijkstra’s argument is repeated as a mantra, but the general consensus is that representation of natural numbers (unsigned ints) brings more issues than ought to solve, so we don’t use them today, which defeats 1), and then 2) loses its causality. >>find(x) could return 0 as an “item not found” marker instead of returning -1 or worse uint_max Let’s test that against Dijkstra’s statement on range unnaturalness? Which is more unnatural, 0, -1, NSNotFound? Programmatically it doesn’t make any sense except in salary gains from mastering off-by-ones. * Edit: natural numbers start differently in different countries, but you may s/0/1/ there and it still holds, because he speaks about domain borderlines. The same holds true for e.g. [321..500].
- jstimpfle 7y agoI think we should compromise on 0.5.
- dooglius 7y agoLooking at it this way also makes it easier to remember/understand function pointer syntax, as well as attributes like const and volatile when placed between asterisks.
- alfiedotwtf 7y agoYou want something even more life-changing? There's the Spiral Rule: http://c-faq.com/decl/spiral.anderson.html http://c-faq.com/decl/spiral.anderson.html
- rcxdude 7y agoI think the 'declaration follows use' insight is far more useful than the 'spiral rule', which manages to get the same result but completely obscures the intuition.
- jstimpfle 7y agoYup. "Declaration follows use" was Ritchie's idea of making it work[0] (I think it was his own). Unfortunately, while it is often useful, it also has its problems. Lacking a keyword, a type table is needed in the parser to recognize declarations. Thus, need to parse everything from the start. The syntax is very concise and easy to read in simple to moderate cases, but difficult to read for more complicated declarations, like functions returning function pointers. And few people know how it works and get confused. I wonder why that knowledge is not a lot more common. [0] https://www.bell-labs.com/usr/dmr/www/chist.html https://www.bell-labs.com/usr/dmr/www/chist.html