powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ручное назначение номеров индексов массива
93 сообщений из 93, показаны все 4 страниц
Ручное назначение номеров индексов массива
    #39261322
ukugyul552465
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
К примеру, есть массив int numbers[4], он состоит из элементов:
numbers[0];
numbers[1];
numbers[2];
numbers[3];
Можно ли переназначить индекс элементов, чтобы массив int numbers[4] состоял из элементов:
numbers[2000];
numbers[2001];
numbers[2002];
numbers[2003].
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261326
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ukugyul552465Можно ли
Можно: объяви массив классом, переопредели операцию [] и там можешь спокойно вычитать из
индекса свои 2000.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261328
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да проще наверное сделать минус 2000.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261349
wst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это уже map какой-то получается, вот только последовательного расположения данных в памяти не будет.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261389
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В паскале это работает из коробки.

Я могу щас ошибаться в синтаксисе но где-то так

Код: pascal
1.
2.
type
  numbers=array [2000..2003] of integer;
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261392
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВ паскале это работает из коробки.

Я могу щас ошибаться в синтаксисе но где-то так

Код: pascal
1.
2.
type
  numbers=array [2000..2003] of integer;

даже в Бейсике не к ночи будь помянут
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261415
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ukugyul552465К примеру, есть массив int numbers[4], он состоит из элементов:
numbers[0];
numbers[1];
numbers[2];
numbers[3];
Можно ли переназначить индекс элементов, чтобы массив int numbers[4] состоял из элементов:
numbers[2000];
numbers[2001];
numbers[2002];
numbers[2003].


можно.
только нахрена?
чета времена у нас пошли суровые,
один 25 тыщ потоков для опроса DNS создает, другой элементы массива с 2000 хочет нумеровать...
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261607
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Автору поможет Стебелек, который как известно работает
опережая релятивистские скорости распространения электрического-поля в металлах.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261660
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ukugyul552465,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
#include <iostream>

int numbers[4] = { 0, 1, 2, 3 };

#define numbers (numbers - 2000)

int main() {
    for (int i = 2000; i < 2004; i++) {
        std::cout << "numbers[" << i << "] = " << numbers[i] << std::endl;
    }
    return 0;
}

Вывод:
Код: plaintext
1.
2.
3.
4.
numbers[2000] = 0
numbers[2001] = 1
numbers[2002] = 2
numbers[2003] = 3
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261696
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman, ага главное не забыть потом сделать undefine
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39261717
д0k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Смею предположить что ТС-у
это нужно ,
но он не может нормально задать вопрос.....
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39267168
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ukugyul552465К примеру, есть массив int numbers[4], он состоит из элементов:
numbers[0];
numbers[1];
numbers[2];
numbers[3];
Можно ли переназначить индекс элементов, чтобы массив int numbers[4] состоял из элементов:
numbers[2000];
numbers[2001];
numbers[2002];
numbers[2003].

Можно попробовать выстрелить себе в ногу

Код: plaintext
1.
2.
3.
4.
5.
    int ar[4]  = {1,2,3,4};
    int *p_ar = &ar[0]-2000;

    p_ar[2000] = 100;
    p_ar[2001] = 100;


но нужно ли?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39267172
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBaga, nice shot!

Мне нравится.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39268271
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
так это старый трюк, я думал, уж это-то все знают...
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39268379
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,
абсолютно согласен - старый добрый С-style трюк. То ли народ подзабывать стал, то ли молодёжь подрастает )
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270694
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaukugyul552465К примеру, есть массив int numbers[4], он состоит из элементов:
numbers[0];
numbers[1];
numbers[2];
numbers[3];
Можно ли переназначить индекс элементов, чтобы массив int numbers[4] состоял из элементов:
numbers[2000];
numbers[2001];
numbers[2002];
numbers[2003].

Можно попробовать выстрелить себе в ногу

Код: plaintext
1.
2.
3.
4.
5.
    int ar[4]  = {1,2,3,4};
    int *p_ar = &ar[0]-2000;

    p_ar[2000] = 100;
    p_ar[2001] = 100;


но нужно ли?

И зачем так пробовать? Разве в данном случае мы не имеем ub?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270713
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

индексация — просто сахар для сложения с последующим разыменованием, какое тут UB?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270742
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RWolfиндексация — просто сахар для сложения с последующим разыменованием, какое тут UB?
прямейшее.

Код: plaintext
1.
int *p_ar = &ar[0]-2000;

может просто не исполниться на ряде архитектур

Например на 80286 в защищённом режиме
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270743
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

это то же, что
Код: plaintext
1.
int *p_ar = ar - 2000;
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270747
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А всегда-ли выпрыгивание за границы аррея это ошибка?

ЕМНИП в каких-то языках (толи PHP толи Пайтон) можно было
"кружить кругами" по массиву если индекс был за границей.
По сути MOD (n).
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270755
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonА всегда-ли выпрыгивание за границы аррея это ошибка?
достаточно того, что это может быть ошибкой.

например в том же защищённом 286 эта операция может привести к записи в сегментый регистр невалидного дескриптора со всеми последствиями.

и чем дальше архитектура от PDP/11 - тем веселее
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270766
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

разве арифметика с указателем затрагивает сегментные регистры?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270770
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RWolfИзопропил,

разве арифметика с указателем затрагивает сегментные регистры?
легко затронет, если массив имеет длину более 64КБайт
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270793
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RWolfSashaMercury,

индексация — просто сахар для сложения с последующим разыменованием, какое тут UB?

В данном случае необходимо сделать отсылку к последней версии стандарта (у меня есть черновик, ссылку на который всем предоставил Анатолий, совсем недавно), в частности к разделу 5.7 Additive operators
С++ 17 N4594 5.7.4When an expression that has integral type is added to or subtracted from a pointer, the result has the type
of the pointer operand. If the pointer operand points to an element of an array object84, and the array is
large enough, the result points to an element offset from the original element such that the difference of the
subscripts of the resulting and original array elements equals the integral expression. In other words, if the
expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and
(P)-N (where N has the value n) point to, respectively, the i + n-th and i − n-th elements of the array object,
provided they exist. Moreover, if the expression P points to the last element of an array object, the expression
(P)+1 points one past the last element of the array object, and if the expression Q points one past the last
element of an array object, the expression (Q)-1 points to the last element of the array object. If both the
pointer operand and the result point to elements of the same array object, or one past the last element of the
array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270828
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

то есть, адресная арифметика определена только в пределах выделенной памяти; ну, видимо, на это были какие-то причины.


Изопропил,

хм, как-то не попадались мне такие модели памяти, в которых инкремент указателя может повалить программу. Глянуть бы листинг для иллюстрации.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39270967
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryBagaBagaпропущено...


Можно попробовать выстрелить себе в ногу

Код: plaintext
1.
2.
3.
4.
5.
    int ar[4]  = {1,2,3,4};
    int *p_ar = &ar[0]-2000;

    p_ar[2000] = 100;
    p_ar[2001] = 100;


но нужно ли?

И зачем так пробовать? Разве в данном случае мы не имеем ub?

Там же сказано - выстрелить себе в ногу :)

Это классический (можно сказать - бородатый) трюк со времен С. И да, это UB, если следовать букве стандарта. По стандарту, если вы уж получили непрерывные кусок памяти (в т.ч. массив), то вся ваша адресная арифметика должна уложиться "внутрь" выделенного непрерывного диапазона адресов. Например, вот такой код
Код: plaintext
1.
2.
3.
4.
5.
int a, b;
int *a = &a;
int *b = &b;

b-a;


тоже UB в чистом виде.

Этот UB можно наглядно словить, если вы "захотите обработать" больше сегмента. Или если вдруг "разность" должна стать отрицательным числом... Что тогда будет, ведь отрицательных адресов не бывает? (подсказка - скорее всего "улетите" в чужой сегмент).

Но к несчастью, в большинстве случаев на x86 этот UB работает так, как ожидается )
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39271629
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBaga Это классический (можно сказать - бородатый) трюк со времен С.

Может быть (хотя трюки должны быть законными). Было бы интересно увидеть где этот "трюк" встречается (увидеть отсылку времен K&R к такому примеру) и как его комментируют авторы
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39273844
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryBagaBaga Это классический (можно сказать - бородатый) трюк со времен С.

Может быть (хотя трюки должны быть законными). Было бы интересно увидеть где этот "трюк" встречается (увидеть отсылку времен K&R к такому примеру) и как его комментируют авторы

SashaMercury, ты не поверишь, но трюки никому ничего не должны :) Более того, большинство из них по определению UB. Ну вот взять хоть те же трюки по доступу к закрытым полям класса. Как их сделать без UB? Никак :)

Во времена K&R, на сколько я знаю, интернета не было. Так что дать ссылку на первоисточник вряд ли можно. Этот трюк встречался в разных кодах, но популяризировали его, скорее всего, авторы книги Numerical Recipes in C. В новых переизданиях этот трюк убрали как не совсем соответсвующий стандарту.

PS
Да, к стати, никого не смущает, что итератор end() указывает _ЗА_ последний элемент? Похоже, что именно для этой практики в адресной арифметике в стандарте сделано исключение - можно получать (про разъыменовывать - ни ни) адрес, на один элемент больший, чем последний адрес выделенной непрерывной области. Иначе пришлось бы "закопать" весь STL :))
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39273858
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaSashaMercuryпропущено...


Может быть (хотя трюки должны быть законными). Было бы интересно увидеть где этот "трюк" встречается (увидеть отсылку времен K&R к такому примеру) и как его комментируют авторы

SashaMercury, ты не поверишь, но трюки никому ничего не должны :) Более того, большинство из них по определению UB. Ну вот взять хоть те же трюки по доступу к закрытым полям класса. Как их сделать без UB? Никак :)


У нас с вами разные определения для этого слова. На мой взгляд трюк это что-то законное, но не явное.

BagaBagaВо времена K&R, на сколько я знаю, интернета не было. Так что дать ссылку на первоисточник вряд ли можно. Этот трюк встречался в разных кодах, но популяризировали его, скорее всего, авторы книги Numerical Recipes in C. В новых переизданиях этот трюк убрали как не совсем соответсвующий стандарту.


Вы выше писали про то, что трюки не обязаны соответствовать стандарту, более того, по определению ub

BagaBagaPS
Да, к стати, никого не смущает, что итератор end() указывает _ЗА_ последний элемент? Похоже, что именно для этой практики в адресной арифметике в стандарте сделано исключение - можно получать (про разъыменовывать - ни ни) адрес, на один элемент больший, чем последний адрес выделенной непрерывной области. Иначе пришлось бы "закопать" весь STL :))

Мне кажется что в данной ситуации все ровно наоборот
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39273869
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И конечно возможность проводить сравнение с элементов следующим за последним элементов скорее всего связана с устоявшейся традицией работать с полуоткрытыми интервалами при непосредственном кодировании и разработке алгоритмов [a,b), т.о. классический цикл в качестве шаблона будет иметь следующий вид:
for(T i=0;i<n;++i){
smth do
}

из чего следует необходимость распространения арифметики указателей на элемент после последнего элемента массива
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274161
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryВы выше писали про то, что трюки не обязаны соответствовать стандарту, более того, по определению ub

SashaMercury,
вы как-то интересно надёргиваете мои слова. Я ни где не писал, что ВСЕ трюки - UB. Как и то, что все UB - трюки... Неужели нужно переформулировать? Ок: большинство трюков (нужно ли уточнять, что из тех, что я видел?) являются UB по определению UB.

SashaMercuryУ нас с вами разные определения для этого слова. На мой взгляд трюк это что-то законное, но не явное.

Можно подумать, UB - это что-то незаконное :). UB это всего лишь UB. Стандарт регламентирует ряд ситуаций. Есть ситуации, которые стандарт отказывается регламентировать. Эти ситуации и есть Undefined стандартом Behavior, т.е. по-просту неопределённые. Это значит, что в этих ситуациях может произойти что угодно, и это "что угодно" будет законным. И зависеть от усмотрения разработчика (компилятора).
Например,
Код: plaintext
1.
2.
3.
4.
void main()
{
  return;
}


чистой воды UB, но при этом этот код спокойно откомпилируется компиляторами от MS, от Borland (а, ну да - Embarcadero), но тот же gcc выдаст ошибку компиляции ))

SashaMercuryBagaBagaPS
Да, к стати, никого не смущает, что итератор end() указывает _ЗА_ последний элемент? Похоже, что именно для этой практики в адресной арифметике в стандарте сделано исключение - можно получать (про разъыменовывать - ни ни) адрес, на один элемент больший, чем последний адрес выделенной непрерывной области. Иначе пришлось бы "закопать" весь STL :))
Мне кажется что в данной ситуации все ровно наоборот
Что - ровно наоборот?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274167
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryИ конечно возможность проводить сравнение с элементов следующим за последним элементов скорее всего связана с устоявшейся традицией работать с полуоткрытыми интервалами при непосредственном кодировании и разработке алгоритмов [a,b), т.о. классический цикл в качестве шаблона будет иметь следующий вид:
for(T i=0;i<n;++i){
smth do
}

из чего следует необходимость распространения арифметики указателей на элемент после последнего элемента массива

Вот из чего что следует, тут совершенно непонятно )))

Вы привели классический пример цикла из С и С++. Вот только он не соответствует устоявшейся практике разработчиков STL. Загляните, там полно другого кода, всё больше в стиле
Код: plaintext
1.
2.
3.
4.
while(it != v.end()){
   ...
   ++it;
}


