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

 
fxsaber :

그것을 알아내고 싶다.

데이터 정렬이 아닙니다

 Print ( sizeof (A)); // 2

분명히 이것은 sizeof() 의 내부 사용을 고려하여 수행됩니다. sizeof()는 물리적 메모리를 고려하지 않고 각 유형을 바이트 단위로 합산합니다.

정렬은 "가져온 dll 함수로 전달하기 위한" 도움말에 기록된 것처럼 실제 메모리에 있는 데이터의 위치입니다. 다른 컴파일러와 언어에서 데이터 유형은 크기가 다를 수 있습니다. 메모리, 따라서 구조의 각 구성원이 "셀 밖으로 크롤링하지 않도록" struct A pack(4)을 사용해야 합니다. - 바이트

기사에서 Habré에 대한 방법은 다음과 같습니다.

 struct Foo
{
     char ch;
     int value ;
};

1바이트: 채널

2바이트: 비어 있음

3바이트: 비어 있음                                          문자 채널;

4바이트: 비어 있음


5바이트: 값[0]

6바이트: 값[1] THIS     정수값;      

7바이트: 값[2]

8바이트: 값[3]


 
Igor Makanu :

분명히 이것은 sizeof() 의 내부 사용을 고려하여 수행됩니다. sizeof()는 물리적 메모리를 고려하지 않고 각 유형을 바이트 단위로 합산합니다.

이것은 사실이 아니다

 struct A pack( 4 )
{
   short j;
   char i;
};

void OnStart ()
{
   Print ( sizeof (A)); // 4
}
 
fxsaber :

이것은 사실이 아니다

그런 다음 귀하의 예제는 sizeof()가 구조의 "가중치"를 바이트 단위로 올바르게 계산했는지 확인했습니다.

물리적 메모리를 확인하는 것만 남아 있지만 제 생각에는 dll을 호출할 때만 작동합니다. 개발자가 메모리에 데이터 저장을 최적화하지 않았다는 사실은 아닙니다.) - 즉. pack(4)가 코드에서 의도된 목적으로 사용되지 않으면 실행 코드에서 무시될 수 있습니다.

 
Igor Makanu :

그런 다음 귀하의 예제는 sizeof()가 구조의 "가중치"를 바이트 단위로 올바르게 계산했는지 확인했습니다.

그렇다면 정렬이 실제로 어떻게 작동하는가 하는 질문이 생깁니다. 문서와 Habr은 예제와 함께 알고리즘을 공개하지 않았습니다.

이고르 마카누 :

물리적 메모리를 확인하는 것만 남아 있지만 제 생각에는 dll을 호출할 때만 작동합니다. 개발자가 메모리에 데이터 저장을 최적화하지 않았다는 사실은 아닙니다.) - 즉. pack(4)가 코드에서 의도된 목적으로 사용되지 않으면 실행 코드에서 무시될 수 있습니다.

물리적 메모리도 마찬가지입니다.
 struct A pack( 4 )
{
   short j;
   char i;
};

void OnStart ()
{
   Print ( sizeof (A)); // 4
  
   const int handle = FileOpen ( __FILE__ , FILE_WRITE | FILE_BIN );
  
   if (handle != INVALID_HANDLE )
  {
    A a = { 0 };
    
     FileWriteStruct (handle, a);
     Print ( FileTell (handle)); // 4
    
     FileClose (handle);
  }
}
 
fxsaber :

그렇다면 정렬이 실제로 어떻게 작동하는가 하는 질문이 생깁니다. 문서와 Habr은 예제와 함께 알고리즘을 공개하지 않았습니다.

그것은 모두 특정 컴파일러에 따라 다르며, 아마도 pack( 4 ) 을 사용할 때 데이터가 어떻게 저장되었는지 보기 위해 유니온에서 MQL을 시도할 수 있습니다.

 
Igor Makanu :

그것은 모두 특정 컴파일러에 따라 다르며, 아마도 pack( 4 ) 을 사용할 때 데이터가 어떻게 저장되었는지 보기 위해 유니온에서 MQL을 시도할 수 있습니다.

offsetof 및 이를 수행하는 다른 방법이 있습니다.


ZY 정렬 작업이 명확성을 제공하는 것으로 나타났습니다. 하지만 내 자신을 위한 것이 아닙니다. 글쎄, 메모리 소비와 분명히 성능은 필드의 순서에 달려 있음을 분명히 알 수 있습니다.

 
fxsaber :

ZY 정렬 작업이 명확성을 제공하는 것으로 나타났습니다. 하지만 내 자신을 위한 것이 아닙니다.

이것은 " 모든 것이 특정 컴파일러에 따라 다릅니다 "입니다. 개발자는 종종 다른 사람에 비해 개발 성능을 높이기 위해 트릭을 사용합니다. MQL에는 소스 코드 최적화 비활성화 등과 같은 컴파일러 지시문이 없습니다. - 작업이나 RAM 네이티브 코드 사용의 차이점을 볼 수 없습니다


추신: 파일에 쓰는 예제가 항상 올바르게 작동하는지 확실하지 않습니다. 최근 누군가가 파일에 쓸 때 Win API에서 MQL을 사용한다고 썼습니다. API 기능과의 호환성에 대한 몇 가지 가정이 있을 수 있습니다. 내 추측입니다, 나는 컴파일러 개발자가 아닙니다

[삭제]  
fxsaber :

offsetof 및 이를 수행하는 다른 방법이 있습니다.


ZY 정렬 작업이 명확성을 제공하는 것으로 나타났습니다. 하지만 내 자신을 위한 것이 아닙니다. 글쎄, 당신은 메모리 소비가 필드의 순서에 의존한다는 것을 분명히 알 수 있습니다.

잘못된 장소에서 어딘가를 파고 있습니다. 정렬이 전혀 필요하지 않습니다. 프로세서는 일부 int가 두 개의 캐시 라인에 들어가지 않도록 정렬이 필요합니다. 패딩이 수행되는 장소는 규제되지 않고 컴파일러에 따라 다르므로 외부 세계로 전달할 때 pack()에 의존할 수 없으며 수동 패딩만 사용할 수 있습니다.

 
Vict :

잘못된 장소에서 어딘가를 파고 있습니다. 정렬이 전혀 필요하지 않습니다. 프로세서는 일부 int가 두 개의 캐시 라인에 들어가지 않도록 정렬이 필요합니다. 패딩이 수행되는 장소는 규제되지 않고 컴파일러에 따라 다르므로 외부 세계로 전달할 때 pack()에 의존할 수 없으며 수동 패딩만 사용할 수 있습니다.

분명합니다. 모두 감사합니다.

 
fxsaber :

그것을 알아내고 싶다.

그리고 문서에 명확하게 명시되어 있는 경우 이해해야 할 사항은 무엇입니까?

구조 이름은 식별자(변수 또는 함수 이름)로 사용할 수 없습니다. MQL5 구조 요소는 정렬 없이 서로 뒤따른다는 점을 염두에 두어야 합니다. C++ 언어에서 이러한 표시는 명령어를 사용하여 컴파일러에 만들어집니다.

 #pragma pack( 1 )

그리고 더 아래로...

즉, MQL5에는 정렬이 전혀 없습니다.

Документация по MQL5: Основы языка / Типы данных / Структуры, классы и интерфейсы
Документация по MQL5: Основы языка / Типы данных / Структуры, классы и интерфейсы
  • www.mql5.com
Структура является набором элементов произвольного типа (кроме типа void). Таким образом, структура объединяет логически связанные данные разных типов. Объявление структуры Имя структуры нельзя использовать в качестве идентификатора (имени переменной или функции). Следует иметь ввиду, что в MQL5 элементы структуры следуют непосредственно друг...