错误、漏洞、问题 - 页 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++中,有人这样想并这样做了。但他们可能没有这样想,因此没有这样做。这就是为什么最好不要参考外面的东西,而是依靠你自己内在的概念,即必须是什么。而这个 "自己的 "应该是真正属于自己的,这才是可取的。而不是在你获得编程经验的过程中不可察觉地强加给你 "应该是这样 "的定型观念的结果。

如果你没有自己的解释,那就意味着没有错误。而如果这个解释在一年后出现,而且相当有说服力,那么大家是不是都要重新做一遍?在C++中,他们已经想了一百次为什么这样做而不是那样做。而如果在MQL中的设置与C++中的设置不同,则需要解释,反之亦然。

 
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;

是由一个构造函数初始化的--禁止!

如果你从逻辑上总结一下最后的帖子,这就是

阿列克谢-纳沃伊科夫

发现了差异的原因。在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;

这种初始化是可能的。因为'a'变量是由一个常数初始化的,而'b'变量是由一个常数表达式初始化的。

 
A100:

那么你需要禁止类的静态实例--因为它们是由构造函数初始化的

请注意

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

虫子,虫子,问题

Alexey Viktorov, 2017.10.18 09:19

为什么你认为你已经改变了,为什么不能接受?请自行决定使用。整个问题是,当一个静态变量 被一个函数初始化 时,初始化被 "暂停",该函数被执行。而在上面的例子中,该函数中仍有一个静态变量尚未被初始化因此,一个被函数初始化的变量会取一个不同的值。
不幸的是,我不知道是否有可能在构造函数中声明和初始化静态变量,但我希望你能告诉我这一点。而且,根据我的理解,初始化顺序是非常重要的。