Особенности языка mql5, тонкости и приёмы работы - страница 202

 
Комментарии, не относящиеся к этой теме, были перенесены в "Вопросы от начинающих MQL5 MT5 MetaTrader 5".
 

Штатные функции получают аргументы слева направо.

Пользовательские - справа налево.

double f1()
{
  Print(__FUNCSIG__);
  
  return(0);
}

double f2()
{
  Print(__FUNCSIG__);
  
  return(0);
}

void Func( double, double )
{
}

#define PRINT(A) Print(#A); A

void OnStart()
{  
  PRINT(MathMin(f1(), f2()));
  
  PRINT(Func(f1(), f2()));
}


Результат.

        MathMin(f1(),f2())
        double f1()
        double f2()
        Func(f1(),f2())
        double f2()
        double f1()


Так задумано?

 
fxsaber:

Так задумано?

Это UB на который нельзя опираться. Т.е. надо явно избегать ситуций, когда логика программы зависит от порядка вычисления аргументов

 
fxsaber:

Штатные функции получают аргументы слева направо.

Вот опровергающий пример:

string f1() { Print(1); return NULL; }
string f2() { Print(2); return NULL; }
void OnStart()
{
    StringCompare(f1(), f2());
}

Результат: 2 1

 
Andrei Trukhanovich:

Это UB на который нельзя опираться. Т.е. надо явно избегать ситуций, когда логика программы зависит от порядка вычисления аргументов

A100:

Вот опровергающий пример:

Получается, что со штатными все нестабильно. С пользовательскими - однозначно с самого начала.

 
fxsaber:

Получается, что со штатными все нестабильно. С пользовательскими - однозначно с самого начала.

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

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

я в свое время предлагал ввести ключевое слово inline для безопасного использования порядка вычислений:

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

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

A100, 2017.10.05 14:30

Это лишний раз свидетельствует о пользе ключевого слова С++ inline (здесь было мнение что оно якобы устаревшее).
Помимо прочего inline фактически означает отказ программиста от использования порядка вычисления параметров функции и если компилятор решит сделать inline функцию встраиваемой, то компилятор может использовать прямой порядок вычисления как более эффективный (обратный порядок вычисления очевидно эффективен только для вызываемых функций).
В то же время если компилятор решит сделать встраиваемой не inline функцию то он должен использовать (общий) обратный порядок вычисления даже если это ведет к потере эффективности (потому что программист заложился на это порядок не объявив функцию inline)

inline был бы к месту и в MQL, где порядком вычисления нельзя управлять явно


 
A100:

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

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

я в свое время предлагал ввести ключевое слово inline для безопасного использования порядка вычислений:

Спасибо за разъяснение, про инлайн не подумал.

__forceinline void Func( double, double )

Такой вариант не влияет на результат.

 
fxsaber:

Спасибо за разъяснение, про инлайн не подумал.

Такой вариант не влияет на результат.

Сейчас не влияет, потому что в MQL сейчас его как бы и нет

#define inline

а в будущем его могут наполнить реальным смыслом, иначе зачем его вводить было

 
A100:

Сейчас не влияет, потому что в MQL сейчас его как бы и нет

а в будущем его могут наполнить реальным смыслом, иначе зачем его вводить было

Насколько помню из справки к версии, ввели как заглушку, что бы можно было *.h файлы инлайнить.

 
Что касается порядка вызова функций, возврат которых передается в качестве аргументов функции, то стандарт c++ не накладывает на компилятор требований по порядку их расчета, они могут быть вызваны в любой последовательности (https://en.cppreference.com/w/cpp/language/eval_order). Насколько аналогия применима к mql - вопрос уже к разработчикам, могли и определить, а могли и не заморачиваться.
Причина обращения: