(1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 02:02
Оценка: 4 (1)
SUBJ
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: (1[&array]-&array[0]) -- UB or not UB?
От: Igore Россия  
Дата: 06.02.14 05:57
Оценка:
Здравствуйте, Erop, Вы писали:

E>SUBJ


Не UB,
1[array] == array[1], грубо говоря
1 + *pointer == *pointer + 1
Re[2]: (1[&array]-&array[0]) -- UB or not UB?
От: rg45 СССР  
Дата: 06.02.14 06:03
Оценка: +3
Здравствуйте, Igore, Вы писали:

I>Здравствуйте, Erop, Вы писали:


E>>SUBJ


I>Не UB,

I>1[array] == array[1], грубо говоря
I>1 + *pointer == *pointer + 1

Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: (1[&array]-&array[0]) -- UB or not UB?
От: Igore Россия  
Дата: 06.02.14 06:16
Оценка: -1
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Igore, Вы писали:


I>>Здравствуйте, Erop, Вы писали:


E>>>SUBJ


I>>Не UB,

I>>1[array] == array[1], грубо говоря
I>>1 + *pointer == *pointer + 1

R>Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.


Ну тогда распишу полностью

1[&array]-&array[0] == &array[1] — &array[0] == &array[0] + 1 — &array[0] == 1
Re[4]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 06:22
Оценка: 1 (1)
Здравствуйте, Igore, Вы писали:

I>Ну тогда распишу полностью


I>
1[&array]-&array[0] == &array[1] - &array[0] == &array[0] + 1 - &array[0] == 1


Не, не так
int array[146];
assert( (1[&array] - &array[0]) == 146 );
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 06:26
Оценка:
Здравствуйте, rg45, Вы писали:

R>Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.


Именно так. Формально мы ка кбы разыменовываем указатель на место за массивом, но разыменовываем его только для того, что бы преобразовать к адресу нулевого элемента этого несуществующего массива, то есть, фактически,
(typeof(array[0])*)1[&array]
это получение указателя на конец массива.
Вопрос в том, валидно ли такое недоразыменование?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 06:29
Оценка:
Здравствуйте, Igore, Вы писали:

I>Не UB,

I>
1[array] == array[1], грубо говоря 
I>1 + *pointer == *pointer + 1


Спасибо за разъяснения. Я верно понял, что с твоей т. з. тут всё нормуль:
int f( int i)
{
    return 1[&i];
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: (1[&array]-&array[0]) -- UB or not UB?
От: Igore Россия  
Дата: 06.02.14 06:32
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Igore, Вы писали:


I>>Ну тогда распишу полностью


I>>
1[&array]-&array[0] == &array[1] - &array[0] == &array[0] + 1 - &array[0] == 1


E>Не, не так

E>
E>int array[146];
E>assert( (1[&array] - &array[0]) == 146 );


Да уж, проверил &array[1] != 1[&array], получается
Re[3]: (1[&array]-&array[0]) -- UB or not UB?
От: flаt  
Дата: 06.02.14 06:39
Оценка:
Здравствуйте, rg45, Вы писали:

R>Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.


А почему? Ведь &array == array == &array[0]?
И array[1] == 1[array].

Или для array[size] берётся не sizeof(array[0]), а sizeof(array[size])?
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 06:42
Оценка:
Здравствуйте, Igore, Вы писали:

Пользуйся, пожалуйста, тэгами [c] тут код [/c]

I>Да уж, проверил
&array[1] != 1[&array]
, получается


Тут скобки не так стоят, как ты думаешь.
&array[1] 
/*интерпретируется как */
&(array[1])
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 06:46
Оценка:
Здравствуйте, flаt, Вы писали:

F>А почему?

По грамматике и семантике языка

F>Ведь
&array == array == &array[0]
?


1) первое равенство вообще не имеет места быть,
2) второе просто использует неявное приведение типов, реально тип массива и указателя на нулевой элемент массива отличается, соответственно и результаты операция могут быть разными.

