mql5语言的特点、微妙之处以及技巧 - 页 151

 
fxsaber:

静态变量在第一次调用时被初始化。

很难猜测开发者为什么这样做,我认为这是一个错误--在编译时用一个未知的值初始化一个常量变量。

这就是我通常检查什么和何时初始化的方法

//+------------------------------------------------------------------+
void OnStart()
{
   f(333);
   f(2);
}
//+------------------------------------------------------------------+
int init_static()
{
   Print(__FUNCTION__);
   return(1);
}

void f( const int i )
{
  static const int j = init_static();
  
  Print(__FUNCTION__," , j =",j);
}

2019.11.30 11:09:32.456 tst (EURUSD,H1) init_static

2019.11.30 11:09:32.457 tst (EURUSD,H1) f , j =1

2019.11.30 11:09:32.457 tst (EURUSD,H1) f , j =1


在我的例子中,所有的初始化都是正确的,但编译器不允许给常数j进一步赋值--会有一个编译错误。

 
Vladimir Simakov:

问题是,在任何情况下都不值得使用它,因为它是一个概念性错误。

好吧,反正也不值得用,因为这是一个概念性错误。

 
Alexey Navoykov:

好吧,反正你不应该使用它,因为这是一个概念性错误。

但为什么是概念性的?相反,有时你不知道在编译时初始化静态变量的值是多少,在第一次调用时初始化会有帮助。

 
Alexey Navoykov:

好吧,反正不值得用,因为这是一个概念性错误。

实施MVS的C++17。

静态局部变量

在块范围内用指定的static或thread_local (自C++11以来) 声明的变量具有静态或线程 (自C++11以来) 存储期限,但在控制第一次通过其声明时被初始化(除非其初始化为常量初始化,这可以在首次进入块之前执行)。在所有进一步的调用中,该声明被跳过。

如果初始化出现了异常,那么这个变量就不被认为是被初始化了,并且在下一次控制通过声明时将再次尝试初始化。

如果初始化递归地进入到变量被初始化的块中,则行为未被定义。

如果多个线程试图同时初始化同一个静态局部变量,那么初始化就正好发生一次(类似的行为可以通过std::call_once 为任意函数获得)。

注意:该功能的通常实现使用了双重检查锁定模式的变种,它将已经初始化的局部状态的运行时间开销减少到一个非原子布尔比较。

(自C++11以来)

区块范围静态变量的析构器在程序退出时被调用,但只有在初始化成功的情况下。

同一内联函数(可能是隐式内联的)的所有定义中的函数本地静态对象都是指一个翻译单元中定义的同一个对象。

我个人很赞成,如果这样的实现在mql中是合法的,只需要在文档中说明。

 
Vladimir Simakov:

那么,为什么它是概念性的呢?相反,有时你不知道在编译时应该用什么值来初始化一个静态变量,这时第一次调用的初始化就有帮助。

所以我们需要用一个零(默认)的值来初始化。 为什么要用第一个遇到的值来初始化呢? 那么函数的行为就由这个函数的调用顺序决定了,这就产生了一个副作用。而且这是不正确的。如果你想从外部初始化内部结构,你最好使用一个类,而不是一个函数。

然而,我说它不能编译其实是错的。 在C++中,它可以工作,奇怪的是,尽管我从来没有想到要做这样的事情。

 
Alexey Navoykov: 在C++中,它是有效的,奇怪的是,尽管我从来没有想过要这样做。

它一直是这样的,没有概念上的问题,问题是如果它不是这样的话。

void fn() {
   static int i = fn_from_other_cpp();
}

而破坏的顺序严格来说是相反的。

 
Vict:

那里的情况一直是这样,没有概念上的问题,如果不是这样就会有问题。

你的例子有点不同。
 
Slava:

选择 "编辑 "上下文菜单后,导航器无法在与ex5相同的路径中找到原始的mq5。

因为ex5已经从 "共享项目 "移到了scripts文件夹,而mq5就在那里。

将修复它。让我们做一个与测试者设置 中相同的智能搜索

也有一种相反的情况。在Favorites Navigator中,如果缺少ex5(例如,有一个编译错误),就不可能进入mq5-editing(mq5是可用的)。请你也解决这个问题。

 
fxsaber:

也有一种相反的情况。在Favorites Navigator中,如果缺少ex5(例如,有一个编译错误),就不可能切换到mq5-editing(mq5是可用的)。请你也解决这个问题。

2250就可以了。

它已经被匆匆忙忙。2251 - 无法打开mq5。

 
fxsaber:

2250就可以了。

匆匆忙忙的。2251 - 无法打开mq5。

它在那里吗?你有吗?它在哪条路上?

它如何能被复制?