2014 dxdy logo

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

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




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


05/06/08
477
В первый раз такое. Не пойму, в чем прикол.
Код:
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
10209
Глюки, сэр. Берите отладчик и трассируйте дизассемблер.

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


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

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


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

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


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

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


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

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


05/06/08
477
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
477
нет. Таже история.
Код:
/////////
   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
10209
MGM в сообщении #1416030 писал(а):
Хотя по идее должен 80 раз

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

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

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



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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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