Кстати, печально, что-то, походу, тут только один коллега понял вопрос, но всё равно не знает ответа...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: (1[&array]-&array[0]) -- UB or not UB?
От: jazzer Россия Skype: enerjazzer
Дата: 06.02.14 06:46
Оценка: 10 (1)
Здравствуйте, Erop, Вы писали:

E>Именно так. Формально мы ка кбы разыменовываем указатель на место за массивом, но разыменовываем его только для того, что бы преобразовать к адресу нулевого элемента этого несуществующего массива, то есть, фактически,
(typeof(array[0])*)1[&array]
это получение указателя на конец массива.

E>Вопрос в том, валидно ли такое недоразыменование?

имхо, нет. С указателем на место за массивом никаких проблем нет (это специально оговорено), а вот с его разыменованием — очевидно, есть. То, что он как-то дальше особенным способом используется, рояли не играет. Так что если тебе нужен просто указатель на место за массивом — используй арифметику указателей, с ней никаких проблем. Тем более что тебе доступен размер массива, так как он вшит в его тип (иначе бы твой код не работал вообще).

А зачем вообще это нужно? Какую задачу ты решаешь этим кодом?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: (1[&array]-&array[0]) -- UB or not UB?
От: flаt  
Дата: 06.02.14 06:52
Оценка:
Здравствуйте, Erop, Вы писали:

E>1) первое равенство вообще не имеет места быть,

Почему? Операция взятия адреса от массива ничего не делает же?
Re[5]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 06:52
Оценка:
Здравствуйте, jazzer, Вы писали:

J>А зачем вообще это нужно? Какую задачу ты решаешь этим кодом?


Встретил на ревью, юзали в качестве lengthof.
Написал, что нестандартно, опасно и не константа времени компиляции + UB.
Попросили аргументировать по UB, так как это а-та-та и депримирование вплоть до увольнения...

В целом я тоже считаю, что это UB, так как 1[&array] -- разыменование.
Но, с другой стороны, это же всего лишь ссылка, у которой потом берут адрес? Ссылку на конец массива получать ведь нельзя? Я верно понимаю?
Я как бы посмотрел стандарт, правда старый, но на вский случай решил проконсультроваться у коллег... Вопрос IMHO крайне казуистический всё-таки.

С другой стороны, просто интересно, насколько это UB реализуемо...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 06:56
Оценка:
Здравствуйте, flаt, Вы писали:

F>Почему? Операция взятия адреса от массива ничего не делает же?

Просто попробуй сравнить адреса
 1 + &array
и
1 + array
и подумай делает она что-то или нет...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 07:00
Оценка:
Здравствуйте, flаt, Вы писали:

E>>1) первое равенство вообще не имеет места быть,

F>Почему? Операция взятия адреса от массива ничего не делает же?

А ты про какой язык, кстати? Я имел в виду, что первого равенства нет в С++, там типы не приведутся...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: (1[&array]-&array[0]) -- UB or not UB?
От: Igore Россия  
Дата: 06.02.14 07:24
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Igore, Вы писали:


E>Пользуйся, пожалуйста, тэгами [c] тут код [/c]


I>>Да уж, проверил
&array[1] != 1[&array]
, получается


Получается
int array[10];

int (*tmp1)[10] = &array + 1;
int *tmp2 = &array[0];

cout << ((int*)tmp1 - tmp2);

Ммм, нигде ничего не разыменовываем, поэтому вроде как не UB, надо смотреть можно ли так указатели приводить.
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: jazzer Россия Skype: enerjazzer
Дата: 06.02.14 07:27
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, jazzer, Вы писали:


J>>А зачем вообще это нужно? Какую задачу ты решаешь этим кодом?


E>Встретил на ревью, юзали в качестве lengthof.

E>Написал, что нестандартно, опасно и не константа времени компиляции + UB.
Согласен. Нафига заниматься жонглированием граблями в рантайме, когда можно пользоваться девайсами времени компиляции типа
boost/std::extent< ArrayType >::value

или
template <typename T, std::size_t N>
  inline std::size_t countof( T (&arr)[N] ) { return N; }

