2015-01-21 4 views
3

Я понимаю, что стандарт C запрещает использование массивов в качестве (изменяемая) lvalues, то есть на левой стороне присваивания:Почему массивы не lvalues?

int lhs[4], rhs[4] = {0, 1, 2, 3}; 
lhs = rhs; /* illegal! */ 

Теперь, я задавался вопрос, почему это так , Я мог видеть заявление выше (и любое другое задание, которое записывает в массив) определяется эквивалентный

memcpy((void *) lhs, (void *) rhs, sizeof(lhs)); 

и налагая бремя обеспечения, что rhs достаточно большой для пользователя, но это не было принято решение в этом должно быть так.

Однако, очень похожий пример делает работы прекрасно:

struct { int a[4]; } lhs, rhs = {{0, 1, 2, 3, 4}}; 
lhs = rhs; 

Просто обертывание массива в структуре, можно получить именно поведение, описанное выше, то есть присвоение lhs = rhs эквивалентно до:

memcpy((void *) &lhs, (void *) &rhs, sizeof(lhs)); 

В чем причина этого (как мне кажется) непоследовательности? Есть ли проблема с разрешающими назначениями массива, которые интерпретируются как memcpy?

+0

Ответ на этот вопрос: http://stackoverflow.com/a/17691191/14955 (Прокрутите вниз до Edit2: The Real Reason) – Thilo

+0

Имя массива * is * lvalue. Я думаю, что вы спрашиваете, почему массивы не назначаются. –

+0

Возможный дубликат: http://stackoverflow.com/q/27881442/827263 –

ответ

2

C должен быть языком низкого уровня, а не скрывать потенциальную память или трудоемкие задачи за простым синтаксисом. Один оператор генерирует одну инструкцию сборки; для более сложных вещей вызовите функцию. В начале C вы также не могли назначать структуры или передавать их между функциями (вы должны передать указатель).

РЕДАКТИРОВАТЬ:

на структуру одно значение. Его размер статичен и известен во время компиляции. Массив - это несколько значений, и большинство массивов динамически распределяются/перераспределяются. Их размер неизвестен во время компиляции, поэтому компилятор не будет знать, сколько памяти выделять и копировать.

int *a, *b; 
a = malloc(/* value based on e.g. user input */); 
b = a; /* compile this into what? */ 

Для того, чтобы работать, C будет иметь внутренне хранить размер на массив вместе с указателем или вместе с данными указал. Это решение было оставлено программисту.

+0

Что вы подразумеваете под "early C"? Каждый стандарт C * *, который я знаю, позволяет назначать структуры, поэтому ваш аргумент не работает ни на каком языке, который можно разумно назвать C. Кроме того, если назначение структуры действительно было добавлено на язык позже, почему не было задание массива включено также? – yyyyyyy

+0

О вашем редактировании: это * не * пример того, о чем я говорю - ваш код даже не содержит * массив, плюс он компилируется просто отлично (присваивая значение * указателю * 'a' для * указатель * 'b')! – yyyyyyy