굿바이 로봇, 만세 광기 - 페이지 7

 
Renat :
...

이 예를 테스트:

  • MQL4/MQL5 - 잠재적 오류에 대한 경고 제공

  • 코드 분석을 포함한 Visual Studio 2012 - 없음, 잠재적 오류에 대한 분석 품질은 일반적으로 0입니다. 오랫동안 경쟁자가 없기 때문에 그들은 증기 목욕을하지 않습니다.

  • PVS Studio가 올바르게 보고합니다.

  • Lint - 유사하게 출력, 선언 'x' 숨기기...

    ...

파블릭 :

나는 또한 메시지가 완전히 쓸모 없다고 생각합니다. 나는 전문 프로그래머는 아니지만 마이크로 리터의 그런 넌센스는 나를 짜증나게합니다. 흥미롭게도 및 b에 대한 참조가 일정하면 PVS Studio에서 경고를 표시합니다(직접 확인할 방법이 없음)?

그래도 경고의 본질을 먼저 이해하고 나서 그것을 논증으로 인용하는 것도 나쁘지 않다. PVS Studio는 전역 변수 가 숨겨져 있어서가 아니라 및 b가 상수가 아닌 참조로 전달되었지만 수정되지 않았기 때문에 불평합니다. 이 경우, 그들의 의견으로는 a 및 b는 지속적인 참조로 전달되어야 합니다. 예를 들어 다음 예는 이 파서에서 불만을 야기하지 않습니다.

 int a= 1 ,b= 2 ;
int sum( const int & a, const int & b){
         return (a+b);
}

int main(){
         return sum(a,b);
}

//-------------------------------------------------
int a= 1 ,b= 2 ;
int sum( int & a, int & b){
        ++a; ++b;
         return (a+b);
}

int main(){
         return sum(a,b);
}
 

나는 PVS가 무엇을 맹세하는지 완벽하게 알고 있습니다.

다시 말하지만, 수십억 줄의 오래된 C/C++ 코드를 컴파일해야 하는 부담이 없습니다. 이것은 경고를 발행하여 비즈니스를 망치지 않으려고 노력하면서 자체 컴파일러에서 처리해야 합니다. 우리는 돈과 함께 작동하는 우리의 응용 언어의 보안 및 오류 제어에 대한 책임이 있습니다.

맙소사, MQL4/5 코드 작성자의 몇 퍼센트가 (실제 의미에서) 전문 프로그래머입니다. 다른 모든 사람들은 독학으로 코드를 얼마나 잘못 작성했는지 모릅니다.

예를 들어, 업데이트된 MQL4로 전환한 후 우리는 코드 기반에 있는 수천 개의 소스를 수동으로 살펴보고 이전 코드에서 엄청난 수의 오류를 수정해야 했습니다. 프로그램을 실행하지 않고도 컴파일러에 의해 많은 오류가 발견되고 표시되었습니다.

따라서 경고 발생에 대해 주장하지 말고 코드를 수정하십시오.

 
Renat :

나는 PVS가 무엇을 맹세하는지 완벽하게 알고 있습니다.

다시 말하지만, 수십억 줄의 오래된 C/C++ 코드를 컴파일해야 하는 부담이 없습니다. 이것은 경고를 발행하여 비즈니스를 망치지 않으려고 노력하면서 자체 컴파일러에서 처리해야 합니다. 우리는 돈과 함께 작동하는 우리의 응용 언어의 보안 및 오류 제어에 대한 책임이 있습니다.

맙소사, MQL4/5 코드 작성자의 몇 퍼센트가 (실제 의미에서) 전문 프로그래머입니다. 다른 모든 사람들은 독학으로 코드를 얼마나 잘못 작성했는지 모릅니다.

예를 들어, 업데이트된 MQL4로 전환한 후 우리는 코드 기반에 있는 수천 개의 소스를 수동으로 살펴보고 이전 코드에서 엄청난 수의 오류를 수정해야 했습니다. 프로그램을 실행하지 않고도 컴파일러에 의해 많은 오류가 발견되고 표시되었습니다.

따라서 경고 발생에 대해 주장하지 말고 코드를 수정하십시오.


배열이 범위를 벗어나도록 허용되면 표시기를 작성할 때 표시기 자체를 작성하는 데 필요한 노력을 기울이지만 계산의 시작 부분만 계산하는 것은 매우 어리석은 일입니다.

이 코드를 파헤치지 않는 것이 가능합니다. 절반은 수정되지 않았지만 깨졌습니다. 이전 mql4, new 또는 new를 엄격하게 구별하기 위해 추가 속성을 간단하게 만드는 것이 가능했습니다. 이전 컴파일러의 크기는 얼마입니까? 잘 모르겠지만 아마 메가바이트도 안 될 것 같으니 기가바이트 시대에 가지고 다니기에는 무리가 없을 것입니다. 그러나 여기에 코드베이스를 파괴하는 것과 같은 영웅적인 작업이 있습니다.