(формально тут рантайм-функция, но так как она возвращает константу времени компиляции, любой вменяемый компилятор просто вставит константу; а в С++11 ее вообще constexpr можно объявить)

E>Попросили аргументировать по UB, так как это а-та-та и депримирование вплоть до увольнения...

как-то жестковато для простого UB, имхо

E>В целом я тоже считаю, что это UB, так как 1[&array] -- разыменование.

именно:

The expression E1[E2] is identical (by definition) to *((E1)+(E2))

а в статье про оператор разыменования сказано:

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an
object type, or a pointer to a function type and the result is an lvalue referring to the object or function
to which the expression points.

стало быть, если нет никакого объекта, на который указывает выражение (E1)+(E2), то и поведение не определено.
Это даже не говоря о том, что у разыменованного "объекта" может оказаться свой веселый перегруженный оператор* (а не встроенный), который может вызвать форматирование винчестера и запуск ракет.

E>Но, с другой стороны, это же всего лишь ссылка, у которой потом берут адрес? Ссылку на конец массива получать ведь нельзя? Я верно понимаю?

Это лишь аппеляция к "существующий судебной практике". В том смысле, что "скорее всего ничего не будет, я в дизассемблере посмотрел и поставил свечку, что все компиляторы всегда такой же код генерят".

E>Я как бы посмотрел стандарт, правда старый, но на вский случай решил проконсультроваться у коллег... Вопрос IMHO крайне казуистический всё-таки.

E>С другой стороны, просто интересно, насколько это UB реализуемо...

Очень легко. Надо просто помнить про существование интерпретаторов С++, типа cint или cling. Им ничто не мешает отслеживать все разыменования и форматировать винчестер, если что не так
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: (1[&array]-&array[0]) -- UB or not UB?
От: rg45 СССР  
Дата: 06.02.14 07:44
Оценка: 6 (1) +1
Здравствуйте, flаt, Вы писали:

F>А почему? Ведь &array == array == &array[0]?


Широко распространенное заблуждение. Почему-то людям кажется, что если массив неявно преобразуется к указателю, то адрес массива и сам массив — это одно и тоже Нет. Выражения &array и array имеют разные типы, не подлежащие даже сравнению.
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: XuMuK Россия  
Дата: 06.02.14 07:57
Оценка:
Здравствуйте, Erop, Вы писали:

E>Встретил на ревью, юзали в качестве lengthof.


оффтоп:
а чем такой вариант принципиально лучше шаблона jazzer'a или стандартного sizeof(array) / sizeof(*array) ?
Re[7]: (1[&array]-&array[0]) -- UB or not UB?
От: uzhas Ниоткуда  
Дата: 06.02.14 08:17
Оценка:
Здравствуйте, XuMuK, Вы писали:

XMK>оффтоп:


еще немного оффтопа : http://www.rsdn.ru/forum/cpp/4831841.flat
Автор: sts
Дата: 26.07.12
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: Abyx Россия  
Дата: 06.02.14 08:31
Оценка: :)))
Здравствуйте, Erop, Вы писали:

E>Встретил на ревью, юзали в качестве lengthof.

E>Написал, что нестандартно, опасно и не константа времени компиляции + UB.
E>Попросили аргументировать по UB, так как это а-та-та и депримирование вплоть до увольнения...

скажи им что вместо & надо использовать std::addressof
In Zen We Trust
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: Evgeny.Panasyuk Россия  
Дата: 06.02.14 08:41
Оценка: 10 (1)
Здравствуйте, Erop, Вы писали:

J>>А зачем вообще это нужно? Какую задачу ты решаешь этим кодом?

E>Встретил на ревью, юзали в качестве lengthof.
E>Написал, что нестандартно, опасно и не константа времени компиляции + UB.

Может быть вот этот код поможет:
#include <type_traits>

int main()
{
    char array[1][11];

    static_assert(std::is_same<decltype((1[&array[0]])), decltype((array[1]))>::value, "");
    static_assert(&1[&array[0]] == &array[1], "");

    array[1]; // line #10
    array[1]-&array[0][0]; // line #11
    
    1[&array[0]]-&array[0][0]; // line #13
    1[&array[0]]-&array[0][0]; // line #14
}

clang++ -std=c++11 -O0 -Wall -Wno-unused-value -pedantic -pthread main.cpp && ./a.out

main.cpp:10:5: warning: array index 1 is past the end of the array (which contains 1 element) [-Warray-bounds]
    array[1]; // line #10
    ^     ~

main.cpp:5:5: note: array 'array' declared here
    char array[1][11];
    ^

main.cpp:11:5: warning: array index 1 is past the end of the array (which contains 1 element) [-Warray-bounds]
    array[1]-&array[0][0]; // line #11
    ^     ~

main.cpp:5:5: note: array 'array' declared here
    char array[1][11];
    ^

2 warnings generated.

Clang во втором случае warning не выдаёт, но я думаю это скорей всего недоработка.
Достаточно доказать ссылаясь на пункты ISO тождественное равенство array[1] и 1[&array[0]], чтобы заручится поддержкой Clang'а.

E>Попросили аргументировать по UB, так как это а-та-та и депримирование вплоть до увольнения...


Это Хотя молодцы

E>В целом я тоже считаю, что это UB, так как 1[&array] -- разыменование.


Тоже так считаю.
Re[7]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 09:17
Оценка: +1
Здравствуйте, XuMuK, Вы писали:

XMK>оффтоп:

XMK>а чем такой вариант принципиально лучше шаблона jazzer'a или стандартного sizeof(array) / sizeof(*array) ?

Кто бы знал...
IMHO, автор хотел выпендриться...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 09:17
Оценка:
Здравствуйте, Abyx, Вы писали:

A>скажи им что вместо & надо использовать std::addressof

Зачем?
В смысле зачем говорить?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: (1[&array]-&array[0]) -- UB or not UB?
От: Кодт Россия  
Дата: 06.02.14 09:22
Оценка: 10 (1)
Здравствуйте, Erop, Вы писали:

Идея прикольная, но больно уж ошибкоопасная.

Классика жанра: вместо array подсунуть указатель на первый элемент.
В случае с sizeof(p)/sizeof(*p) мы получим константу времени компиляции, которая принимает значения от 0 до 8 в зависимости от платформы и типа элементов.
В случае (&p)[1]-&(p[0]) — константа времени исполнения, зависящая от того, какой мусор валяется в памяти рядом с указателем.
Перекуём баги на фичи!
Re[8]: (1[&array]-&array[0]) -- UB or not UB?
От: Abyx Россия  
Дата: 06.02.14 09:41
Оценка: :)
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Abyx, Вы писали:


A>>скажи им что вместо & надо использовать std::addressof

E>Зачем?
E>В смысле зачем говорить?
затем что & в обобщенном коде использовать нельзя потому что он может быть перегружен.
In Zen We Trust
Re[4]: (1[&array]-&array[0]) -- UB or not UB?
От: k55 Ниоткуда  
Дата: 06.02.14 09:45
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, rg45, Вы писали:


R>>Я уверен, Егор это и так знает. Видимо, весь вопрос в волшебном символе &, а точнее в его положении — в одном случае он задает адрес элемента массива, а в другом — адрес всего массива.


E>Именно так. Формально мы ка кбы разыменовываем указатель на место за массивом, но разыменовываем его только для того, что бы преобразовать к адресу нулевого элемента этого несуществующего массива, то есть, фактически,
(typeof(array[0])*)1[&array]
это получение указателя на конец массива.

E>Вопрос в том, валидно ли такое недоразыменование?

Спасибо за код. Долго курил, но вопрос остался. А почему тут происходит разименование адреса?
По тойже причине что и
cout << array;

автоматом разименует на 0 элемент?
Если есть желание — найдется 1000 возможностей.
Если нет желания — найдется 1000 причин.
Re[5]: (1[&array]-&array[0]) -- UB or not UB?
От: Evgeny.Panasyuk Россия  
Дата: 06.02.14 10:01
Оценка: 12 (2)
Здравствуйте, k55, Вы писали:

k55>Спасибо за код. Долго курил, но вопрос остался. А почему тут происходит разименование адреса?