Обратите внимание, типовая реализация от STL требует только наличия оператора сравнения на равенство (ну, или неравенство). Ваш же цикл требует значительно большего - он требует не только сравнимости равно - не равно (как в STL), но и упорядоченности (какой из двух элементов больше). Причём, строгой :)). Что может вызвать некоторые проблемы, причём ровно те же, что и UB в решении с трюком-на-указателях :)
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274170
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaВот из чего что следует, тут совершенно непонятно )))
Очень даже понятно. Если последний элемент занимает последние байты адресного пространства, то это бесконечный цикл, т.к. ++ уведет в начало.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274180
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
следуйте соглашениям STL и используйте "!=" вместо "<" - тогда и "бесконечного цикла" не будет :)
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274222
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBaga, у нас здесь не курица с яйцом и не сообщество благородных девиц Сорбонны, потому софистикой заниматься мне не интересно. Вы безусловно можете оставаться при своем мнении
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274223
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBaga Ваш же цикл требует значительно большего - он требует не только сравнимости равно - не равно (как в STL), но и упорядоченности (какой из двух элементов больше). Причём, строгой :)). Что может вызвать некоторые проблемы, причём ровно те же, что и UB в решении с трюком-на-указателях :)


Приведите пожалуйста пример
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274337
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryBagaBaga, у нас здесь не курица с яйцом и не сообщество благородных девиц Сорбонны, потому софистикой заниматься мне не интересно. Вы безусловно можете оставаться при своем мнении
Софистикой здесь занимаетесь только вы. Укажите на пункт стандарта, запрещающий UB, и тогда я с вами соглашусь. Но вы такого не найдёте.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274345
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryBagaBaga Ваш же цикл требует значительно большего - он требует не только сравнимости равно - не равно (как в STL), но и упорядоченности (какой из двух элементов больше). Причём, строгой :)). Что может вызвать некоторые проблемы, причём ровно те же, что и UB в решении с трюком-на-указателях :)


Приведите пожалуйста пример

Вам же привели пример
Dima TЕсли последний элемент занимает последние байты адресного пространства, то это бесконечный цикл, т.к. ++ уведет в начало.
Вам достаточно подобрать такой адрес, когда it < end() заведомо не выполнится. Т.е. в (it+1) будет происходить переполнение, и "неожиданно" (it+1) < it < end() :)
Как думаете, что выдаст в качестве значения "с"
Код: plaintext
1.
2.
3.
char c = 0
for(; c < 255; c++)
;


такой код? Всегда ли он вернёт одно и то же? Зависит ли возвращаемое от чего-либо? Вернёт ли он что либо? )))
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274448
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBaga, я рискну предположить что данный UB относится не к циклам и шаблону итераторов,
а к переполнению разрядной сетки в принципе.

Я предлагаю участника вообще закрыть это направление. Тем более что градус напряжения в сабже поднялся,
а сегдня - пятница и надо ходить в гавайской рубашке и шортах и быть няшкой и вообще...
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274591
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
рискну предположить, что "проблемы трюка - с - указателем" как раз и проявляются из-за необработки "переполнения" - выхода результирующего адреса за диапазон допустимых значений (e.g., за границы выделенного сегмента).

SashaMercury привёл код
SashaMercuryт.о. классический цикл в качестве шаблона будет иметь следующий вид:
for(T i=0;i<n;++i){
smth do
}

и попросил меня
SashaMercuryBagaBaga ... Что может вызвать некоторые проблемы, причём ровно те же, что и UB в решении с трюком-на-указателях :)

Приведите пожалуйста пример

показать его проблемы. Для чего мне пришлось привести пример,
Код: plaintext
1.
2.
3.
for(char i=0; i < 255;++i){
smth do
}



полностью повтояющий структуру приведённого т.н. "классического цикла", но при этом являющийся UB в чистом виде.

PS
Я только за гавайские рубашки :)
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274595
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЕсли последний элемент занимает последние байты адресного пространства, то это бесконечный цикл, т.к. ++ уведет в начало.
А можете привести пример в котором создается такая ситуация ? )))
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274604
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBaga, ваши контрпримеры неудачны. Придумайте что-нибудь получше ;)
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274627
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryBagaBaga, ваши контрпримеры неудачны. Придумайте что-нибудь получше ;)
Ну так и давайте по пунктам:
- в чём конкретно они неудачны и почему:
- на основании каких критериев сделаны такие выводы;
- откуда вообще эти "критерии" взялись? Желательно, со ссылками на стандарт.

И да, где ссылка на пункт стандарта, утверждающего "UB - это незаконно"? :) Вы же так обильно его цитируете, приведите и здесь )
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274717
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaSashaMercuryBagaBaga, ваши контрпримеры неудачны. Придумайте что-нибудь получше ;)
Ну так и давайте по пунктам:
- в чём конкретно они неудачны и почему:
- на основании каких критериев сделаны такие выводы;
- откуда вообще эти "критерии" взялись? Желательно, со ссылками на стандарт.

И да, где ссылка на пункт стандарта, утверждающего "UB - это незаконно"? :) Вы же так обильно его цитируете, приведите и здесь )

Неудачны потому, что ничего не доказывают. Мне кажется, что ваш пример скорее относится к implementation-defined behavior, нежели к ub. Но это не существенно в любом случае, т.к. из этого не следует что именно операция сравнения привела к этому. Можно привести аналогичный пример с операцией сравнения.

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

Что вы пытаетесь доказать? Что ub это норма? Так вот, это такая-же норма как и поведение того идиота в Ницце. Вчера он обыкновенный тунисец, а сегодня он давит людей. Вчера этот участок кода работал, сегодня вы имеете крах программы или что-нибудь похуже.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39274746
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryНеудачны потому, что ничего не доказывают. ... из этого не следует что именно операция сравнения привела к этому.
Именно операция сравнения знакового char и беззнакового 255 привела к UB. Но для вас, так и быть, "из этого не следует"...

Модератор: Прекращайте спорить
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39275980
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ukugyul552465К примеру, есть массив int numbers[4], он состоит из элементов:
numbers[0];
numbers[1];
numbers[2];
numbers[3];
Можно ли переназначить индекс элементов, чтобы массив int numbers[4] состоял из элементов:
numbers[2000];
numbers[2001];
numbers[2002];
numbers[2003].Можно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int numbers[4];

inline int* number_for_year(int year) {
  assert((2000 <= year) && (year <= 2003));
  return &numbers[year - 2000];
}

int main() {
  *number_for_year(2000) = 3;
  assert(*number_for_year(2000) == 3);
  return 0;
}


