Ошибки, баги, вопросы - страница 3611

 
Alexey Viktorov #:
Вот смотри… Казалось бы переменной уже присвоено новое значение, ан нет, пока ещё j равна 2

Именно. Почему?

 
Artyom Trishkin #:

Именно. Почему?

Наверное потому, что присвоение нового значения происходит в момент использования. Или вообще присвоение не происходит в таком случае… ХЗ означает, я тоже Хотел бы Знать…

 
Alexey Viktorov #:
я тоже Хотел бы Знать…
+
 
Alexey Viktorov # :

Наверное потому, что присвоение нового значения происходит в момент использования. Или вообще присвоение не происходит в таком случае… ХЗ означает, я тоже Хотел бы Знать…

Я дал объяснение, но вы его не поняли.
 
Alain Verleyen #:
Я дал объяснение, но вы его не поняли.

Из Вашего пояснения видно, что последовательность расчётов никак не регламентируется, а отдаётся на "откуп" компилятору.

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

Я понимаю, что можно все расчёты сделать построчно шаг за шагом. Но оно стоит того?

 
Artyom Trishkin # :

Из Вашего пояснения видно, что последовательность расчётов никак не регламентируется, а отдаётся на "откуп" компилятору.

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

Я понимаю, что можно все расчёты сделать построчно шаг за шагом. Но оно стоит того?

Может быть, я что-то упустил из-за перевода. Я перечитаю.
 

MQL использует ту же компиляцию, что и язык C.

        push    rbp
        mov     rbp, rsp
        sub     rsp, 16 
        mov     dword ptr [rbp - 4 ], 0
        mov     dword ptr [rbp - 8 ], 2               j=2 
        mov     eax, dword ptr [rbp - 8 ]             temp=j
        mov     dword ptr [rbp - 8 ], 5               j=5 
        imul    eax, eax, 5                           temp=temp*5   //[2*5] 
        mov     dword ptr [rbp - 8 ], eax             j=temp 
        mov     esi, dword ptr [rbp - 8 ]
        mov     rdi, qword ptr [rip + std::cout@GOTPCREL]
        call    std::ostream::operator<<( int )@PLT
        xor     eax, eax
        add     rsp, 16 
        pop     rbp
        ret
Компиляция MSVC/GCC (которая дает j=25):
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp- 4 ], 2                 j= 2 
        mov     DWORD PTR [rbp- 4 ], 5                 j= 5 
        mov     eax, DWORD PTR [rbp- 4 ]               temp=j
        imul    eax, eax                               temp=temp*temp //[ 5 * 5 ]
        mov     DWORD PTR [rbp- 4 ], eax               j=temp         //[ 25 ]
        mov     eax, DWORD PTR [rbp- 4 ]
        mov     esi, eax
        mov     edi, OFFSET FLAT:std::cout
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<( int )
        mov     eax, 0 
        leave
        ret

Оба варианта верны.

Вы НЕ МОЖЕТЕ полагаться на порядок выполнения или на то, как компилятор будет оценивать операнды.

 
Alain Verleyen #:
Вы НЕ МОЖЕТЕ полагаться на порядок выполнения или на то, как компилятор будет оценивать операнды.

Надеюсь, что оценка операндов в логических операциях всегда слева направо. Если это так, то это только благодаря brief estimate?

Очень распространенные примеры инициализации чего-то, где порядок оценки операндов критически важен:

bool a();
bool b();
bool c();
void doSomething();

bool initialize1()
  {
   return(a() && b() && c());
  }

bool initialize2()
  {
   if(!a() || !b())
      return(false);
   doSomething();
   return(c());
  }

void OnStart() {}
 
Vladislav Boyko #:
Очень распространенные примеры инициализации чего-то, где порядок оценки операндов критически важен:

Из того примера не очевидно, что порядок оценки операндов критически важен. Вот другой пример:

class A
  {
public:
   bool initialize();
   int get();
  };

class B
  {
public:
   bool initialize(int a);
   int get();
  };

class C
  {
public:
   bool initialize(int a, int b);
  };

bool f()
  {
   A a;
   B b;
   C c;
   // .get() should not be called before .initialize()
   return(a.initialize() && b.initialize(a.get()) && c.initialize(a.get(), b.get()));
  }
 
Vladislav Boyko # :

Надеюсь, что оценка операндов в логических операциях всегда слева направо. Если это так, то это только благодаря  brief estimate?

Очень распространенные примеры инициализации чего-то, где порядок оценки операндов критически важен:

Конечно, речь шла об арифметических операторах, а не о логических.