Ещё со времён C, для массивов 1[x] тождественно равно *(1+x). ISO/IEC 9899:TC2:

6.5.2.1 Array subscripting
[...]
2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). [...]

Если нет специальных правил для &* (на подобие short-circuit evaluation) — то происходит dereferencing.

Хотя я нашёл вот такие пункты в ISO C:

6.5.3.2 Address and indirection operators
[...]
3. The unary & operator yields the address of its operand. If the operand has type ‘‘type’’, the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator. Otherwise, the result is a pointer to the object or function designated by its operand.
4. The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.84)
[...]
84) Thus, &*E is equivalent to E (even if E is a null pointer), and &(E1[E2]) to ((E1)+(E2)). It is always true that if E is a function designator or an lvalue that is a valid operand of the unary & operator, *&E is a function designator or an lvalue equal to E. If *P is an lvalue and T is the name of an object pointer type, *(T)P is an lvalue that has a type compatible with that to which T points.
Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an address inappropriately aligned for the type of object pointed to, and the address of an object after the end of its lifetime.

Возможно что и не UB.
Re[9]: (1[&array]-&array[0]) -- UB or not UB?
От: night beast СССР  
Дата: 06.02.14 10:07
Оценка: -1
Здравствуйте, Abyx, Вы писали:

A>>>скажи им что вместо & надо использовать std::addressof

E>>Зачем?
E>>В смысле зачем говорить?

A>затем что & в обобщенном коде использовать нельзя потому что он может быть перегружен.


за такие фокусы (перегрузка &) по рукам надо бы давать.
Re[2]: (1[&array]-&array[0]) -- UB or not UB?
От: Vlad_SP  
Дата: 06.02.14 10:08
Оценка:
Здравствуйте, Кодт, Вы писали:

К>В случае с sizeof(p)/sizeof(*p) мы получим константу времени компиляции, которая принимает значения от 0 до 8 в зависимости от платформы и типа элементов.


Гмм. Почему "от 0" ? Поясни, плз.
(То есть, если p — просто указатель, это понятно. Но как будто в треде обсуждается случай, когда p — честный массив. Нет?)
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: Evgeny.Panasyuk Россия  
Дата: 06.02.14 10:10
Оценка:
EP>Возможно что и не UB.

Для UB тут есть ещё и другая возможность, помимо разыменования.
Насколько легален следующий код:
int main()
{
    int x = 0;
    auto first = &x;
    auto last = first + 1; // legal?
    // use as range [first, last)
}
?
Re[7]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 10:36
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Насколько легален следующий код:

EP>
EP>int main()
EP>{
EP>    int x = 0;
EP>    auto first = &x;
EP>    auto last = first + 1; // legal?
EP>    // use as range [first, last)
EP>}
EP>
?


В С++ легален. В С -- не смотрел, но скорее всего тоже легаелен.
Вообще скалярные переменные во всей адресной арифметике везде могут трактоваться как массивы из одного элемента. Есть такой отдельный пункт в стандарте.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 10:37
Оценка:
Здравствуйте, Abyx, Вы писали:

E>>В смысле зачем говорить?

A>затем что & в обобщенном коде использовать нельзя потому что он может быть перегружен.
Это ответ на вопрос "зачем использовать?", а не на мой...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: (1[&array]-&array[0]) -- UB or not UB?
От: Evgeny.Panasyuk Россия  
Дата: 06.02.14 10:52
Оценка:
E>Вообще скалярные переменные во всей адресной арифметике везде могут трактоваться как массивы из одного элемента. Есть такой отдельный пункт в стандарте.

А какой пункт? Может кто знает/найдёт.
Я помню искал — да видимо keyword'ы не те.
Re[9]: (1[&array]-&array[0]) -- UB or not UB?
От: Fuz  
Дата: 06.02.14 11:26
Оценка: 28 (2)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

E>>Вообще скалярные переменные во всей адресной арифметике везде могут трактоваться как массивы из одного элемента. Есть такой отдельный пункт в стандарте.


EP>А какой пункт? Может кто знает/найдёт.

