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

 
Alexey Viktorov:

Такая инициализация возможна. Потому, что переменная 'а' инициализируется константой, а переменная 'b' инициализируется константным выражением.

'b' здесь инициализируется НЕ константным выражением.  Поэтому это противоречит правилам, описанным в документации.

Вся проблема в том, что при инициализации статической переменной функцией, "приостанавливается" инициализация и выполняется эта функция. А в приведённом примере, в той функции ещё есть статическая переменная которая пока ещё не инициализирована. Отсюда и переменная инициализированная функцией принимает не соответствующее значение.

Да как инициализация может приостанавливаться то.  Все операции выполняются в строгом порядке, определённом синтаксисом языка.  Сначала выполняется функция, затем возвращаемое значение этой функции передаётся в конструктор нашей переменной - это называется инициализацией.  А в данном случае операция инициализации нагло игнорируется компилятором, и код компилируется дальше, как ни в чём не бывало. Это недопустимо.    Это то же самое, как если бы ты например объявил такой массив:  int a[]= { f(), g(), h() };  и оно бы компилировалось, но естественно ничего при этом не инициализируя.  

 
A100:

В 32-разрядном терминале ошибка при любом OPTIMIZE

Реально.  Проверил в МТ4, действительно ошибки при любом раскладе.  И как народ там что-то кодит на новых билдах
 
Alexey Navoykov:

'b' здесь инициализируется НЕ константным выражением.  Поэтому это противоречит правилам, описанным в документации.

Да как инициализация может приостанавливаться то.  Все операции выполняются в строгом порядке, определённом синтаксисом языка.  Сначала выполняется функция, затем возвращаемое значение этой функции передаётся в конструктор нашей переменной - это называется инициализацией.  А в данном случае операция инициализации нагло игнорируется компилятором, и код компилируется дальше, как ни в чём не бывало. Это недопустимо.    Это то же самое, как если бы ты например объявил такой массив:  int a[]= { f(), g(), h() };  и оно бы компилировалось, но естественно ничего при этом не инициализируя.  

Если не константным выражением, то ЧЕМ???

Алексей, проще будет если сам возьмёшь тот код и посмотришь в дебагере последовательность инициализации. И ещё, я не сразу заметил, что в этом примере

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Alexey Navoykov, 2017.10.17 20:31

И вот ещё по теме инициализации переменных.  Если следовать тому, что было указано в документации, тогда и ссылаться на другие глобальные/статические переменные тоже нельзя.  Т.к. это не является константным выражением:

int a= 1;
int b= a+1;  // Согласно документации, такая инициализация не возможна

void OnStart()
{
  Print(b);
}

Однако пока это работает.  И я полагаю, многие всегда пользовались такими конструкциями, ничего не подозревая.  Но выходит что в любой момент разработчики могут отрубить это.  И как и в случае с инициализацией функциями, эти коды будут продолжать успешно компилироваться, но станут работать неправильно.  В общем, весь MQL - это мина замедленного действия.


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

У меня не хватает знаний чтобы доступно объяснить, а у вас не хватает внимательности. "приостанавливается" в кавычках!!!

Не надо сваливать в одну кучу инициализацию статических и обычных переменных, тем-более локальных.

 
Alexey Viktorov:

Если не константным выражением, то ЧЕМ???

Неконстантным выражением.

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

У меня не хватает знаний чтобы доступно объяснить, а у вас не хватает внимательности...

Вы ничего не путаете?

Более того, глобальные и статические переменные ведут себя абсолютно идентично.  Вот из документации:

Глобальная переменная может быть проинициализирована только соответствующей ее типу константой либо константным выражением.

Признаюсь, для меня это было таким же открытием, как и со статическими переменными.  Уж не знаю, когда это всё появилось в документации, а может и было раньше, просто никто не обращал внимания, т.к. по факту всё работало как в C++, потому вопросов не возникало. 

 
Alexey Navoykov:

Неконстантным выражением.

Вы ничего не путаете?

Более того, глобальные и статические переменные ведут себя абсолютно идентично.  Вот из документации:

Признаюсь, для меня это было таким же открытием, как и со статическими переменными.  Уж не знаю, когда это всё появилось в документации, а может и было раньше, просто никто не обращал внимания, т.к. по факту всё работало как в C++, потому вопросов не возникало. 

Мне кажется что вы абсолютно заблуждаетесь. Как можно говорить об идентичности переменных, если одни доступны из всех функций, определенных в программе, а другие только в той функции в которой они объявлены.

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

 
Alexey Viktorov:

Мне кажется что вы абсолютно заблуждаетесь. Как можно говорить об идентичности переменных, если одни доступны из всех функций, определенных в программе, а другие только в той функции в которой они объявлены.

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

 
После отправки сообщений через полноценный чат не происходит автодобавление отправленного сообщения в историю переписок на текущей странице.
Отправленное сообщение появляется только после перезагрузки страницы.

На вскидку, ответ от сервера при отправке сообщения приходит адекватный, возможно что-то поплыло в обработчиках событий в js кодах.
 
Alexey Navoykov:

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

На сколько я помню речь шла об инициализации СТАТИЧЕСКОЙ переменной

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Alexey Navoykov, 2017.10.17 17:16

Баг с инициализацией статических переменных.  В старых билдах его не было.

class A
{
 public:
  static int f()
  { 
    static int a=1;
    Print(a);       // Получаем a=0 !!
    return a;  
  }   
};


int a= A::f();


void OnStart()
  {
   
  }

Кому не трудно, отравьте это в сервис-деск.  У меня больше нет желания общаться с ними там.


Или это не ваше сообщение?

Разберитесь уже с последовательностью инициализации переменных. В этом примере сначала инициализируется переменная глобального уровня

int a= A::f();

которая вызывает функцию в которой ещё не инициализирована одноимённая переменная

static int a=1;

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


 
Alexey Navoykov:

Правда я там размерность массива не ту поставил, может это повлияло как-то (хотя не должно никак влиять).

Попробуйте вот с размерностью = 3

Спасибо за сообщение.
Действительно, это ошибка оптимизатора компилятора, исправлено.
Исправление войдёт в следующий билд.
 
Alexey Viktorov:

На сколько я помню речь шла об инициализации СТАТИЧЕСКОЙ переменной

Или это не ваше сообщение?

Не понимаю, чего вы хотите.  Я ж сказал, речь шла об "инициализации переменных". И в этом контексте статические и глобальные переменные ведут себя идентично.  Я вам даже ссылку давал на документацию: инициализация переменной

Обратите внимание, что статические и глобальные переменные там везде объединены вместе.

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

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

Ну поменяйте имя глобальной переменной, если вас это так смущает.  На результат это никак не повлияет.

Причина обращения: