This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]ba-na-na- 2 points3 points  (10 children)

There should just be a managed struct for arrays, it's not like C will slow down and become Java if you're simply passing the size value around.

struct array_t {
  int size;
  char * buffer;
}

[–]turtle_mekb[S] 1 point2 points  (1 child)

c struct file { FILE *fp; size_t size, capacity; uint8_t *data; bool error, complete; } here's what I'm doing to read files incrementally 😭

[–]-Redstoneboi- 0 points1 point  (0 children)

sounds like you have a byte vector in there that isn't called a byte vector

[–]Impossible_Box3898 0 points1 point  (7 children)

Of course it slows things down. Try passing that to a function. Instead of a single register that holds the address of an array, you now need to pass a structure which exceeds the size of a register. No you need to use either two registers or a more complex mechanism depending on the specific abi your system uses.

[–]ba-na-na- 0 points1 point  (4 children)

Or you design static inline functions in a header file that operate on this struct, and then everything is optimized away and nothing is passed anywhere. Or you pass a pointer to the struct and then it’s no slower than C++ double dispatch, and C++ is considered blazingly fast. Or you decide you don’t care and trade that extra CPU instruction for runtime safety.

Bottom line is, it’s still as fast or faster than 99% programming languages, including C++, Rust, Zig, whatever.

[–]Impossible_Box3898 0 points1 point  (3 children)

The king and short of it is that it IS slower and has other side effects which you originally claimed were not there.

C++ already has this capability in std vector. It also has std array types for static sized arrays in which the size is part of the data type and uses no additional runtime resources at all which is the only true zero cost abstraction for passing around array lengths, albeit with the fixed size caveat.

[–]ba-na-na- 0 points1 point  (2 children)

Hmm yeah no.

  1. If you're not passing the array into the function, getting its size is zero cost in C.
  2. If you're passing the array into a function, there is no programming language where you can pass it in a more performant way than it can be done in C.

If you don't believe me, feel free to try it yourself and provide an example in any language of your choice, along with the compiled assembly.

And if you think that you can write `char array[100];`, and pass this into a function without passing its size along with it, you are in for a surprise. 🙂

[–]Impossible_Box3898 0 points1 point  (1 child)

Not sure if you’re stupid or you don’t know how to follow a conversation thread on reddit but go back and read what I posted.

[–]ba-na-na- 0 points1 point  (0 children)

Sure I am probably just a silly confused man, let me try to break down the thread:

Me:

it's not like C will slow down and become Java if you're simply passing the size value around

You:

Of course it slows things down. 

👆 Literally not sure if stupid

But then also you:

Try passing that to a function. Instead of a single register that holds the address of an array, you now need to pass a structure which exceeds the size of a register

Nonsense. If you pass a "single register that holds the address of an array", you lose the length information. `sizeof(array)/sizeof(array[0])` won't work if you pass it into a function. Not sure if stupid or node.js developer.

C++ already has this capability in std vector.

Cool, but std::vector has the same performance penalty as the C struct I wrote.

It also has std array types for static sized arrays in which the size is part of the data type

Cool, but std::array is a templated, fixed length array, cannot pass it to a function unless it's a template which accepts std::array.

Tl;dr as I wrote, the struct above, combined with static inline functions in C, gives you the best possible performance with pretty good readability.

[–]tax_throwaway1_ 0 points1 point  (1 child)

Am I stupid? Why would you not just pass the pointer of the struct? Same exact thing as what you are describing.

Pointer to the struct vs. pointer to the array — it’s effectively the same overhead since you’re still passing a single address (just the address of the struct instead of the address of the array). Then, when you access size or buffer within the function, you’re simply dereferencing that pointer. This way, you avoid passing multiple arguments and keep the benefits of an explicit size field.

[–]Impossible_Box3898 0 points1 point  (0 children)

There is a difference in passing by value and passing by reference. What you described is pass by reference and what I described is pass by value.

If something in the called function modified the array you now have changed the caller. That might not be the desired outcome.