2014-05-26 3 views
7

Как я узнал, можно написать следующий код:- это int [указатель на массив] в стандарте C++?

char *a = new char[50]; 
for (int i = 0; i < 50; ++i) { 
    i[a] = '5'; 
} 

Он компилирует. Оно работает. Это делает точно же, как

char *a = new char[50]; 
for (int i = 0; i < 50; ++i) { 
    a[i] = '5'; 
} 

Является ли это просто потому, что:

  • a[b] реализуется как макро *(a + b) по умолчанию, и тот факт, что оба образца кода действительны только случайно/составитель специфический
  • он стандартизирован где-то, и результаты таких алгоритмов должны быть одинаковыми на с каждой платформа

Разумно предположить, что добавление должно быть коммутативным, но если мы реализуем operator[] таким образом, мы сделали что-то еще коммутативное, чего бы мы не хотели.

Интересным фактом является то, что нет оператора pointer[pointer], поэтому operator[] не является макросом.

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

+17

Это не ** макрос, это правило языка. – stefan

+0

Я удалил тег C, так как это кажется скорее C++-сфокусированным. – unwind

+0

_'Но я хочу знать, если это просто несчастный случай, и он не будет работать в далекой стране, где у единорогов есть семь ног, а рожки - на их левой щеке. '' Вряд ли, потому что стандарт определяет это поведение неявно. –

ответ

10

C++ standard, § 8.3.4, note 7 (page 185) (emphasis mine).

исключения случаев, когда она была объявлена ​​для класса (13.5.5), оператор подстрочного [] интерпретируется в таком способ, которым E1[E2] идентичен *((E1)+(E2)). Из-за правил преобразования, которые применяются к +, если E1 является массивом и E2 целым числом, то E1[E2] относится к E2 -м члену E1. Следовательно, , несмотря на его асимметричный внешний вид, subscriptipit является коммутативной операцией.

1

Выражение E1 [E2] идентично (по определению) до * ((E1) + (E2))

... а затем коммутативности индекса и указатель приимет. Обратитесь к дружественным окрестностям C++ стандарта, раздел 5.2.1 в этой версии: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf

4

Вот что C++ 11 стандарта должен сказать:

Примечания: За исключением случаев, она была объявлена ​​для класса (13.5.5), оператора подстрочного [] интерпретируется в таком Способ, которым E1[E2] идентичен *((E1)+(E2)). Из-за правил преобразования, которые применяются к +, если E1 является массивом и E2 целым числом, то E1[E2] относится к E2 -м члену E1.Поэтому, несмотря на его асимметричный внешний вид, подписка является коммутативной операцией. (добавлен акцент).

Так что ваше предположение, что a[b] реализуется как *(a + b) правильно, за исключением того, что она осуществляется непосредственно в компиляторе, а не как макрос.