BagaBagaМожно подумать, UB - это что-то незаконное :). UB это всего лишь UB. Стандарт регламентирует ряд ситуаций. Есть ситуации, которые стандарт отказывается регламентировать. Эти ситуации и есть Undefined стандартом Behavior, т.е. по-просту неопределённые. Это значит, что в этих ситуациях может произойти что угодно, и это "что угодно" будет законным. И зависеть от усмотрения разработчика (компилятора).По-моему, вы смешиваете две принципиально разные вещи -- unspecified behavior и undefined behavior. Undefined behavior плохо тем, что оптимизирующий компилятор полагается на то, что оно не случается. Например, есть код:
Код: plaintext
1.
2.
3.
4.
5.
6.
int n = ...;
if (n < n + 1) {
  ...
} else {
  handle_overflow();
}

Знаковое (signed) переполнение -- это undefined behavior, оптимизирующий компилятор полагается на то, что оно не случается. Значит, условие в if -- всегда true, его можно не проверять, а вызов функции handle_overflow -- вообще выкинуть.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39277594
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовПо-моему, вы смешиваете две принципиально разные вещи -- unspecified behavior и undefined behavior. Undefined behavior плохо тем, что оптимизирующий компилятор полагается на то, что оно не случается. Например, есть код:
Код: plaintext
1.
2.
3.
4.
5.
6.
int n = ...;
if (n < n + 1) {
  ...
} else {
  handle_overflow();
}

Знаковое (signed) переполнение -- это undefined behavior, оптимизирующий компилятор полагается на то, что оно не случается. Значит, условие в if -- всегда true, его можно не проверять, а вызов функции handle_overflow -- вообще выкинуть.

Пётр, чесслово, очень хотелось бы увидеть на русском "на пальцах" (но без "распальцовки :) ) объяснение, что же такое undefined behavior, unspecified behavior, и на каких критериях (желательно, всё же формальных, а то ведь скатимся до "я ТАК вижу") и тест-кейсах можно отличить одно от другого.

Если честно, мне немного непривычно, что в качестве примера unspecified behavior вы привели результаты работы оптимизатора. Оптимизатор, это такая "вещь в себе", что его работа остаётся загадкой - т.к. зависит от набора доступных ему правил преобразования кода и умения "распознавать" .. клише, что-ли... для оптимизации. И первое, и последнее зависят от разработчиков. Но на первое мы можем влиять через ключи. Правда, мало кто на себе (на своём коде, конечно же) прочувствовал, что выбирая опцию выше O2 собственноручно позволяешь ему произвести ... как бы это ... исполняемый, но неработающий как ожидается код :)

Как думаете, прав ли будет оптимизатор, выкидывая конструкцию вида
Код: plaintext
1.
2.
3.
4.
5.
double d = 1;
...
if(d !=d){
    //process THAT case
}


?

А удивление моё вызвано простой вещью. Существует очень старый, ещё со времён С, пример. Как думаете, что вернёт код
Код: plaintext
1.
2.
3.
int i = 0;
auto f = [](const int a, const int b)->bool{return a > b;};
cout << f(++i,++i);
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278283
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaПётр, чесслово, очень хотелось бы увидеть на русском "на пальцах" (но без "распальцовки :) ) объяснение, что же такое undefined behavior, unspecified behavior, и на каких критериях (желательно, всё же формальных, а то ведь скатимся до "я ТАК вижу") и тест-кейсах можно отличить одно от другого.Да я просто в Wikipedia-и читал:
undefined behavior
unspecified behavior
Ну и в русско-язычной Wikipedia-и тоже есть статьи. Ещё есть статья на cppreference.com. Хотя если глубоко разбираться, то надо стандарт C++ читать, но там много букв.

BagaBagaЕсли честно, мне немного непривычно, что в качестве примера unspecified behavior вы привели результаты работы оптимизатора.Там было про undefined behavior :).

BagaBagaКак думаете, прав ли будет оптимизатор, выкидывая конструкцию вида
Код: plaintext
1.
2.
3.
4.
5.
double d = 1;
...
if(d !=d){
    //process THAT case
}


?Думаю, прав. Здесь же нет volatile, поэтому можно выкинуть if. Вот если написать «volatile double d = 1;», то компилятор должен сохранить if, потому что мы сообщили ему, что другой поток (thread) может в любой момент изменить значение переменной d.

BagaBagaА удивление моё вызвано простой вещью. Существует очень старый, ещё со времён С, пример. Как думаете, что вернёт код
Код: plaintext
1.
2.
3.
int i = 0;
auto f = [](const int a, const int b)->bool{return a > b;};
cout << f(++i,++i);

В последней строке -- два побочных эффекта на одну и ту же переменную, это undefined behavior, насколько я понимаю. Так что неизвестно, что тут будет происходить, и этот код надо переписать. Ну и в старом C-шном коде не может быть лямбды :).
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278964
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовBagaBagaЕсли честно, мне немного непривычно, что в качестве примера unspecified behavior вы привели результаты работы оптимизатора.Там было про undefined behavior :).

тогда согласен :)

Пётр Седов
BagaBagaКак думаете, прав ли будет оптимизатор, выкидывая конструкцию вида
Код: plaintext
1.
2.
3.
4.
5.
double d = 1;
...
if(d !=d){
    //process THAT case
}


?Думаю, прав. Здесь же нет volatile, поэтому можно выкинуть if. Вот если написать «volatile double d = 1;», то компилятор должен сохранить if, потому что мы сообщили ему, что другой поток (thread) может в любой момент изменить значение переменной d.

volatile здесь совершенно непричем. И нет ни слова о многопоточности. Этот код - x!=x - не что иное как полный аналог isnan(x). NaN - это единственное число, коротое не равно самому себе :) Так что будет выкинута проверка получения не-числа...

Пётр СедовBagaBagaА удивление моё вызвано простой вещью. Существует очень старый, ещё со времён С, пример. Как думаете, что вернёт код
Код: plaintext
1.
2.
3.
int i = 0;
auto f = [](const int a, const int b)->bool{return a > b;};
cout << f(++i,++i);

В последней строке -- два побочных эффекта на одну и ту же переменную, это undefined behavior, насколько я понимаю. Так что неизвестно, что тут будет происходить, и этот код надо переписать. Ну и в старом C-шном коде не может быть лямбды :).
Про лямбду. Замените её на функцию :) Это просто чтобы "визуально омолодить" пример и сэкономить пару строк на экране. В стандарте С++ (и С - тоже) порядок вычисления аргументов, переданных в функцию, unspecified. Результат, взвращаемый данной функцией, корректен, но завсист от прядка вычисления аргументов. Так что это был пример на unspecified behavior. Ради интереса, попробуйте скомпилировать его же на компиляторе MS C++ под x86 и под ARM - получите разные результаты :) Его можно (при желании) привратить в UB, если допустить вычисление параметров конкурентно в __разных__ потоках (вот тогда получим UB из-за "одновременного" доступа к "незащищённой" переменной из разных потоков...), вот только ни один компилятор, на сколько я знаю, такого извращения не делает :)
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278971
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagavolatile здесь совершенно непричем. И нет ни слова о многопоточности.
volatile в С/С++ к многопоточности не имеет отношения. volatile означает нестандартная память, т.е. "не оптимизировать и перечитывать при каждом обращении", например в память проецируется показания каких-то датчиков и каждый их опрос вызывает какое-то действие.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278981
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
ок.

