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

 

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

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

template<typename T>
int F1(const T& array[]) { return ArrayMaximum(array); }

template<typename T>
int F2(const T& array[]) { return F1(array); }

void OnStart()
  {
    int arr[3]= { 1, 2, 3 };
    Print(F2(arr));  // Выдаёт -1 !!!
  }
 

Обнаружил причину несоответствия.  В режиме OPTIMIZE=0 ошибка есть, а с OPTIMIZE=1 нет.   Я обычно всегда только OPTIMIZE=0 пользуюсь

 
fxsaber:

Если нахожу логическое (непротиворечивое) объяснение результату, то не вижу бага. Не считаю, что доказательство бага приемлемо, если результат не совпадает с C++. Это в C++ кто-то так подумал и сделал. А мог и не подумать так и, соответственно, не сделать. Поэтому лучше не ссылаться на что-то там, а основываться на какой-то своей внутренней концепции, как должно быть. И желательно, чтобы "свое" было, действительно, своим. А не результатом незаметного навязывания стереотипов "как надо" по мере набирания опыта программирования.

Если своего объяснения нет то значит и ошибки нет. А если через год появится это объяснение и весьма убедительное - то тогда всем все переделывать??? В С++ там уже сто раз подумали почему так, а не иначе. И объяснение требуется если в MQL что то иначе устроено, чем в С++, а не наоборот

 
Alexey Viktorov:
 
Статическая переменная может быть проинициализирована соответствующей ее типу константой или константным выражением, в отличие от простой локальной переменной, которая может быть проинициализирована любым выражением.


Но никак не функцией.

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

 

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

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

void OnStart()
{
  Print(b);
}

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

 
Alexey Navoykov:

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

//+------------------------------------------------------------------+
//|                                                   ExpertMACD.mq5 |
//|                   Copyright 2009-2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
CExpert ExtExpert;

инициализируется функцией-конструктором - запретить!

Это если логически обобщить последние сообщения

Alexey Navoykov:

Обнаружил причину несоответствия.  В режиме OPTIMIZE=0 ошибка есть, а с OPTIMIZE=1 нет.   Я обычно всегда только OPTIMIZE=0 пользуюсь

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

int g1( int& t[] ) { return ArraySize( t ); }
int g2( int& t[] ) { return g1( t ); }
void OnStart()
{
        int t[] = { 1, 2, 3, 4, 5 }; //всего 5
        Print( g2(t)); //Результат:          3
}
 
A100:

инициализируется функцией-конструктором - запретить!

Это если логически обобщить последние сообщения

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


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

 
Alexey Navoykov:
Ясно, тогда прошу прощения, не заметил сразу.  Удивительно конечно, как они успели втихаря это поменять, и ничего никому не сказали.  Тогда не понятно, почему компилятор никак не реагирует на то, что выполняется недопустимая операция.   Т.е. баг в любом случае имеет место
Почему вы думаете что поменяли, почему она недопустимая? Пожалуйста пользуйтесь на своё усмотрение. Вся проблема в том, что при инициализации статической переменной функцией, "приостанавливается" инициализация и выполняется эта функция. А в приведённом примере, в той функции ещё есть статическая переменная которая пока ещё не инициализирована. Отсюда и переменная инициализированная функцией принимает не соответствующее значение.
 
Alexey Navoykov:

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

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

Ну... никакого расхождения с описанием в документации в этом примере НЕТ... Внимательно изучите цитату из документации

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


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

int a= 1;
int b= a+1;

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

 
A100:

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

Обратите внимание на

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

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

Alexey Viktorov, 2017.10.18 09:19

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