Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the rationale for preventing assignment to arrays?

I've tried to google this and have read:

  • Why can't arrays of same type and size be assigned?
  • Assigning arrays
  • Assign to array in struct in c

But they all state the obvious: you can't assign to arrays because the standard says so. That's great and all, but I want to know why the standard doesn't include support for assigning to arrays. The standard committee discusses things in detail, and I'd be surprised if they never discussed making arrays assignable. Assuming they've discussed it, they must have some rationale for not letting arrays be assigned to.

I mean, we can put an array in a struct and assign to the struct just fine:

struct wrapper {     int array[2]; };  struct wrapper a = {{1, 2}}; struct wrapper b = {{3, 4}}; a = b; // legal 

But using an array directly is prohibited, even though it accomplishes effectively the same thing:

int a[2] = {1, 2}; int b[2] = {3, 4}; a = b; // Not legal 

What is the standard committee's rationale for prohibiting assigning to arrays?

like image 221
Cornstalks Avatar asked Jan 10 '15 21:01

Cornstalks


People also ask

What is assignment array?

An array assignment occurs either when you assign one array to another using an assignment (=) statement or when you pass an array as a routine parameter. In general, the rules for array assignment are different for assignment between ABL arrays compared to assignment between .

Why do we use arrays in programming?

In coding and programming, an array is a collection of items, or data, stored in contiguous memory locations, also known as database systems . The purpose of an array is to store multiple pieces of data of the same type together.

Can you assign an array to an array in C?

You cannot assign an array (here b ) by a pointer to the first element of another array (here a ) by using b = a; in C. The syntax doesn't allow that.


2 Answers

In C, assignment copies the contents of a fixed-size object to another fixed-size object. This is well defined and fairly straightforward to implement for scalar types (integers, floating-point, pointers, complex types since C99). Assignment of structs is nearly as simple; larger ones might require a call to memcpy() or equivalent, but it's still straightforward since the size and alignment are known at compile time.

Arrays are a different matter. Most array objects have sizes that aren't determined until run time. A good example is argv. The runtime environment constructs an array of char for each command-line argument, and an array of char* containing pointers to the arguments. These are made available to main via argv, a char**, and via the dynamically allocated char[] arrays that the elements of argv point to.

C arrays are objects in their own right, but they're not generally accessed as objects. Instead, their elements are accessed via pointers, and code traverses from one element to the next using pointer arithmetic.

Languages can be designed to treat arrays as first-class objects, with assignment -- but it's complicated. As a language designer, you have to decide whether an array of 10 integers and an array of 20 integers are the same type. If they are, you have to decide what happens when you try to assign one to the other. Does it copy the smaller size? Does it cause a runtime exception? Do you have to add a slice operation so you can operate on subsets of arrays?

If int[10] and int[20] are distinct types with no implicit conversion, then array operations are inflexible (see Pascal, for example).

All these things can be defined (see Ada), but only by defining higher-level constructs than what's typical in C. Instead, the designers of C (mostly Dennis Ritchie) chose to provide arrays with low-level operations. It's admittedly inconvenient at times, but it's a framework that can be used to implement all the higher-level array operations of any other language.

like image 64
Keith Thompson Avatar answered Sep 19 '22 12:09

Keith Thompson


The reason is basically historic. There was a C even before ISO C89 which was called "K&R" C, after Kernighan and Ritchie. The language was designed to be small enough so a compiler would fit in severely limited (by today's standards) memory of 64kb.

This language did not allow assigning arrays. If you wanted to copy same-sized arrays, memcpy was there for your needs. Writing memcpy(a, b, sizeof a) instead of a = b is certainly not a big complication. It has the additional advantage of being generalizable to different-sized arrays and array slices.

Interestingly, the struct assignment workaround you mention also did not work in K&R C. You had to either assign members one by one or, again, use memcpy. The first edition of K&R's The C Programming language mentions struct assignment as a feature for future implementation in the language. Which eventually happened with C89.

like image 21
Jens Avatar answered Sep 22 '22 12:09

Jens