Errors, bugs, questions - page 2499

 
fxsaber:

I would like to get to the bottom of this.

data alignment is not

Print(sizeof(A)); // 2

apparently this is done considering the internal use of sizeof() , i.e.sizeof() does not consider physical memory, it simply sums up each type in bytes

alignment is an arrangement of data in physical memory, as written in the help "to transfer to the imported dll-functions" - in different compilers and languages data types may differ in size or rather how they are stored in memory, so you need to use struct A pack(4), so eachmember of the structure "did not climb beyond its box" - bytes

Here's how it looks like on the hubra in the article:

struct Foo
{
    char ch;
    int value;
};

1 byte: ch

2 byte: empty

3 byte: emptyTHIS ischar ch

4 byte: empty


5 byte: value[0]

6 byte: value[1]THIS isint value;

7 byte: value[2]

8 byte: value[3]


 
Igor Makanu:

apparently this is done to accommodate the internal use of sizeof() , i.e.sizeof() does not take physical memory into account, it just sums up each type in bytes

It does not.

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

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

This is not the case.

then your example checked that sizeof() correctly counted "weight" of the structure in bytes,

the only thing left to check is physical memory, but in my opinion it will only work when calling dll, not the fact that developers have not over-optimized data storage in memory ;) - i.e. if pack(4) is not used as intended in the code, it may be ignored in the executable code

 
Igor Makanu:

then your example checked that sizeof() correctly counts the "weight" of the structure in bytes

That's why the question arises: how does alignment actually work? The documentation and Habr have not disclosed the algorithm with their examples.

Igor Makanu:

The only thing left to check is physical memory, but in my opinion it will only work when calling dll, not the fact that developers did not over-optimize data storage in memory ;) - i.e. if pack(4) is not used as intended in the code, it may be ignored in the executable code

The physical memory is similar.
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:

This begs the question, how does alignment actually work? The documentation and hubr have not disclosed the algorithm with their examples.

it depends on the specific compiler, maybe in MQL you can try union to see how the data was saved when usingpack(4)

 
Igor Makanu:

it depends on the specific compiler, you can probably try to look in union in MQL to see how the data was saved when using pack(4)

There are offsetof and other ways to do it.


HH It turns out that setting an alignment serves to make it unambiguous. But not for own use. Well, and it's clearly seen that the order of fields affects memory consumption and, apparently, performance.

 
fxsaber:

HH It turns out that the alignment setting serves to make it unambiguous. But not for own use.

and this is"it all depends on the specific compiler" - developers often go for tricks to improve performance of their developments relative to others, there are no compiler directives in MQL - like disabling source code optimization, etc. - you cannot see the difference in performance or RAM usage of the native code


SZZ: I'm not sure that the example with writing to file always works correctly, someone recently wrote that MQL use Win API when writing to file, there may be some assumptions made for compatibility with API functions - but that's my guess, I'm not a compiler developer (((

 
fxsaber:

There are other ways to do this.


It turns out that setting an alignment serves to make it unambiguous. But not for own use. And you can see that the order of the fields affects memory consumption.

You are digging somewhere wrong, alignment is not needed for you at all, it is needed for processor not to get some int on two cache-lines. The place where the fetching will be done is not regulated and depends on the compiler, so you cannot rely on pack() when transferring to the outside world, only manual fetching.

 
Vict:

You are digging somewhere wrong, alignment is not necessary for you at all, it is necessary for processor not to get some int on two cache-lines. The place in which the add is made is not regulated and depends on the compiler, so you can't rely on pack() when transferring to the outside world, only manual add.

It became clear, thank you all.

 
fxsaber:

I want to get to the bottom of it.

What is there to figure out if the documentation clearly says

The structure name cannot be used as an identifier (a variable or function name). Please note that in MQL5 the elements of a structure follow each other directly , without alignment. In C++, such indication is made to the compiler using the

#pragma  pack(1)

And so on...

So, there is no alignment at all in MQL5.

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