EP>Я помню искал — да видимо keyword'ы не те.

5.7 (Additive operators)
...
4. For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the
first element of an array of length one with the type of the object as its element type.

Re[8]: (1[&array]-&array[0]) -- UB or not UB?
От: Igore Россия  
Дата: 06.02.14 11:36
Оценка:
Здравствуйте, Igore, Вы писали:

I>Здравствуйте, Erop, Вы писали:


E>>Здравствуйте, Igore, Вы писали:


I>Получается

I>
I>int array[10];

I>int (*tmp1)[10] = &array + 1;
I>int *tmp2 = &array[0];

I>cout << ((int*)tmp1 - tmp2);
I>

I>Ммм, нигде ничего не разыменовываем, поэтому вроде как не UB, надо смотреть можно ли так указатели приводить.

Исправлюсь напоследок, правильный вариант.

int* tmp1 = *(&array + 1);//1[&array]
int* tmp2 = *(&array);//&array[0]
cout << (tmp2 - tmp1);
Re[3]: (1[&array]-&array[0]) -- UB or not UB?
От: Igore Россия  
Дата: 06.02.14 11:39
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Igore, Вы писали:


I>>Не UB,

I>>
1[array] == array[1], грубо говоря 
I>>1 + *pointer == *pointer + 1


E>Спасибо за разъяснения. Я верно понял, что с твоей т. з. тут всё нормуль:
int f( int i)
E>{
E>    return 1[&i];
E>}


Неверное сравнение, переделаю твой пример
int f( int i)
{
    return *(&i + 1);
}
Re[4]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 13:07
Оценка:
Здравствуйте, Igore, Вы писали:

E>>Спасибо за разъяснения. Я верно понял, что с твоей т. з. тут всё нормуль:
int f( int i)
E>>{
E>>    return 1[&i];
E>>}


I>Неверное сравнение, переделаю твой пример

I>
I>int f( int i)
I>{
I>    return *(&i + 1);
I>}
I>


AFAIK, в С, и в С++, если не намудрить с перегрузкой операторов, выражения
*(1 + &i)
и
1[&i]
ЭКВИВАЛЕНТНЫ...

Тем не менее, всё нормуль, да?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: (1[&array]-&array[0]) -- UB or not UB?
От: Igore Россия  
Дата: 06.02.14 13:45
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Igore, Вы писали:


E>>>Спасибо за разъяснения. Я верно понял, что с твоей т. з. тут всё нормуль:
int f( int i)
E>>>{
E>>>    return 1[&i];
E>>>}


I>>Неверное сравнение, переделаю твой пример

I>>
I>>int f( int i)
I>>{
I>>    return *(&i + 1);
I>>}
I>>


E>AFAIK, в С, и в С++, если не намудрить с перегрузкой операторов, выражения
*(1 + &i)
и
1[&i]
ЭКВИВАЛЕНТНЫ...


E>Тем не менее, всё нормуль, да?..


Нет, не нормуль. Мне передача по значению не понравилась.
В этом коде есть проблемы?
int inc( int* i )
{
   return 1[i];
}

int main(int argc, char* argv[])
{
   int arr[] = { 1, 2, 3 };
   cout << inc( &0[arr] ) << inc( &1[arr] ) << endl;
   return 0;
}
Re[6]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 16:04
Оценка:
Здравствуйте, Igore, Вы писали:

I>Нет, не нормуль. Мне передача по значению не понравилась.

Дык в исходном примере array был автоматической переменной жеж, а не строкой в массиве...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: (1[&array]-&array[0]) -- UB or not UB?
От: Erop Россия  
Дата: 06.02.14 16:32
Оценка:
Здравствуйте, rg45, Вы писали:

R>Широко распространенное заблуждение. Почему-то людям кажется, что если массив неявно преобразуется к указателю, то адрес массива и сам массив — это одно и тоже Нет. Выражения &array и array имеют разные типы, не подлежащие даже сравнению.


Ну, в С вроде как типы разные, а сравнить всё равно можно...
Правда если там и там по +1 приписать, то уже не будет равенства даже в С...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.