* * *

경고

'a' 선언은 X 행에서 전역 선언을 숨깁니다.

이것은 어리석은 경고입니다. "상위" 세계의 누군가가 이것에 문제가 있다고 해서 다른 사람들도 그러한 문제를 가질 수 있다는 의미는 아닙니다. 변수의 범위가 있습니다. 변수 이름을 지정하는 방법은 개인 문제입니다.

 
Integer :


배열이 범위를 벗어나도록 허용되면 표시기를 작성할 때 표시기 자체를 작성하는 데 필요한 노력을 기울이지만 계산의 시작 부분만 계산하는 것은 매우 어리석은 일입니다.

이 코드를 파헤치지 않는 것이 가능합니다. 절반은 수정되지 않았지만 깨졌습니다. 이전 mql4, new 또는 new를 엄격하게 구별하기 위해 추가 속성을 간단하게 만드는 것이 가능했습니다. 이전 컴파일러의 크기는 얼마입니까? 잘 모르겠지만 아마 메가바이트도 안 될 것 같으니 기가바이트 시대에 가지고 다니기에는 무리가 없을 것입니다. 그러나 여기에 코드베이스를 파괴하는 것과 같은 영웅적인 작업이 있습니다.

고장이 아닌 고정입니다.

편집 후 오류가 발생하면 가능한 일입니다. 편집하면 필연적으로 이러한 오류가 발생합니다. 그러나 이것이 하나의 오류가 깃발에 매달려 수정 된 오류의 산을 오를 수 있음을 의미하지는 않습니다.


'a' 선언은 X 행에서 전역 선언을 숨깁니다.

이것은 어리석은 경고입니다. "상위" 세계의 누군가가 이것에 문제가 있다고 해서 다른 사람들도 그러한 문제를 가질 수 있다는 의미는 아닙니다. 변수의 범위가 있으며 변수 이름을 지정하는 방법은 개인 문제입니다.

석궁의 권리를 위해 싸우는 놀라운 사람들. 특히 진지한 사람이 "오래된 컴파일러를 떠나십시오"라고 쓰는 것은 기쁘게 생각합니다.
 
simpleton :

잠재적 오류는 잠재적 오류이며 반드시 오류는 아닙니다.

글쎄요. 우리는 경고를 4~5단계로 설정하고 경고를 오류로 간주하는 확인란을 선택하는 릴리스 규칙이 있었습니다.

그들은 프라그마로 정말 어리석은 경고를 제거했지만 어쨌든 제거했습니다.

 
Andrei01 :