volatile здесь означает "выход в другую вселенную", или мене поэтично - значение переменной может измениться независимым от программы способом (например, как значение от внешнего датчика). volatile заставляет при генерации ассемблерного кода не выкидывать инструкии чтения значения из "памяти" в регистр как достаточно медленную операцию. Без этого слова вы можете обнаружить, что программа вдруг показания датчика "не считвает" (а в ассемблерном коде обнаружить, что значение кешируется или, что даже чаще - вообще "заоптимизировано" и вычислено на этапе компиляции... ведь вот же значение, зачем его вычислять рантайм... ну а о его возможных изменениях никто бедному компилятору не сообщит без volatile). Некоторые программисты ошибочно используют это слово для решения проблем совместного использования разными потоками. Увы, это ничего не решает. volatile не имеет отношения к многопоточности. А что же у меня были за слова про многопоточнось? Это был ответ на фразу "Вот если написать «volatile double d = 1;», то компилятор должен сохранить if, потому что мы сообщили ему, что другой поток (thread) может в любой момент изменить значение переменной d."
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278986
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaЭтот код - x!=x - не что иное как полный аналог isnan(x).Так лучше функцию isnan и использовать, а то вдруг на какой-нибудь платформе попытка использовать NAN приведёт к аппаратному прерыванию.

BagaBagaТак что это был пример на unspecified behavior.«f(++i,++i)» -- это как раз undefined behavior:
// http://en.cppreference.com/w/cpp/language/ub Examples of undefined behavior are ..., modification of the same scalar more than once in an expression without sequence points, ...
Dima Tvolatile в С/С++ к многопоточности не имеет отношения.Ну std::atomic далеко не всегда был, некоторые люди до сих пор сидят на старых компиляторах.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278987
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я разбирался с темой volatile в многопоточности http://www.sql.ru/forum/1195434/std-atomic-bool-ili-volatile-bool-est-raznica
А после в книжке прочитал что volatile в С нужен для всяких экзотических случаев, т.к. на нем драйвера пишут, софт для экзотических девайсов и т.д. суть volatile - просто запретить компилятору все оптимизации и тупо делать как написали в коде.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278992
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовBagaBagaЭтот код - x!=x - не что иное как полный аналог isnan(x).Так лучше функцию isnan и использовать, а то вдруг на какой-нибудь платформе попытка использовать NAN приведёт к аппаратному прерыванию.

На момент появления "трюка" стандартного isnan не существовало. Кроме того, не факт, что в используемом компиляторе под все целевые платформы isnan реализована. Ну и наконец, ни кто не будет править исправно работающий и проверенный десятилетиями код только ради сахара.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278995
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовBagaBagaТак что это был пример на unspecified behavior.«f(++i,++i)» -- это как раз undefined behavior:
// http://en.cppreference.com/w/cpp/language/ub Examples of undefined behavior are ..., modification of the same scalar more than once in an expression without sequence points, ...
Dima Tvolatile в С/С++ к многопоточности не имеет отношения.Ну std::atomic далеко не всегда был, некоторые люди до сих пор сидят на старых компиляторах.
Ключевое выделено красным. В применяемой по дефолту модели памяти в приведённом примере есть "sequence points".
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39278997
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовDima Tvolatile в С/С++ к многопоточности не имеет отношения.Ну std::atomic далеко не всегда был, некоторые люди до сих пор сидят на старых компиляторах.
Это не меняет того факта, что volatile не предназначен для решения проблем многопоточности.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39280124
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaНа момент появления "трюка" стандартного isnan не существовало. Кроме того, не факт, что в используемом компиляторе под все целевые платформы isnan реализована.Функцию isnan легко сделать самому.

BagaBagaНу и наконец, ни кто не будет править исправно работающий и проверенный десятилетиями код только ради сахара.«if(d !=d)» -- это плохо читаемый код, потому что здесь написано совсем не то, что имел в виду программист («если в переменной d хранится NAN»).

BagaBagaПётр Седовпропущено...
«f(++i,++i)» -- это как раз undefined behavior:
пропущено...

Ключевое выделено красным. В применяемой по дефолту модели памяти в приведённом примере есть "sequence points".Для текущего стандарта, вот именно про этот код написано, что здесь undefined behavior:
// http://en.cppreference.com/w/cpp/language/eval_order
Код: plaintext
1.
f(++i, ++i);       // undefined behavior until C++17

Да и GCC 4.8.4 при компиляции этого кода выдаёт предупреждение:
Код: plaintext
warning: operation on ‘i’ may be undefined [-Wsequence-point]
На всякий случай: перечисление параметров функции -- это не оператор запятая, поэтому в коде «f(++i,++i)» никогда не было sequence point-а между первым «++i» и вторым «++i».

