5 ms·
The meat of the proposal: "a pair consisting of a pointer to the start of the array, and a size_t of the array dimension" No, that still doesn't fix the ABI.
by knaq 6y ago
The meat of the proposal:
"a pair consisting of a pointer to the start of the array, and a size_t of the array dimension"
No, that still doesn't fix the ABI. It's syntactic sugar. It is most definitely not passing an array.
Passing an array means exactly that, no more and no less. For example, suppose this is your array:
double foo[100][100];
The size is 80000 bytes. That is exactly how much data needs to be copied onto the stack, no more and no less.
Getting the array dimensions is secondary. It would be nice to have them work. They could automatically get names. They could get size checks, so a function might declare itself compatible with a certain range of sizes. That's all a bonus, of much lower importance than the actual ability to pass an array.
The inability to pass an array impacts numerous other languages because they use the C ABI. If you can't put those 80000 bytes on the stack in C, then you can't do it in any language. The whole software ecosystem is thus impoverished.
- brundolf 6y agoAre you non-jokingly suggesting copying the entire array to and from the stack each time, as an alternative to the OP's proposal (and as a default best-practice)?
- knaq 6y agoYes. If you don't really want to pass an array then don't do that. The language shouldn't get in the way when somebody wants to pass an array. Take the address, and pass a pointer, if that is what you want to do. Maybe I want the callee to be able to modify the array without affecting the caller. Maybe I'm even telling the linker to put that array in ROM, but I want a writable copy in the callee. Whatever... I have my reasons. The language shouldn't block me.
- brundolf 6y agoI don't think you realize how intractably inefficient that would be for all but the smallest cases.
- knaq 6y agoI realize exactly how inefficient it would be. If it hurts, don't do that. I'm the kind of person who optimizes with assembly, counts cache misses, counts TLB misses, and pays attention to pipeline stalls. I definitely understand the performance implications, and I definitely wouldn't be passing arrays around all the time. That said, I want the ability. I want the language to let me do what I want, and on rare occasions I want to pass an array. Let me pass an array.
- brundolf 6y agoOk, but you didn't just say this should be possible, you said it should be the default best-practice. Even if it were useful in a handful of cases, this would be a terrible default way of doing things.
- knaq 6y agoI didn't say it should be the default, but yes it should be. It is for structs. We can have giant structs. I've seen some over a megabyte in size. The default is that the callee gets a copy. (depending on the ABI it could be in the "wrong" stack frame, but it is a distinct copy) Are we having huge problems with structs being passed by value? I don't think so. Normal people pass pointers, except when they actually want to pass by value. It works fine. I have frequently seen beginners struggle with C arrays and pointers. Part of the trouble is that you can't pass an array. You can try, but the compiler quietly substitutes different code. It's a source of confusion, generating incorrect mental models of what is going on.
- brundolf 6y agoBeginners don't struggle in Java, JavaScript, Python, C#, Ruby, and the dozen (at least) other languages that exclusively pass arrays by reference. But all of this is way off-topic from the OP: the original point was, "Passing a pointer and length separately is error-prone; there should be a way to easily package the two together and this should be the default pattern for 90% of cases." Then you came in and said "No, instead C should support this totally orthogonal side-case that's a bad idea 90% of the time but has some niche uses." It's not a bad suggestion in itself, necessarily, but it's totally unrelated to the original proposal, much less an alternative to it.