이 언급은 의미가 없고 원칙적으로 프로그래머에게 유용한 정보를 제공하지 않습니다. 왜냐하면 언급한 바와 같이 처음에는 여기에 변수 "a"가 숨겨져 있지 않기 때문입니다.

 1 .cpp( 3 ): remark # 3280 : declaration hides variable "a" (declared at line 1 )
   int sum( int & a, int & b){        

프로그래머가 의도적으로 은폐를 사용한다면 - 예, 이 발언은 의미가 없으며 유용한 정보를 전달하지 않습니다. 은폐가 우연히, 부주의로 발생한 경우 이 표시를 통해 초기 단계에서 오류를 감지할 수 있습니다.

Andrei01 :

은닉은 변수의 로컬 복사본이 만들어질 때만 발생하며 이는 완벽하게 합법입니다. 이 숨김으로 인해 갑자기 코드의 오류가 발생하더라도 바로 검색하면 같은 이름을 찾기 때문에 쉽게 정확하게 찾을 수 있습니다. 함수 템플릿에서 이름을 변경하고 맹글링하기 시작하고 이것이 컴파일러의 논리에 따라 정확히 이 설명의 "해결책"이라면 오류를 찾는 상황이 훨씬 더 어려워지고 혼란이 측량할 수 없을 정도로 증가할 것입니다. 코드 이해하기. 분명한 것 같습니다.

지역 변수 와 매개 변수는 같은 범위에 있으므로 매개 변수에 이러한 이름이나 지역 변수가 있는지 여부는 중요하지 않지만 어떤 경우에도 이 이름은 외부 범위에서 이름을 숨깁니다.

숨기기는 변수 복사본과 아무 관련이 없으며 엔터티 이름과 관련이 있습니다. 예, 하지만 유형과 같은 엔터티의 이름은 다음과 같습니다.

 class A { };

void f( int a) {
        A x;
}

이것은 컴파일합니다:

$ icpc -c 1 .cpp
$ 

이:

 class A { };

void f( int A) {
        A x;
}

더 이상:

$ icpc -c 1 .cpp
1 .cpp( 4 ): error: expected a ";"
        A x;
          ^

compilation aborted for 1 .cpp (code 2 )
$ 

함수 내부의 이름 A는 더 이상 유형의 이름이 아니라 매개변수 변수의 이름이기 때문입니다. 외부 범위에서 선언된 유형의 이름은 이제 매개변수 변수의 이름으로 숨겨집니다. 이것은 다음 코드를 통해 간접적으로 확인할 수 있습니다.

 class A { };

void f( int A) {
        A++;
}

꽤 성공적으로 컴파일:

$ icpc -c 1 .cpp
$ 

MQL4++에서는 변수-매개변수 이름으로 유형 이름을 숨기는 단계, 즉 빈 함수 본문이 있는 경우에도 이미 컴파일되지 않습니다.

 #property strict

class A { };
void f( int A) { }
void OnStart () { }

결과:

 'A' - structure identifier cannot be used       3 .mq4   4        12
'A' - structure identifier cannot be used       3 .mq4   4        12

이유는 모르겠지만 전혀 놀라지 않습니다.

C++의 경우 이러한 코드에는 문제가 없습니다.

 class A { };
void f( int A) { }

컴파일 시도 결과:

$ icpc -c 1 .cpp
$ 

이 예에서는 숨기기가 다른 항목이 아닌 엔터티 이름과 관련되어 있음을 보여 줍니다.

그 발언이 비활성화되지 않으면 네, 이름을 맹글링하는 것과 같은 모든 종류의 방법을 발명해야 합니다. 그러나 인텔 컴파일러와 같이 비활성화되어 있으면 그러한 문제가 없습니다.

MQL4++에서 문제는 중첩 범위에서 이름 숨김을 감지하는 컴파일러의 기능에 있는 것이 아니라 이 기능을 원칙적으로 비활성화할 수 없다는 사실에 있습니다.

 
Renat :

따라서 경고 발생에 대해 주장하지 말고 코드를 수정하십시오.

논의 중인 경고/비고에 대한 주장은 기본적으로 단절되지 않는다는 주장이 하나만 있을 수 있다고 생각합니다.

그리고 물론 프로그래머에게 언어 내에서 무엇을 해야 하고 무엇을 하지 말아야 하는지 말할 수는 없습니다.

 

이러한 메시지( 전역 변수 숨기기)는 C++에서 단순히 의미가 없습니다(결국 mql은 C++과 유사하게 선언되었지요?). 예를 들어 이유는 다음과 같습니다.

 struct S1{
     int val;
};

struct S2{};

template<typename _T>
struct SS : _T{
     int f() { int val; return val;}
};

int main(){
    SS<S1> q1; q1.f();
    SS<S2> q2; q2.f();
}
 
Pavlick :

C++에서 이러한 메시지(전역 변수 숨기기)는 단순히 의미가 없습니다(mql은 C++과 유사하게 선언되었지요?). 예를 들어 이유는 다음과 같습니다.

 struct S1{
     int val;
};

struct S2{};

template<typename _T>
struct SS : _T{
     int f() { int val; return val;}
};

int main(){
    SS<S1> q1; q1.f();
    SS<S2> q2; q2.f();
}

MQL4++에는 구조/클래스 템플릿이 없고 함수 템플릿만 있기 때문에 C++를 여기에서 가져왔습니다.

개발자가 이에 대해 알고 있는지 확실하지 않지만 상당한 제한이 있기는 하지만 클래스 템플릿도 MQL4++에서 가능합니다. 특히 이 예제는 다음과 같은 방식으로 MQL4++로 변환될 수 있습니다(또한 로컬 변수 대신 매개변수가 메소드에 사용됨).

 #property strict

struct S1 { };
struct S2 { int val; };

template <typename T>
void f(T &t) {
   struct SS: public T {
     int f( int val) { return val; }
  } ss = { 0 }; // Переменная типа SS
}

void OnStart () {
  S1 s1; f(s1);
  S2 s2; f(s2);
}

컴파일할 때 이름 숨기기에 대한 단일 경고가 나타납니다.

 '3.mq4' 3 .mq4   1        1
struct has no members, size assigned to 1 byte    3 .mq4   3        8
struct has no members, size assigned to 1 byte    3 .mq4   8        10
declaration of 'val' hides member declaration at line 4 3 .mq4   9        15
0 error(s), 3 warning(s)                 1        4

OnStart()에서 마지막 중요한 줄을 주석 처리하면 이름 숨기기에 대한 경고가 사라집니다.

 
simpleton :

MQL4++에는 구조/클래스 템플릿이 없고 함수 템플릿만 있기 때문에 C++를 여기에서 가져왔습니다.

...

일반적으로 예, 하지만 µl당 다음을 수행할 수도 있습니다.

 struct S1{
     int val;
};

struct S2{};

#define INSTANTIATE(_Name, _T)          \
     struct _Name : _T                   \
    {                                   \
         int f() { int val; return val;}; \
    }

INSTANTIATE(SS1, S1);
INSTANTIATE(SS2, S2);

void start(){
    SS1 q1; q1.f();
    SS2 q2; q2.f();
}