5 ms·
Contrast the first example with Golang: str [10]*byte which reads exactly as it is declared: "str is an array of length 10 of pointers to byte" (byte is Go
by gtrubetskoy 10y ago
Contrast the first example with Golang:
str [10]*byte
which reads exactly as it is declared: "str is an array of length 10 of pointers to byte" (byte is Go equivalent of C char (mostly)).
- userbinator 10y agoI am not familiar with Go, and have heard many praises of its declaration syntax, but is its dereference operator postfix? That would make sense in such a case. On the other hand, IMHO the whole "make declarations read left-to-right" idea is misguided --- plenty of other constructs exist in programming languages which simply can't be read left-to-right, but are nested according to precedence. I mean, you might as well make 3+4*3 evaluate to 21 if you want to try making everything consistently left-to-right, but I don't really see anyone complaining about not being able to understand operator precedence...
- dsymonds 10y agoGo's defererence operator `*` is prefix, like in C. The point here is that type declarations are regular to read, and those tend to be the tricky ones. Expressions tend not to be so difficult, and are more commonly factored if they become complex. For various reason, type declarations are not so practically factorable.
- vorg 10y agoWhen I came to Go, I hadn't used C or C++ for over a decade, only Java and C# in between. Using explicitly written pointers came flooding back, but the new "C for expressions, Pascal for declarations" syntax still takes getting used to. Declaring `v * T` means we can write `* v` as an expression, so the use of token * is synchronized for both these uses, but I must vocalize the * in my head differently: `*T` vocalizes as "pointer to something of type T" `*v` vocalizes as "that pointed to by variable v" `&v` vocalizes as "pointer to variable v" So my thought process when I see * goes: If it's in a type, say "pointer to", otherwise say the opposite of "pointer to", i.e. "that pointed to by". It feels like an inconsistent use of * whenever I'm writing Go code -- even though I know it's a natural result of Go using Pascal-style declaration syntax but C-style tokens.
- kccqzy 10y agoIt can also be simpler if you use idiomatic modern C++ with std::array<T, n> and std::function<R(T1, T2)>.
- Jach 10y agoOr Nim: var str: array[10, ptr byte] (and much richer types) Edit: and while I'm here, Nim has other sensible syntax for this low level stuff... var b: byte = 10 str[0] = addr b echo $str[0][]
- userbinator 10y agoLooking at "idiomatic modern C++", I am often at a loss for words at what lengths they've gone to in order to reinvent things while greatly obfuscating them in the process. Is there a std::pointer_to<T> too? I don't know, but something like this std::array<std::pointer_to<byte>, 10> str; certainly does not look any more readable to me than byte *str[10]; . (Disclaimer: I mainly work with C, but find some C++ features genuinely useful, although the majority of the time they seem more like absurd complexity for the sake of complexity.)
- detrino 10y agostd::array does not exist because it is easier to read. It exists because C arrays behave strangely. Two examples: decay to pointer and no value semantics.
- physguy1123 10y agoI've never seen nor heard of pointer_to ever being used to declare a pointer to something. I believe t's used inside of custom allocators for a generic type that might not use a normal pointer as the pointer type, but would never be used for normal declarations like this. std::array is useful for letting the compiler avoid array-to-pointer decaying, value semantics, and also actually putting array length type info in a function parameter.
- iopq 10y agoOr Rust: let string: [&u8; 10]; string is an array of references to unsigned integers of 8 bits of length ten
- Ericson2314 10y agoActually it's a semicolon.
- iopq 10y agoWhoops, fixed
- Peaker 10y agoBut then you lose C's nice property that declaration and use are the same syntax. For example, D also uses a similar type syntax, so in D if you declare: int[10][20] x; x[19][9] // is legal In C: int x[10][20]; x[9][19] // is legal I think the correct solution would have been to make pointer syntax post-fix like the arrays and functions, so that you get the best of both worlds. Go-like declarations and C-like matchup between use and declarations.