Це законно:
int array[5];
int *array_begin = &array[0];
int *array_end = &array[5];
Розділ 5.2.1 Передплата Вираз E1 [E2] ідентичний (за визначенням) fi ((E1) + (E2))
Отже, цим можна сказати, що array_end теж еквівалентний:
int *array_end = &(*((array) + 5));
Розділ 5.3.1.1 Одинарний оператор '*': Одинарний * оператор виконує опосередкування: вираз, до якого він застосовується, повинен бути покажчиком на тип об'єкта або покажчиком на тип функції, а результат - значення l, що відноситься до об'єкта або функція, на яку вказує вираз. Якщо тип виразу "вказівник на Т", то результат результату - "Т." [Примітка: вказівник на неповний тип (відмінний від cv void) може бути розменований. Отримане таким чином значення lvalue можна використовувати обмежено (наприклад, для ініціалізації посилання); це значення l не слід перетворювати на значення r, див. 4.1. - кінцева примітка]
Важлива частина вищезазначеного:
'результат - значення lvalue, що посилається на об'єкт або функцію'.
Одинарний оператор '*' повертає значення lvalue, яке посилається на int (без дефеференції). Потім одинарний оператор '&' отримує адресу значення.
Доки не буде знято посилання на вказівник поза межами, тоді операція повністю охоплюється стандартом і визначається вся поведінка. Отож, прочитавши вище, цілком законно.
Той факт, що багато алгоритмів STL залежать від чітко визначеної поведінки, є свого роду натяком на те, що комітет стандартів вже це зробив, і я впевнений, що є щось, що явно це охоплює.
У розділі коментарів нижче подано два аргументи:
(будь ласка, прочитайте: але це довго, і ми в кінцевому підсумку троллі)
Аргумент 1
це є незаконним через пункт 5 розділу 5.7
Коли вираз, який має інтегральний тип, додається або віднімається від покажчика, результат має тип операнда покажчика. Якщо операнд вказівника вказує на елемент об'єкта масиву, а масив досить великий, результат вказує на зміщення елемента від вихідного елемента таким чином, що різниця індексів результуючого та вихідного елементів масиву дорівнює інтегральному вираженню. Іншими словами, якщо вираз P вказує на i-й елемент об'єкта масиву, вирази (P) + N (еквівалентно N + (P)) та (P) -N (де N має значення n) вказують відповідно до i + n-го та i - n-го елементів об'єкта масиву за умови їх існування. Більше того, якщо вираз P вказує на останній елемент об'єкта масиву, вираз (P) +1 вказує один минулий останній елемент об'єкта масиву, і якщо вираз Q вказує один за останнім елементом об'єкта масиву, вираз (Q) -1 вказує на останній елемент об'єкта масиву. Якщо і операнд покажчика, і результат вказують на елементи одного і того ж об'єкта масиву або одного з останніх елементів об'єкта масиву, обчислення не повинно викликати переповнення; в іншому випадку поведінка не визначена.
І хоча розділ є актуальним; він не демонструє невизначеної поведінки. Всі елементи масиву, про які ми говоримо, знаходяться або в масиві, або поза кінцем (що добре визначено в наведеному вище абзаці).
Аргумент 2:
Другий аргумент, представлений нижче, - *
це оператор де-посилання.
І хоча це загальний термін, який використовується для опису оператора '*'; цього терміну навмисно уникають у стандарті, оскільки термін "відміна посилання" не є чітко визначеним з точки зору мови та того, що це означає для базового обладнання.
Хоча доступ до пам'яті після закінчення масиву, безумовно, невизначений. Я не впевнений у unary * operator
доступі до пам'яті (читання / запис у пам'ять) у цьому контексті (не так, як це визначає стандарт). У цьому контексті (як визначено стандартом (див. 5.3.1.1)) unary * operator
повертається a lvalue referring to the object
. На моє розуміння мови, це не доступ до основної пам'яті. Потім результат цього виразу негайно використовується unary & operator
оператором, який повертає адресу об'єкта, на який посилається lvalue referring to the object
.
Наведено багато інших посилань на Вікіпедію та неканонічні джерела. Все, що я вважаю неактуальним. С ++ визначається стандартом .
Висновок:
Я хочу визнати, що є багато частин стандарту, які я, можливо, не враховував, і може довести свої помилки вище. НЕ наведено нижче. Якщо ви покажете мені стандартне посилання, яке показує, що це UB. я буду
- Залиште відповідь.
- Якщо поставити всі шапки, це дурне, і я помиляюся, щоб усі читали.
Це не аргумент:
Не все у всьому світі визначається стандартом С ++. Відкрий свій розум.