错误、漏洞、问题 - 页 2499

 
fxsaber:

我想弄清楚这个问题。

数据排列不

Print(sizeof(A)); // 2

显然,这是考虑到sizeof()的内部使用,即sizeof()不考虑物理内存,它只是以字节为单位对每个类型进行加总

对齐是物理内存中的数据排列,正如帮助中写到的 "转移到导入的dll-函数"--在不同的编译器和语言中,数据类型的大小可能不同,或者说它们在内存中的存储方式不同,所以你需要使用结构A pack(4),所以结构的 每个成员"没有超出它的盒子"--字节。

以下是文章中Hubra的样子。

struct Foo
{
    char ch;
    int value;
};

1个字节:CH

2字节:空

3字节:空的这个是char ch

4字节:空


5个字节:值[0]

6个字节:value[1]THIS是int值

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:

这就引出了一个问题,对齐工作究竟是如何进行的?文件和hubr没有用他们的例子披露算法。

这取决于具体的编译器,也许在MQL中你可以尝试union,看看在使用pack(4)时数据是如何被保存的

 
Igor Makanu:

这取决于具体的编译器,你也许可以尝试在MQL中查看union,看看在使用pack(4)时,数据是如何保存的

有抵消和其他方法。


HH事实证明,设置排列组合的作用是使其不含糊。但不是为了自己使用。嗯,而且可以清楚地看到,字段的顺序会影响到内存的消耗,显然也会影响到性能。

 
fxsaber:

事实证明,排列组合的设置是为了给人以不含糊的感觉。但不是为了自己使用。

这就是"这一切都取决于具体的编译器" - 开发人员经常使用一些技巧来提高他们开发的产品相对于其他产品的性能,在MQL中没有编译器指令 - 如禁用源代码优化,等等。- 你无法看到本地代码在性能或内存使用上的差异。


SZZ:我不确定写到文件 的例子是否总是正确的,最近有人写道,MQL在写到文件时使用Win API,可能有一些假设是为了与API函数兼容--但这是我的猜测,我不是一个编译器开发者(())。

 
fxsaber:

还有其他方法可以做到这一点。


事实证明,设置排列组合的作用是使其不含糊。但不是为了自己使用。而且你可以看到,字段的顺序会影响内存消耗。

你挖错地方了,对齐对你来说根本不需要,需要的是处理器不要在两个缓存线上得到一些int。取值的地方没有规定,取决于编译器,所以在向外界传输时不能依靠pack(),只能依靠手动取值。

 
Vict:

你挖错地方了,对齐对你来说根本不需要,需要的是处理器不要在两个缓存线上得到一些int。添加的地方没有规定,取决于编译器,所以你在向外界转移时不能依靠pack(),只能依靠手动添加。

它变得清晰了,谢谢大家。

 
fxsaber:

我想弄清楚这个问题。

如果文件中写得很清楚,还有什么可弄清楚的呢?

结构名称不能作为标识符(变量或函数名称)使用。请注意,在MQL5中,结构中的元素直接相互跟随,没有对齐。在C++中,这种指示是用

#pragma  pack(1)

以此类推...

所以,在MQL5中根本没有对齐。

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