2015-07-14 6 views
3

Рассмотрим следующее объявление массива:Что действительно означает `int const a [5]`?

int const a[5]; 

С семантической точки зрения языка, это точно эквивалентно const int a[5]? Предполагая, что это так, обе декларации будут по существу считаться «a - это массив из 5 постоянных ints».

Альтернативный способ чтения первого объявления будет «a является постоянным массивом из 5 целых чисел».

Очевидно, что оба утверждения логически означают, что весь массив является постоянным; если массив состоит из 5 постоянных ints, тогда весь массив является постоянным. Альтернативно, если весь массив является постоянным, то все его значения также являются постоянными.

Я знаю, что понятие «постоянный массив» немного бессмысленно, так как массивы не изменяются lvalues ​​(то есть они не могут появляться с левой стороны задания). Однако существуют ли какие-либо обстоятельства, при которых эти два заявления могут привести к другому поведению?

(Cdecl.org отклоняет первое заявление в качестве синтаксической ошибки, в то время как большинство современных компиляторов принимают его.)

EDIT:

Связанный дубликат спрашивает, может ли порядок const вопросов для обычных переменных. С массивами это немного более запутанно, поэтому я не считаю это дубликат.

+0

'const 'относится к типу слева, если только он не является первым в объявлении , и в этом случае оно применяется к праву. Таким образом, оба эквивалентны. – bolov

+1

Возможно, дубликат http://stackoverflow.com/questions/7633776/constant-array-of-constant-objects? Несмотря ни на что, это ничего не значит. Здесь '5' уже является константой. При использовании 'const int a [5];' он даст вам постоянный массив в 'C++'. Обратите внимание, что это не работает (правильно) в 'C'! Так что для C это в значительной степени игнорируется. – Wolph

+2

Они такие же. http://stackoverflow.com/questions/162480/const-int-vs-int-const-as-function-parameter-in-c-and-c – rlbond

ответ

12

это точно эквивалентно const int a[5]

Да, это так.

Альтернативным способом чтения первого объявления будет «a - это постоянный массив из 5 целых чисел».

Не совсем. Ваше объявление, как написано, применяет const к элементам массива. Для того, чтобы применить const в самом массиве (в отличие от его применения к элементам массива), то вы должны сделать что-то вроде

int (const a)[5]; 

но такое заявление синтаксически неверен в C.

Косвенной попытки применить const к самому массиву можно сделать через промежуточный ЬурейеГо

typedef int A[5]; 
const A a; 

, но в этом случае, согласно правилам языка, const классификатора «проваливается» к элементам массива и в целом вещь просто эквивалентно

const int a[5]; 

Note, опять же, что const A a; выше не сразу эквивалентно const int a[5];. Это фактически эквивалентно вышеупомянутому int (const a)[5]; (!). (Это законный способ прогнать int (const a)[5]; за защитой компилятора.) Но этот int (const a)[5]; очень короткий - он сразу же превращается в const int a[5]; компилятором.

Если массив состоит из 5 постоянных целых чисел, то весь массив является постоянным. Альтернативно, если весь массив является постоянным, то все его значения также являются постоянными.

Ну, это не совсем так. Язык C различает объект массива и его элементы. Концептуально это разные сущности. Например, как вы отметили сами, спецификация языка говорит, что массивы немодифицируемые lvalues ​​. Это, конечно, не препятствует модификации элементов массива.

Это концептуальное различие между массивом в целом и отдельных массивов элементов, в сочетании с «проваливаются» поведения для const именно то, что приводит к следующей неприятной ситуации

typedef int A[5]; 
A a; 
const A *p = &a; // ERROR!!! 

т.е. нарушает «нормальный» const-correctness, которое позволяет нам инициализировать указатели const T * с значениями T *. (C++ намеренно обновлял правила константной корректности, чтобы заставить вышеприведенный код вести себя «как ожидалось», но C настаивает на его отклонении.)

1

Я положил это вместе:

#include <stdio.h> 

int main() 
{ 
    int const a[5]; 
    const int b[5]; 
    int c[5]; 

    a[0] = 1; 
    b[0] = 2; 
    c = a; 
    c = b; 
} 

И НКУ (4.1.2) выплюнуть это:

gcc -o /tmp/x2 /tmp/x2.c 
/tmp/x2.c: In function ‘main’: 
/tmp/x2.c:9: error: assignment of read-only location 
/tmp/x2.c:10: error: assignment of read-only location 
/tmp/x2.c:11: error: incompatible types in assignment 
/tmp/x2.c:12: error: incompatible types in assignment 

Так, по крайней мере на этом основании там не наблюдается никаких различий.

+0

Я сделал тот же эксперимент, прежде чем задавать вопрос, но он все еще не исключает каких-либо потенциальных различий между ними. –

 Смежные вопросы

  • Нет связанных вопросов^_^