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:

事实证明,用标准的一切是不稳定的。对于定制的,从一开始就毫不含糊。

不同的是,有常规函数(从右到左)和内联函数(未定义顺序)。

内联函数根本就不是函数,即它们不能有地址。从这个角度看,常规函数和自定义函数之间没有区别,所以,例如,不清楚为什么最简单的自定义函数(本质上是内联的)的参数总是从右向左计算。我不排除将来内联函数的顺序可能会改变,所以

我曾一度建议引入一个内联关键字来安全使用计算顺序。

关于交易、自动交易系统和交易策略测试的论坛

错误、漏洞、问题

A100, 2017.10.05 14:30

这再一次证明了C++内联关键字的有用性(这里有一种观点认为它应该是过时的)。
其中,内联实际上意味着程序员不使用函数参数的计算顺序,如果编译器决定让内联函数内联,那么编译器可以使用正向计算顺序,因为它更有效率(反向计算顺序显然只对被调用函数有效)。
同时,如果编译器决定嵌入一个非内联函数,它应该使用(一般)相反的评估顺序,即使这导致了效率的损失(因为程序员在没有声明该函数为内联函数的情况下假设了这个顺序)。

inline在MQL中也是合适的,因为在MQL中计算顺序不能被明确控制


 
A100:

不同的是,有普通函数(从右到左)和内联函数(未定义顺序)。

内联函数根本就不是函数,即它们不能有地址。从这个角度看,常规函数和自定义函数之间没有区别,所以,例如,不清楚为什么最简单的自定义函数(本质上是内联的)的参数总是从右向左计算。我不排除将来内联函数的顺序可能会改变,所以

我曾一度建议引入一个内联关键字来安全使用计算顺序。

谢谢你的澄清,我没有想到内联的问题。

__forceinline void Func( double, double )

这样的选项并不影响结果。

 
fxsaber:

谢谢你的澄清,我没有想到内联 的问题。

这个选项不影响结果。

它现在没有效果,因为它在MQL中不存在。

#define inline

而在未来,它可能有真正的意义,否则为什么要引入它?

 
A100:

它现在没有影响,因为在MQL中,它现在有点不存在。

而在未来,它可能有一个真正的意义,否则为什么会被引入?

据我在版本帮助中的记忆,它是作为一个存根引入的,允许内联*.h文件。

 
至于调用其返回值作为参数传递给函数的顺序,c++标准并没有对编译器的计算顺序提出要求,它们可以以任何顺序被调用(https://en.cppreference.com/w/cpp/language/eval_order)。这个类比如何适用于mql是由开发者决定的,他们可能会也可能不会费心去定义它。