再见,机器人--你好,沼泽地。 - 页 8

 
simpleton:

局部变量和参数在同一个作用域中,所以--参数有这个名字或局部变量并不重要,但无论怎样,这个名字都会在外部作用域中隐藏。

在任何情况下都不会。当通过引用传递一个变量时,不会创建本地拷贝,工作直接在传递的变量上进行。那么,这里到底发生了什么样的隐藏?
 
Andrei01:
不在任何职能部门。当变量通过引用传递时,不会创建一个本地拷贝,而是直接对传递的变量进行操作。那么,这里到底发生了什么隐藏?

这就是隐藏名字的地方。其他一切--复制,不复制--都是次要的。在一个函数中,当使用引用名称时,工作将在引用所指的对象上完成。如果它指的是外层作用域中的一个对象,那么工作将由它来完成。这并不是因为没有名称隐藏--隐藏是存在的,就像在其他情况下一样--而是因为引用指向了这个对象。一个函数是这样调用的。通过引用传递给这个对象,现在它指向了它。当在调用另一个对象的时候调用和传递,同样的函数代码会对另一个对象起作用。

我举了一个有类型名称和变量名称的例子,即有尽可能不同性质的实体,以表明隐藏适用于/参考于名称,其他都是次要的。

然而,当我试图在MQL4++中就这个主题创建另一个例子时,我意外地发现,在MQL4++中为参数创建了一个额外的范围。本地变量的范围 已经嵌套在其中。

#property strict

void f(int a) {
  int saved = a;
  int a = a + 1;

  Print("saved = " , saved, ", a = ", a);
}

void OnStart() {
  f(3);
}

这个例子是用一个典型的警告来汇编的。

declaration of 'a' hides local declaration at line 3    3.mq4   5       7

后来它被成功执行。

23:52:22 Script 3 EURUSDm,H1: loaded successfully
23:52:22 3 EURUSDm,H1: initialized
23:52:22 3 EURUSDm,H1: saved = 3, a = 4
23:52:22 3 EURUSDm,H1: uninit reason 0
23:52:22 Script 3 EURUSDm,H1: removed

很明显,在MQL4++中为参数创建了另一个 "层 "范围。这就是为什么可以声明一个与参数同名的局部变量。

在C/C++中,不存在这样的 "层"。

void f(int a) {
  int saved = a;
  int a = a + 1;
}

编译器通俗地解释说,在作用域中已经有一个具有该名称的变量。

$ icpc -c 1.cpp
1.cpp(3): error: "a" has already been declared in the current scope
    int a = a + 1;
        ^

也就是说,函数参数的范围和它的局部变量是同一个。

为什么在MQL4++中不是这样,以及为什么不是这样--当然,这是一个有趣的问题。

 
simpleton:

void f(int a)

这个例子在COMPILES时有一个特有的警告。

这个案例讨论的是通过引用传递变量和错误的警告的情况,而不是创建一个本地拷贝。

void f(int& a)
 

我只读了前几个帖子。

当然,垫子下面的事情也不太顺利。这里的开发人员在测试到达最终用户的产品方面有一些失误。然而,MT4在多货币策略方面也不强(测试),需要,需要完善。所以我希望它毕竟会有一天。

如果你不知道如何编程,就不要去看真实的,暂时使用演示。像往常一样,一个糟糕的舞者挡住了 "球 "的去路,包括金色和粉色。

好运!


 
Andrei01:

这是一个通过引用传递变量的案例,也是一个错误的警告,不是创建一个本地拷贝。

void f(int& a)

就警告的性质而言,这其实并不重要。此外,不仅一个变量是通过引用还是通过值传递,而且它是什么类型也不重要。

#property strict

int a; // line 3
class A { };
void f(A *&a) { } // line 5
void OnStart() { }

代码编译后,产生了你所讨论的警告。

declaration of 'a' hides global declaration at line 3   3.mq4   5       12

出于某种原因,你不想理解这一点。

该警告本身并没有任何问题。此外,一目了然,与其他事情的做法相比,MQL4++中的范围跟踪做得出奇的好。

警告虽然是真的,但并不实用,而你却不能把它们关掉--这就是它的意义所在。而决不是传输的环节。

 
simpleton:

就警告的性质而言,这是不相关的。此外,变量是通过引用还是通过值传递并不重要

在函数中传递变量本身并对其进行修改,与创建一个副本,而变量本身保持不变,这两者之间在警告的本质上有很大区别。

而事实上,这些警告不能被禁用或定制,这是一个经典的MC专有风格--"不要让":))你对此无能为力,只能谦卑温顺地接受,因为这种风格已被提升到宗教属性的地位......。在这里寻找逻辑或任何形式的正义都没有意义。))

 

我把所有的元宝级的东西都像时钟一样工作了。

完全没有抱怨。

 
simpleton:

潜在的错误就是这样,潜在的错误根本不一定就是错误。因此,"这意味着我们必须修正这些错误 "的说法是错误的,因为它们可能根本就不是错误。

...

这些人是极客。这样的呆子像风车一样与编译器对抗,不明白主要的事情:编译器是你的盟友!当编译器对潜在的不安全代码片段发誓时,就会感到高兴。即使应用程序在启动后立即以错误字符串崩溃,也会感到高兴。但上帝保佑,当没有错误或警告时,你会得到一个无法管理的代码,程序似乎工作得很好,但不时出现奇怪的故障,其原因无法追踪到任何地方。在这样的时刻,你会被水汽覆盖,并开始梦想着"无效指针"或 "除以零 "等错误。
 
C-4:
但上帝保佑,当没有错误或警告时,你会得到一个无法管理的代码,程序似乎工作得很好,但不时出现奇怪的错误,其原因在哪里都找不到。在这样的时刻,你会被水汽覆盖,并开始梦想着 "无效指针 "或 "除以零 "等错误。

编译器与此无关,这是典型的错误写作,当危险的代码片段中没有测试检查,其中可能出现未定义或错误的状态,这就是小毛病出现的原因。

功能性代码检查与编译器无关,从一开始就期望这样做是没有意义的。

同样专业的程序员通常不看警告,因为他们知道编译器的逻辑,而编译器在检查代码功能方面是无用的。

 
Andrei01:

传递变量本身和在函数中修改它,以及对它进行复制,而变量本身保持不变,这在本质上是有很大区别的警告。

这里只是一种不同类型的警告。关于隐藏姓名。

变量本身没有被传递。一个对它的引用被传递。