오류, 버그, 질문 - 페이지 417

 
joo :

예, return()에서 무언가를 반환해야 하는 경우.

또는 적어도 컴파일러가 함수가 무언가를 반환할 것이라고 확신할 수 있도록:

이것은 사실뿐만 아니라
 switch

그러나 일반적으로 void를 제외한 모든 기능에 대해

이 코드를 컴파일해 보세요.

 //+----------------------------------------------------------------------------+
//|                                                                  Scale.mqh |
//|                                             Copyright © 2010, JQS aka Joo. |
//|                                           http://www.mql4.com/ru/users/joo |
//|                                        https://www.mql5.com/ru/users/joo |
//——————————————————————————————————————————————————————————————————————————————
double Scale( double In, double InMIN, double InMAX, double OutMIN, double OutMAX)
{
   if (OutMIN==OutMAX)
     return (OutMIN);
   if (InMIN==InMAX)
     return ((OutMIN+OutMAX)/ 2.0 );
   else
  {
     if (In<InMIN)
       return (OutMIN);
     if (In>InMAX)
       return (OutMAX);
     //return(((In-InMIN)*(OutMAX-OutMIN)/(InMAX-InMIN))+OutMIN);
  }
}
//——————————————————————————————————————————————————————————————————————————————

컴파일하지 않습니다.

이제 주석을 제거하십시오.

 //return(((In-InMIN)*(OutMAX-OutMIN)/(InMAX-InMIN))+OutMIN);

그리고 기적이 일어날 것입니다! :)

[삭제]  
Yedelkin :

핸드북에 따르면 bool은 정수와 다른 특수 유형입니다. 따라서 잘못된 설명을 제거했습니다. 나는 논쟁하지 않을 것이지만 - 특별하지는 않습니다.

케이스 레이블이 아니라 열거(bool 유형을 가장 작은 것으로 간주)를 의미했습니다. 다음은 동일한 컴파일 오류가 있는 예입니다.

따라서이 예와 관련하여 질문을 반복하겠습니다. 컴파일러가 Triple 열거의 값 목록과 총 수를 고려하지 않는다는 말입니까? switch 문에 사용된 열거형의 모든 값이 있습니다.

컴파일러(개발자)는 내가 이해한 대로 재보험됩니다. 결론은 변수가 명시적으로 초기화되지 않은 경우 유형에 따라 false / 0 값이 할당된다는 것입니다(두 번째는 열거에 적용됨).

그러나 가능한 옵션의 한계를 넘어서는 값이 매개변수로 주어지면(Triple의 예에서는 -1 - +1 범위에 속하지 않는 모든 값일 수 있음) 실행할 때 심각한 문제가 발생합니다. 기본 결과 없이.

 
Interesting :

기본 옵션이 제외된 경우 함수는 무엇을 반환해야 합니까?

ENUM_CHART_MODE 열거형의 마지막 값이라고 생각합니다. 지금 확인하겠습니다.

...M-dy, 잘 안됐어. 다음을 인쇄합니다. ChartMode=ENUM_CHART_MODE::-1
 
Interesting :

컴파일러(개발자)는 내가 이해한 대로 재보험됩니다. 결론은 변수가 명시적으로 초기화되지 않은 경우 유형에 따라 false / 0 값이 할당된다는 것입니다(두 번째는 열거에 적용됨).

그러나 매개변수로 가능한 옵션의 범위를 벗어나는 값이 있는 경우(Triple의 경우 -1 - +1 범위에 속하지 않는 모든 값일 수 있음) 다음과 같은 경우 심각한 문제가 발생합니다. 기본 결과 없이 실행

그것은 정말로 그것에 관한 것이 아닙니다. 내 이전 게시물을 참조하십시오.
[삭제]  
joo :
그것은 정말로 그것에 관한 것이 아닙니다. 내 이전 게시물을 참조하십시오.

