2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Загадка компилятора MS VS 2017
Сообщение19.09.2019, 13:52 
Аватара пользователя


05/06/08
474
В первый раз такое. Не пойму, в чем прикол.
Код:
iint cnt = 0;
   for(int i = -4; i <= 4; i++)
      for (int j = -4; j <= 4; j++)
                  if( i !=0 || j != 0){
                                 bool zr = i != 0 || j != 0;
                                                cnt++;
                                                }

Цикл вылетает после первой инкрементации j++;
По идее даже ранний break оператора if не должен срабатывать после первой инкрементации.
Пока j доползет до нуля. До и вообще, не понятно, почему вообще оператор if в прерывает цикл?
Если zn всегда true. Кроме одной точки. (проверенно дебагом если убрать if( i !=0 || j != 0))
Раньше такого не наблюдал ни разу.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 13:59 


27/08/16
9426
Глюки, сэр. Берите отладчик и трассируйте дизассемблер.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 14:13 
Аватара пользователя


05/06/08
474
Делать мне больше нечего. Проще встроить if в тело цикла с предварительным вычисление bool переменной.
Однако многие мои старые программы написаны именно в такой форме (даже круче if(!( i == 0 && j == 0))), и есть некоторые сомнения, работают ли эти блоки нормально.
Увы...

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 14:34 


27/08/16
9426
MGM в сообщении #1415935 писал(а):
и есть некоторые сомнения, работают ли эти блоки нормально
Вот поэтому и нужно трассировать такие вещи, чтобы понять условия, при которых проявляется баг компилятора. Если это баг компилятора, а не какая-то незамеченная вами ошибка в неопубликованной вами части кода. Но с кодом в подобном стиле, возможно, и смысла нет.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 14:40 
Заслуженный участник


20/08/14
11190
Россия, Москва
Компилятор с -O2 и выше просто выкидывает оба цикла и в printf печатает тупо константу ... :D
Так что да, какой-то глюк компилятора.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 15:14 
Заслуженный участник
Аватара пользователя


16/07/14
8504
Цюрих
MGM, покажите, пожалуйста, больший фрагмент - из которого понятно, как вы сделали вывод, что происходит выход из цикла. В идеале - вообще минимально работающий демонстрирующий этот эффект пример.
При всём уважении, почти наверняка это ошибка у вас, а не в компиляторе.
Dmitriy40 в сообщении #1415943 писал(а):
Компилятор
с -O2 и выше просто выкидывает оба цикла
Имеет право - наблюдаемое поведение не меняется.
Он и более сложные штуки может выкинуть (вплоть до суммы арифметической прогрессии ЕМНИП).

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 15:59 


16/08/19
70
Вообще-то, такое выражение и должно тупо превращаться в int cnt = 80; еще на этапе компиляции.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 16:06 


14/01/11
2921
mihaild в сообщении #1415950 писал(а):
Он и более сложные штуки может выкинуть (вплоть до суммы арифметической прогрессии ЕМНИП).

До чего техника дошла. Надо забить туда частичную сумму ряда $\sum \limits_{i=1}^\infty \frac{1}{n^3 \sin^2 n}$ - чем чёрт не шутит. :-)

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 18:02 
Аватара пользователя


05/06/08
474
mihaild в сообщении #1415950 писал(а):
MGM, покажите, пожалуйста, больший фрагмент - из которого понятно, как вы сделали вывод, что происходит выход из цикла. В идеале - вообще минимально работающий демонстрирующий этот эффект пример.
При всём уважении, почти наверняка это ошибка у вас, а не в компиляторе.
Dmitriy40 в сообщении #1415943 писал(а):
Компилятор
с -O2 и выше просто выкидывает оба цикла
Имеет право - наблюдаемое поведение не меняется.
Он и более сложные штуки может выкинуть (вплоть до суммы арифметической прогрессии ЕМНИП).

Я отлаживал кусок программы, и в дебагере и ставил метку внутри цикла.
Если if имел место быть, то вместо 80 раз на метку выходил лишь раз.
Вот код. Сейчас он работает, но если раскомментить if таже история.

Код:
uint64_t * make_crk_census(int X, int Y, BYTE * im)
{
   uint64_t  x64[64];
   float *img = new float[X*Y];

   POINT *xy = new POINT[64];
   /////////
   



Здесь баг:

Код:
int cnt = 0;
   for(int i = -4; i <= 4; i++)
      for (int j = -4; j <= 4; j++)
                  {

             bool zr = i != 0 || j != 0;
            float r = sqrt((float)(i*i + j*j));
            int ri = i < 0 ? (int)(r + 0.5): (int)(r + 0.6);
            int rr = 0;
            if (zr && ri < 5) { xy[cnt].x = i; xy[cnt].y = j; cnt++; }
            
      }
   /////////

далее
Код:
for (int p = 0; p < X*Y; p++) img[p] = 0.11*im[p] + 0.59*im[p + X*Y] + 0.3*im[p + 2 * X*Y];
   uint64_t * out = new uint64_t[X*Y];
   x64[0] = 1; for (int i = 1; i < 64; i++)x64[i] = x64[i - 1] * 2;
   for (int p = 0; p < X*Y; p++)
   {
      out[p] = point_crk_census(p%X, p / X, X, Y, img, x64, xy);

   }

   delete[] img;
   delete[] xy;

   return out;
}

Ошибка - врядли, но вот глюк оптимизатора - может быть.
Хотя на стадии отдадки я вообще забанил все в подпрограмме, что не относилось непосредственно к заполнению массива POINT xy, как и само заполнение.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 18:08 
Заслуженный участник
Аватара пользователя


16/07/14
8504
Цюрих
MGM в сообщении #1416022 писал(а):
Ошибка - врядли, но вот глюк оптимизатора - может быть.
А почему глюк? Компилятор имеет полное право заменить цикл на дающие тот же результат инструкции.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 18:10 
Аватара пользователя


05/06/08
474
mihaild в сообщении #1416024 писал(а):
MGM в сообщении #1416022 писал(а):
Ошибка - врядли, но вот глюк оптимизатора - может быть.
А почему глюк? Компилятор имеет полное право заменить цикл на дающие тот же результат инструкции.

Ну если так...
Попробую в общем виде.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 18:14 


16/08/19
70
Посмотрите, xy правильно ли заполнен? Боюсь, компилятор заменил всё это на банальный memcpy.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 18:18 
Аватара пользователя


05/06/08
474
нет. Таже история.
Код:
/////////
   int cnt = 0;
   for(int i = -4; i <= 4; i++)
      for (int j = -4; j <= 4; j++)
                  if( i!=0|| j!=0){

             bool zr = i != 0 || j != 0;
            float r = sqrt((float)(i*i + j*j));
            int ri = i < 0 ? (int)(r + 0.5): (int)(r + 0.6);
            int rr = 0; ///!!!!!!!!!!!!!!!!!!!!!!!!!!! МЕТКА
            if (zr && ri < 5) { xy[cnt].x = i; xy[cnt].y = j; cnt++; }
            
      }
   /////////

На метке отстанавливается только раз. И выходит на следующую метку вне цикла.
Хотя по идее должен 80 раз

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 18:21 


16/08/19
70
Повторяю свой предыдущий вопрос. Как ведет себя отладчик совсем не интересует.

 Профиль  
                  
 
 Re: Загадка компилятора MS VS 2017
Сообщение19.09.2019, 18:23 


27/08/16
9426
MGM в сообщении #1416030 писал(а):
Хотя по идее должен 80 раз

Отключите оптимизацию. Полностью.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: mihaild


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group