BagaBagaЭто не меняет того факта, что volatile не предназначен для решения проблем многопоточности.Теоретически (по стандарту) -- да, а на практике многопоточный код на C++ писали задолго до появления std::atomic. Например, у Рихтера в старом издании книги «Programming Applications for Windows» есть такой код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
/******************************************************************************
Module:  IntLockTest.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
...
// Set to TRUE when worker threads should terminate cleanly.
volatile BOOL g_fQuit = FALSE;
...
DWORD WINAPI WorkerThread(PVOID pvParam) {
   ...
   // Should worker thread terminate?
   while (!g_fQuit) {
      ...
   }
   ...
}
...


volatile -- это был единственный способ указать компилятору, что переменная используется несколькими потоками. Ещё в документации к Visual C++ 2010 написано:
// https://msdn.microsoft.com/en-us/library/12a04hfd(v=vs.100).aspx The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread.
И Visual C++ до сих пор воспринимает volatile как «многопоточная переменная», чтобы не ломать старый код:
// https://msdn.microsoft.com/en-us/library/12a04hfd(v=vs.140).aspx Visual Studio 2015
...
Microsoft Specific

When the /volatile:ms compiler option is used—by default when architectures other than ARM are targeted—the compiler generates extra code to maintain ordering among references to volatile objects in addition to maintaining ordering to references to other global objects. In particular:

* A write to a volatile object (also known as volatile write) has Release semantics; that is, a reference to a global or static object that occurs before a write to a volatile object in the instruction sequence will occur before that volatile write in the compiled binary.

* A read of a volatile object (also known as volatile read) has Acquire semantics; that is, a reference to a global or static object that occurs after a read of volatile memory in the instruction sequence will occur after that volatile read in the compiled binary.

This enables volatile objects to be used for memory locks and releases in multithreaded applications.
http://en.cppreference.com/w/cpp/atomic/memory_order Relationship with volatile
...
One notable exception is Visual Studio, where, with default settings, every volatile write has release semantics and every volatile read has acquire semantics (MSDN), and thus volatiles may be used for inter-thread synchronization.
Понятно, что сейчас лучше использовать std::atomic, но при этом странно читать утверждения вроде «volatile в С/С++ к многопоточности не имеет отношения», потому что есть «volatile по стандарту», но есть и «volatile по понятиям».
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39280439
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовBagaBagaНа момент появления "трюка" стандартного isnan не существовало. Кроме того, не факт, что в используемом компиляторе под все целевые платформы isnan реализована.Функцию isnan легко сделать самому.
Ок. Я определю isnan как
Код: plaintext
1.
2.
3.
bool isnan(double d){
   return d!=d;
} 


и в результате оптимизатор заменит её вызво на вечный false? Помним же - речь была в контексте оптимизатора. Раньше он выкидывал ветвь условного оператора, а будет выкидывать вызов функции, делов-то... Что так, что эдак - одна фигня... т.е. нерабочий код.
Но вы так и не ответили: нафига переписывать нормальный работающий код? Вам больше делать на работе нечего?

Пётр СедовBagaBagaНу и наконец, ни кто не будет править исправно работающий и проверенный десятилетиями код только ради сахара.«if(d !=d)» -- это плохо читаемый код, потому что здесь написано совсем не то, что имел в виду программист («если в переменной d хранится NAN»).

Это хорошо известная идиома, такая же как
Код: plaintext
1.
while (*dst++ = *src++);


Хорошо детектирует неофита на ниве использования С/С++ для численного счёта :)

Пётр СедовДа и GCC 4.8.4 при компиляции этого кода выдаёт предупреждение:
Код: plaintext
warning: operation on ‘i’ may be undefined [-Wsequence-point]

Что же мне для вас всё красным приходится выделять. Не все предупреждения и ошибки компиляции действительно состоят в том, о чём выводит текст компилятор...

Пётр СедовBagaBagaЭто не меняет того факта, что volatile не предназначен для решения проблем многопоточности.Теоретически (по стандарту) -- да
Этого - достаточно. Не далее как пару страниц назад г-н SashaMercury очень методично высказывался на трюк-с-указателем по поводу "не по стандарту" (точнее, про "это ж UB" !!! ). Так что - либо только стандарт и никаких UB, либо "а фиг с этим стандартом, у нас и так работает" :))
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39280730
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaПётр Седовпропущено...
Функцию isnan легко сделать самому.
Ок. Я определю isnan как
Код: plaintext
1.
2.
3.
bool isnan(double d){
   return d!=d;
} 


Так гораздо лучше, потому что трюк локализован в функции с понятным именем, а не растиражирован по всей программе.

BagaBagaи в результате оптимизатор заменит её вызво на вечный false?GCC 4.8.4 c включённой оптимизацией (-O3) сохраняет проверку, и трюк работает. Как поступит другой компилятор -- не знаю.

BagaBagaНо вы так и не ответили: нафига переписывать нормальный работающий код?Чтобы код был понятен программистам, которые не знакомы с трюком. Например, если есть код:
Код: plaintext
1.
  if (((width & (width - 1)) == 0) && ((height & (height - 1)) == 0)) {

то его надо переписать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
inline bool is_pow_2(int n) {
  assert(n >= 1);
  return (n & (n - 1)) == 0;
}
...
  if (is_pow_2(width) && is_pow_2(height)) {


BagaBagaПётр Седовпропущено...
«if(d !=d)» -- это плохо читаемый код, потому что здесь написано совсем не то, что имел в виду программист («если в переменной d хранится NAN»).

Это хорошо известная идиома,Скорее, не очень известный трюк. О нём разве пишут в учебниках по C++?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39280960
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовBagaBagaи в результате оптимизатор заменит её вызво на вечный false?GCC 4.8.4 c включённой оптимизацией (-O3) сохраняет проверку, и трюк работает. Как поступит другой компилятор -- не знаю.

так и исходная конструкция (не запрятанная в функцию) также не будет исключена. А потом проверить обе конструкции на icc с максимально агрессивной оптимизацией :)

Пётр СедовBagaBagaНо вы так и не ответили: нафига переписывать нормальный работающий код?Чтобы код был понятен программистам, которые не знакомы с трюком.
Так и запишем. Чтобы был понятен программистам с меньшей квалификацией. Вопрос только, до какого уровня опускаться?

Пётр Седов
Код: plaintext
1.
  if (((width & (width - 1)) == 0) && ((height & (height - 1)) == 0)) {

то его надо переписать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
inline bool is_pow_2(int n) {
  assert(n >= 1);
  return (n & (n - 1)) == 0;
}
...
  if (is_pow_2(width) && is_pow_2(height)) {



О вкусах, конечно, не спорят (как и о замечательной книге Алгоритмические трюки для программистов), но проверку на степени двойки обычно делают при помощи битовых сдвигов. Когда-то так было быстрее, чем с использованием арифметики. А к этой реализации есть и стилевые вопросы: сначала используются битовое &, а затем логическое == 0. Странное, ведь в С (и С++) есть прекрасная идиома (!с) вместо (с == 0). Обычно так пишут новички в С/С++, только пришедшие из "более других языков". А если из совсем "более других языков", то могут написать и ( 0 == с ) только для того, чтобы отловить места, в которых они = и == попутали )

Пётр СедовBagaBagaЭто хорошо известная идиома,Скорее, не очень известный трюк. О нём разве пишут в учебниках по C++?
В хороших книгах по численным методам - пишут. Иначе вы не сможете прочесть половину кода открытых моделей NASA... правда, фортрана там всё же больше :)
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281038
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Генри Уоррен в своей книге описал почти все трюки с целочисленной
арифметикой.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281099
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовЧтобы код был понятен программистам, которые не знакомы с трюком. Например, если есть код:
Код: plaintext
1.
  if (((width & (width - 1)) == 0) && ((height & (height - 1)) == 0)) {

то его надо переписать так:
...

можно просто комментарий написать
Код: plaintext
1.
2.
// если width и height степени двойки
  if (((width & (width - 1)) == 0) && ((height & (height - 1)) == 0)) {
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281245
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, такой код сложно поддерживать. Уж лучше макрос или функция. Атомарно по крайней мере
с точки зрения смысла.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281477
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaпроверку на степени двойки обычно делают при помощи битовых сдвигов. Когда-то так было быстрее, чем с использованием арифметики. А к этой реализации есть и стилевые вопросы:И в итоге, как выглядит идеальная функция, которая проверяет, является ли число степенью двойки?

BagaBagaв С (и С++) есть прекрасная идиома (!с) вместо (с == 0).Я пишу так:
!x -- для bool
x == 0 -- для чисел

BagaBagaИначе вы не сможете прочесть половину кода открытых моделей NASA...Надеюсь, никогда в жизни не придётся разбираться в коде, который написали учёные. Куча переменных с именами из одной буквы -- это нечто.

Dima Tможно просто комментарий написатьЛучше, когда код понятен без комментариев.
Код: plaintext
1.
if (x != x) { // если в x хранится NAN

Код: plaintext
1.
if (isnan(x)) {
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281483
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовНадеюсь, никогда в жизни не придётся разбираться в коде, который написали учёные. Куча переменных с именами из одной буквы -- это нечто.

Учоные - это не фарисеи и саддукеи. И их код ничем особо
не будет отличаться от того как мы пишем если речь идет
о C/C++.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281491
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр Седовразбираться в коде, который написали учёные. Куча переменных с именами из одной буквы -- это нечто.
На заре карьеры довелось сопровождать прогу разработки конца 80х на FoxBase. Наименование таблиц БД (dbf-ки) a001, a002, a003 ... это был ахтунг, я думал это просто маньяк какой-то написал, потом узнал что и другие с этим сталкивались, оказывается это целая школа разработчиков таких была в то время.
Пётр СедовDima Tможно просто комментарий написатьЛучше, когда код понятен без комментариев.

На вкус и цвет ... Только выше самплес был другой, и главное - обоснование "незнающие не поймут", ну так им вынесенное в отдельную функцию не намного понимание улучшит, так что комментарий нужен, другой вопрос у if`а или у функции, тут дело вкуса фломастеров.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281501
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТолько выше самплес был другой, и главное - обоснование "незнающие не поймут", ну так им вынесенное в отдельную функцию не намного понимание улучшит,Как раз улучшит. Выносим проверку на степень двойки в отдельную функцию => в коде появляется имя «is_pow_2», которое ясно даёт понять, что происходит => комментарий «если width и height степени двойки» не нужен, потому что он просто повторяет код.

Dima Tтак что комментарий нужен, другой вопрос у if`а или у функции,А у функции зачем комментарий? Типа так?
Код: plaintext
1.
2.
3.
4.
// проверяет, является ли число степенью двойки
inline bool is_pow_2(int n) {
  ...
}

Так тут из имени функции понятно, что она делает.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281509
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовА у функции зачем комментарий? Типа так?
Код: plaintext
1.
2.
3.
4.
// проверяет, является ли число степенью двойки
inline bool is_pow_2(int n) {
  ...
}

Так тут из имени функции понятно, что она делает.
Лично мне тут не нужен, т.к. я знал но забыл что такое x & (x - 1) == 0, но если не знаешь изначально, и не знаешь что такое "pow" (я это тоже знал но забыл за ненадобностью, ни разу в жизни pow() не использовал), то понятнее не становится без нормального комментария.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281513
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tя это тоже знал но забыл
а что такое степень двойки - не забыл?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281514
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропила что такое степень двойки - не забыл?
Разбуди с глубокого перепою - скажу любую степень до 2^20 в десятичном исчислении. Полтора года счета в тетрадке в двоичном представлении не забываются
Только степень двойки для меня это не pow() а битовый сдвиг <<
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281517
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сдвиг дает умножение константы на 2. Но это не всегда будет степенью двойки.
Суть формулы Уоррена в том что мы формируем маску из младших битов
и проверяем что пересечение дает пустоту. Это и есть проверка на степень двойки.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281519
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonСдвиг дает умножение константы на 2. Но это не всегда будет степенью двойки.
Частный случай: сдвиг единицы всегда будет степенью двойки.

PS Я электронщик по образованию, нас дрючили за двоичную логику, из нее элементы И-НЕ, ИЛИ-НЕ из них триггеры (типа RAM), сумматоры (типа АЛУ) и т.д. и т.п. Как спроектировать и спаять процессор я в курсе, только паять очень долго придется.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281521
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonСдвиг дает умножение константы на 2.
Не умножение на 2, а на 2 в степени на сколько бит сдвинулись.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281523
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТолько степень двойки для меня это не pow() а битовый сдвиг <
сдвиг - это одна из возможных реализаций.

степень двойки - это из предметной области.


если вместо is_pow_2 гонять биты и маски - ясное дело, что комментарий требуется.

в ряде процессоров имеется команда, выдающая количество единичных бит в операнде.
__popcnt16, __popcnt, __popcnt64 - соответствующие интринсики для интела
и что теперь - писать __popcnt64(n)==1 ?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281526
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TТолько степень двойки для меня это не pow() а битовый сдвиг <
сдвиг - это одна из возможных реализаций.

степень двойки - это из предметной области.
еще раз, математика забыта за ненадобностью, а степень двойки "наше всё" в двоичном мире. Поэтому сдвиг это сдвиг, а никак не возведение в степень. В моем мозгу нет тождественности pow(2,N) и 1<<N, хотя это одно и тоже.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281535
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как выше написал, я электронщик, а в электронике сдвиг это просто провода по диагонали, добавить нолики в младшие разряды результата и сделать ИЛИ тому что ушло за разрядность для контроля переполнения. Т.е. максимум один такт вычисления.
И возведение в степень: это во первых очень сложная операция умножения, которая основана на сложении и еще надо в цикле все выполнять. Тут такты считать устанешь.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281544
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИ возведение в степень: это во первых очень сложная операция умножения, которая основана на сложении и еще надо в цикле все выполнять. Тут такты считать устанешь.
это забота компилятора.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281910
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовBagaBagaв С (и С++) есть прекрасная идиома (!с) вместо (с == 0).Я пишу так:
!x -- для bool
x == 0 -- для чисел

В С/С++ нет разницы между целым и булевым. Ноль - ложь, всё иное - истина :). И будет любопытно, как вы начнёте рефаторить код, кода вдруг bool заменят на int или наоборот... В любом случае !x - широко распространённая практики именно в С/С++...

Пётр СедовBagaBagaИначе вы не сможете прочесть половину кода открытых моделей NASA...Надеюсь, никогда в жизни не придётся разбираться в коде, который написали учёные. Куча переменных с именами из одной буквы -- это нечто.

Могу предложить почитать код на COBOL... на нём точно писали не ученые, но multiplied by вместо знака умножения это ... сильно. И не волнуйтесь, имена из одной буквы вы можете встретьить не только у ученых :).

PS
Надеюсь, все помнять, что переменные, чьb имена начинаются с i,j,k,l,m,n - целоцисленные по умолчанию? :)
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39281938
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКак выше написал, я электронщик, а в электронике сдвиг это просто провода по диагонали, добавить нолики в младшие разряды результата и сделать ИЛИ тому что ушло за разрядность для контроля переполнения. Т.е. максимум один такт вычисления.
И возведение в степень: это во первых очень сложная операция умножения, которая основана на сложении и еще надо в цикле все выполнять. Тут такты считать устанешь.
Дим. Мне кажется это сильно упрощение. Мне кажется здесь ключевое слово не электроника
а набор инструкций. Например 1 раунд шифрования за 1 инструкцию. А сдвиг это уже мелочи.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39282005
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДим. Мне кажется это сильно упрощение. Мне кажется здесь ключевое слово не электроника
а набор инструкций. Например 1 раунд шифрования за 1 инструкцию. А сдвиг это уже мелочи.
Реализация в электронике определяет время выполнения инструкций. Вот я к чему.
По сути любая электроника это тоже набор инструкций. Только в железе. Базовые блоки всей цифровой электроники - элементы И, И-НЕ, ИЛИ, ИЛИ-НЕ, НЕ и ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR). Каждый это несколько транзисторов/диодов/резисторов . Вот время прохождения транзистора это и есть константа, а сколько транзисторов надо пройти для выполнения каждой инструкции асма зависит от инструкции.
Например при выполнении A<<1 все разряды обрабатываются параллельно, тут просто надо скоммутировать 0й разряд входа с 1м выхода и т.д. (готовой схемы не нашел, рисовать лень), а если сделать A+A то уже каскад из одноразрядных сумматоров (рис.10) , т.е. последовательно складываем 0-е разряды, получаем 0-й разряд результата и бит переполнения, передаем его следующему блоку который берет его и 1е разряды и т.д. последовательно каждый разряд. В итоге получили что для 32бит A<<1 в 32 раза быстрее A+A. Это упрощенно, в реале за счет большого количества транзисторов (базовых блоков) можно ускорить например сделав 8-битный сумматор, где 8 разрядов будут параллельно обрабатываться, тогда каскад будет из 4х сумматоров.

Вобщем я к тому что измерение скорости в количестве инструкций процессора это очень грубое измерение.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39282040
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, непонятно зачем ты сделал такой глубокий экскурс в fundamentals для меня.

Ну да ладно. Я думаю что общая (средняя) производительность бинарного кода
зависит конечно-же от алгоритма который ты выбрал. Но мы это просто здесь
пропускаем. Считаем что к алгоритму нет замечаений. И второе - это от
оптимизатора и от возможностей архитектуры под которую ты собираешь.
И не забывать про side-effects. Сдвиги сдвигами но умножение на степень
двойки для отрицательных чисел надо реализовать особо или-же в случае
сомнений может быть имеет смысл вообще отказаться от сдвигов а
просто умножить на 2^N и довериться компиллятору.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39282044
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonСдвиги сдвигами но умножение на степень
двойки для отрицательных чисел надо реализовать особо
двоичное представление отрицательных таково что знак не мешает
Значение двоичное представление-11111b-21110b-41100b
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39282052
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну правильно. Ты должен гарантировать что будут сгенерированы инструкции SAL/SAR
для знакового типа. Только где в части стандарта С++ описано поведение знаковых
сдвигов?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39282726
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНу правильно. Ты должен гарантировать что будут сгенерированы инструкции SAL/SAR
для знакового типа. Только где в части стандарта С++ описано поведение знаковых
сдвигов?
Зависит от того каком представлении хранятся отрицательные числа. Если это дополнительное представление (т.е. отрицательное это 2^R - |X|, где R разрядность) то <<1 равносильно умножению на 2. Насколько я знаю везде используют дополнительное представление, т.к. оно намного удобнее для воплощения мат.операций в железе. Т.к. многие операции делаются одинаково независимо от вида операндов (со знаком и без) Например сложение, потом SHR и SAR это вообще синонимы одной и той же команды. ЕМНИП вычитания как такового вообще нет в железе, второй операнд переводится в дополнительную форму и дальше сложение.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39282757
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, а много ты из практики видел альтернативных способов представления знакового целого?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39282788
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonDima T, а много ты из практики видел альтернативных способов представления знакового целого?
Практики у меня немного, кроме x86 можно сказать ничего не видел, но когда мы изучали двоичную математику (шла в курсе схемотехники год-полтора по 5-6 пар в неделю) про альтернативные варианты нам не рассказывали.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39283047
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TmaytonDima T, а много ты из практики видел альтернативных способов представления знакового целого?
Практики у меня немного, кроме x86 можно сказать ничего не видел, но когда мы изучали двоичную математику (шла в курсе схемотехники год-полтора по 5-6 пар в неделю) про альтернативные варианты нам не рассказывали.
Аналогично. Из курса системотехники нам рассказали о прямом коде, обратном, и модифицированом обратном коде.

Но в своей практике я встречал формат классического 32х битного целого для last-endian (x86)
и big-endian (x86_64,spark,Java). Попадают бит-в-бит. Можно сериализовать между С++ и Java
целые числа.

Другие формы - не встречал.

Кстати Java определяет две операции правого сдвига ">>" и ">>>".
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39283072
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНо в своей практике я встречал формат классического 32х битного целого для last-endian (x86)
и big-endian (x86_64,spark,Java).
endian тут вообще ни при чем, это просто порядок читать биты справа-налево или слева-направо, битовый сдвиг ведь сдвиг в сторону старших/младших, а где они (справа или слева) вообще пофиг.

maytonКстати Java определяет две операции правого сдвига ">>" и ">>>".
Ну так есть два вида сдвига: обычный и циклический. Второй по кругу, то что выпало вставляется с другой стороны. Почитай хэлп почти уверен что >>> циклический.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39283076
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tendian тут вообще ни при чем, это просто порядок читать биты справа-налево или слева-направо, битовый сдвиг ведь сдвиг в сторону старших/младших, а где они (справа или слева) вообще пофиг.

Я делаю акцент на сериализации.

maytonПочитай хэлп почти уверен что >>> циклический.
Неа
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39283077
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПочитай хэлп почти уверен что >>> циклический.
не угадал - просто беззнаковый сдвиг
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39283134
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TПочитай хэлп почти уверен что >>> циклический.
не угадал - просто беззнаковый сдвиг
а в жаве типов чтоли нет?
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39283135
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИзопропилпропущено...

не угадал - просто беззнаковый сдвиг
а в жаве типов чтоли нет?
Все типы - знаковые с точки зрения арифметики целых чисел.
Но в момент битовых операций 'and','or','xor' обладают семантикой unsidned.
...
Рейтинг: 0 / 0
Ручное назначение номеров индексов массива
    #39283136
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonDima Tпропущено...

а в жаве типов чтоли нет?
Все типы - знаковые с точки зрения арифметики целых чисел.
Но в момент битовых операций 'and','or','xor' обладают семантикой unsidned.
Тогда понятно, нет беззнаковых для того и костыль >>>
...
Рейтинг: 0 / 0
93 сообщений из 93, показаны все 4 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ручное назначение номеров индексов массива
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]