예, 컴파일러는 최소한 무언가를 반환할 것이라고 확신해야 합니다. 나는 이것이 합리적인 재보험이라고 생각합니다(특히 예에서 스위치 를 처리할 때 기본값이 있음).

또 다른 것은 값을 반환할 필요가 없는 경우입니다.

 
Yedelkin :

ENUM_CHART_MODE 열거형의 마지막 값이라고 생각합니다. 지금 확인하겠습니다.

...M-dy, 잘 안됐어. 다음을 인쇄합니다. ChartMode=ENUM_CHART_MODE::-1

이러한 모든 복잡성에 대해 자세히 알아보려면 Bjorn Stroustrup, C++를 읽으십시오.

솔직히 말해서 특히 MQL5 문서를 읽지 않았습니다. 저는 그냥 C++처럼 씁니다. 개발자는 이 언어의 표준을 매우 밀접하게 따릅니다.

 

안녕하세요!

빌드 466.

연결이 나타나고 몇 킬로바이트가 다운로드되자마자 터미널이 닫힙니다. 인터넷을 끕니다. 닫히지 않습니다.

/logs/Crash/ 디렉토리에서 파일을 첨부합니다.

문제에 해결책이 있습니까?

감사해요

))는 첨부되어 있지 않습니다. 텍스트는 다음과 같습니다.

시간 : 2011.06.16 10:28 (0:00:11)

프로그램 : 클라이언트 터미널

버전 : 500.466 (2011년 6월 9일)

개정: 32925

OS : Windows 7 Professional 서비스 팩 1(빌드 7601)

프로세서: 2 x AMD Athlon 64 X2 듀얼 코어 프로세서 5000+

메모리 : 1983Mb 중 911개

가상: 1815에서 2047Mb 무료

크래시MD5 : 2219A3BB7215B179256A7E41D40BD511

예외: C0000094 at 007B41B4 NA ~ 00000000


모듈: 00400000 00B96000 terminal.exe(5.0.0.466)

: 6FDC0000 00027000 wlidnsp.dll(7.250.4225.0)


007B41A0:00014 [007B41B4] #22663(터미널.exe)

774D58FC:00C74 [774D6570] strcspn(ntdll.dll)

774D58FC:00CAA [774D65A6] strcspn(ntdll.dll)

74A5DC14:000EC [74A5DD00] func_0x74A5DC14(dbghelp.dll)

74A5E10D:0016E [74A5E27B] SymGetLineFromAddr64(dbghelp.dll)

74A5F73A:0085A [74A5FF94] func_0x74A5F73A(dbghelp.dll)

74A6189C:000D2 [74A6196E] func_0x74A6189C(dbghelp.dll)

74A5F73A:00A54 [74A6018E] func_0x74A5F73A(dbghelp.dll)

74A5DC14:000EC [74A5DD00] func_0x74A5DC14(dbghelp.dll)

74A5E10D:0016E [74A5E27B] SymGetLineFromAddr64(dbghelp.dll)

74A5F73A:0085A [74A5FF94] func_0x74A5F73A(dbghelp.dll)

74A6189C:000D2 [74A6196E] func_0x74A6189C(dbghelp.dll)

74A5F73A:00A54 [74A6018E] func_0x74A5F73A(dbghelp.dll)

774D68C7:000E0 [774D69A7] RtlLogStackBackTrace(ntdll.dll)

774D58FC:004D7 [774D5DD3] strcspn(ntdll.dll)


레지스터: EAX=00000000 EIP=007B41B4 EFLGS=00010246 ES=0023

: EBX=00000000 ESP=0012E2CC EBP=0012E320 FS=003b

: ECX=00000000 ESI=04C74C48 CS=001b GS=0000

: EDX=00000000 EDI=00000007 DS=0023 SS=0023

 

값을 반환하는 함수에서 switch 문을 사용하는 주제를 계속합니다. 어제 잠정 결론을 받았고 "enumeration+switch" 바인딩을 사용할 때 기본 레이블 사용이 필수 되었음을 확인했습니다. 그러나 다음은 이 결론이 반박된 예입니다.

 enum Triple
  {
   err=- 1 ,
   no = 0 ,
   hay= 1
  };
Triple triple_var1,triple_var2;
Triple Test( void )
  {
   switch (triple_var1)
     {
       case   err: return (err);
       case    no: return (no);
       case   hay: return (hay);
       default :
         switch (triple_var2)
           {
             case   err: return (err);
             case    no: return (no);
             case   hay: return (hay);
           }
     }
  }
void OnStart ()
  {
   Test();
  }
여기서 switch 문은 두 번 적용되며, 다시 적용(2단계)하면 기본 레이블이 제외됩니다. 동일한 연산자, 동일한 컴파일러 - 하지만 작동합니다. 컴파일러가 triple_var1 및 triple_var2 변수에서 가비지를 찾을 가능성을 고려하고 동시에 Triple 열거형의 값 목록과 해당 번호를 고려하지 않는다는 가정에서 진행하면 그 이유는 무엇입니까? 컴파일러는 switch 문을 사용하는 두 번째 수준에서 오류를 보고하지 않습니까? 중간 결론/가정이 잘못되었거나 컴파일러가 "첫 번째 수준"에서만 연산자를 검사하도록 제한되어 있습니까? 특히 스위치 (triple_var 2 )에서 레이블을 주석 처리하면 Test() 함수가 void 유형이 아니더라도 여전히 오류 메시지가 표시되지 않습니다.

switch (triple_var 1 ) 문에서 case 레이블 뒤에 switch (triple_var 2 ) 문( 기본 레이블 없음)을 삽입하면 비슷한 결과를 얻을 수 있습니다.

 
Yedelkin :

값을 반환하는 함수에서 switch 문을 사용하는 주제를 계속합니다. 어제 잠정 결론을 받았고 "enumeration+switch" 바인딩을 사용할 때 기본 레이블 사용이 필수 되었음을 확인했습니다. 그러나 다음은 이 결론이 반박된 예입니다.

여기서 switch 문은 두 번 적용되며, 다시 적용(2단계)하면 기본 레이블이 제외됩니다. 동일한 연산자, 동일한 컴파일러 - 하지만 작동합니다. 컴파일러가 triple_var1 및 triple_var2 변수에서 가비지를 찾을 가능성을 고려하고 동시에 Triple 열거형의 값 목록과 해당 번호를 고려하지 않는다는 가정에서 진행하면 그 이유는 무엇입니까? 컴파일러는 switch 문을 사용하는 두 번째 수준에서 오류를 보고하지 않습니까? 중간 결론/가정이 잘못되었거나 컴파일러가 "첫 번째 수준"에서만 연산자를 검사하도록 제한되어 있습니까? 특히 스위치 (triple_var2)에서 레이블/레이블을 주석 처리하면 Test() 함수가 void 유형이 아니지만 여전히 오류 메시지가 표시되지 않습니다.

이것은 우리의 결함입니다. 찾아주셔서 감사합니다. 수정하겠습니다. 오류가 발생합니다.
컴파일 범위를 벗어난 경우 가능한 모든 값을 포함하도록 스위치를 확인합니다.
MQL5의 "기능"으로서 이것이 흥미롭기 때문에 우리는 무엇을 할 수 있을지 생각해 볼 것입니다.
 
버그가 수정되었습니다.
스위치 점검의 "기능"에 대해 논의했지만 올바른/올바른 제어를 구현하는 것은 불가능합니다.
switch 표현식의 값은 무엇이든 될 수 있습니다. 예를 들면 다음과 같습니다.

 enum EV { v1, v2, };

string Test( void )
  {
   switch (EV( 3 ))
     {
       case v1: return ( "v1" );
       case v2: return ( "v2" );
     }
   return ( "oops" );
  }
  
void OnStart ()
  {
   Print (Test());
  }