Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> why did it become idiomatic to pass pointers and lengths separately in C?

I've read that it's because there used to be binary interface issues with structures. They can be returned from functions and passed as parameters but it isn't immediately clear how that happens: is it on the stack, in one register or in several registers? Even today there are compiler options that affect the generated code in those cases:

  -fpcc-struct-return

  Return “short” struct and union values in memory like
  longer ones, rather than in registers.

  -freg-struct-return

  Return struct and union values in registers when possible.
https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#ind...

https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#ind...

https://gcc.gnu.org/onlinedocs/gcc/Incompatibilities.html#in...



>They can be returned from functions and passed as parameters but it isn't immediately clear how that happens: is it on the stack, in one register or in several registers?

Why does it have to be clear? It can be unspecified and the compiler will do what it thinks is best given the struct, e.g. return `struct {int x,y};` in registers, return `struct int[80] x}` as pointer to memory or write in-place to the caller's stack, via RVO.


> Why does it have to be clear?

Because it's part of the binary interface. Changing the binary interface prevents existing programs from interoperating. Everything breaks until the software is recompiled and that can be a major nuisance at best and impossible in the worst case.

Simple, well-defined and stable binary interfaces are a major reason why C is still widely used. Uncertainty in this area is never a good thing so people will actively avoid language features that introduce it. Looks like enums aren't favored for similar reasons: what is the underlying type?


Because then code compiled separately can’t interoperate.


It doesn't have to be a return value though. You could pass pointers to it as parameters.

To answer the question though, a number of people do define structures containing a buffer and a length (and potentially capacity), there just isn't such a structure standardized so everybody who wants to do this has to bring their own.

Some examples from Unix: iovec, sendmsg/recvmsg. Surely there are others I'm just not thinking of right now.

In the Windows world you have UNICODE_STRING and similar structures. SChannel has "PSecBufferDesc". Again, surely there are others.

And prominent libraries might also have their own.


Passing struct arguments by value is also complicated in some ABIs. The most reliable way is to pass a pointer to struct, but with slices that means double indirection.

I don't think ABI is a concern these days, though, even if things were different 30 years ago. The specs that we have today do cover how to pass and return structs in the standard manner.


Originally C didn't have the ability to pass or return structures. That was added in the V7 period, after some habits were well established.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: