News for hackers. Stuff that matters.
Re:Everything I wish I knew when learning C by retrac on Monday November 28, 2022 @12:31PM (#33776518)
> it's largely just an arbitrary restriction

Kind of. But the restriction is in keeping with the C philosophy of no hidden implementation magic. C has the same restriction on structs. That's the same question; an array of bytes of known size to the compiler it could easily abstract away. But assignment is always a very cheap operation in C. If we allow assigning to represent memcpy() that property is no longer true.

Same reason why Rust requires you to .clone() so much. It could do many of the explicit copies transparently, but you might accidentally pass around a 4 terabyte array by value and not notice.

Re:Everything I wish I knew when learning C by mytherin on Monday November 28, 2022 @12:54PM (#33776898)
Perhaps I am missing something in the spec - but trying this in various compilers, it seems that you *can* assign structs holding arrays to one another, but you *cannot* assign arrays themselves.

This compiles:

  struct BigStruct {
    int my_array[4];
  };
  int main() {
    struct BigStruct a;
    struct BigStruct b;
    b = a;
  }
But this does not:

  int main() {
    int a[4];
    int b[4];
    b = a;
  }
That seems like an arbitrary restriction to me.
Re:Everything I wish I knew when learning C by poepie on Monday November 28, 2022 @01:29PM (#33777468)
In the first example a & b are variables, which can be assigned to each other. In the second a & b are pointers, but b is fixed, so you can not assign a value to it.
Re:Everything I wish I knew when learning C by yakubin on Monday November 28, 2022 @07:40PM (#33782085)
They’re not pointers. sizeof a == 4*sizeof(int), not sizeof(int*).
Re:Everything I wish I knew when learning C by chipsa on Tuesday November 29, 2022 @09:48AM (#33788237)
They're pointers, just weird ones. The compiler knows it's an array, so it gives the result of the actual amount of space it takes up. If you passed it into a function, and used the sizeof operator in the function, it'd give `sizeof(int *)`. Because sizeof is a compile-time operation, so the compiler still knows that info for your example.
Re:Everything I wish I knew when learning C by yakubin on Tuesday November 29, 2022 @11:17AM (#33789455)
That jest means it decays into a pointer after being passed as a function argument. In the example given however it’s not a pointer. Just like it wouldn’t be inside a struct.
Re:Everything I wish I knew when learning C by fsociety on Monday November 28, 2022 @05:43PM (#33780954)
Essentially ‘b = a’ in the second example is equivalent to ‘b = &a[0]’ or assigning an array to a pointer.

This is because if you use an array in an expression, it’s value is (most of the time) a pointer to the array’s first element. But the left element is not an expression, therefore it is referring to b the array.

Example one works because no arrays are referred to in the expression side, so this shorthand so to speak is avoided.

Arrays can be a painful edge in C, for example variable length arrays are hair pulling.

Re:Everything I wish I knew when learning C by int_19h on Friday December 02, 2022 @02:17PM (#33835365)
The left side of assignment in C is an expression. it's just not in a context where array-to-pointer decay is triggered.
Re:Everything I wish I knew when learning C by brundolf on Monday November 28, 2022 @12:59PM (#33776979)
Ironically, Rust does allow you to implicitly copy an array (or arbitrary struct), as long as it reduces to a memcpy
Re:Everything I wish I knew when learning C by tialaramex on Monday November 28, 2022 @06:33PM (#33781440)
Specifically arrays [T; N] are Copy if precisely T is Copy. So, an array of 32-bit unsigned integers [u32; N] can be copied, and so can an array of immutable string references like ["Hacker", "News", "Web", "Site"] but an array of mutable Strings cannot.

The array of mutable Strings can be memcpy'd and there are situations where that's actually what Rust will do, but because Strings aren't Copy, Rust won't let you keep both - if it did this would introduce mutable aliasing and so ruin the language's safety promise.

Re:Everything I wish I knew when learning C by DSMan195276 on Monday November 28, 2022 @02:39PM (#33778485)
> But assignment is always a very cheap operation in C.

That's just not true though, you can assign struct's of an arbitrarily large size to each-other and compilers will emit the equivalent of `memcpy()` to do the assignment. The might actually call `memcpy()` automatically depending on the particular compiler.

The fact that if you wrap the array in a struct then you're free to copy it via assignment makes it arbitrary IMO.