Erros, bugs, perguntas - página 2499

 
fxsaber:

Gostaria de chegar ao fundo da questão.

o alinhamento dos dados não é

Print(sizeof(A)); // 2

aparentemente isto é feito considerando o uso interno de sizeof() , ou seja,sizeof() não considera a memória física, simplesmente resume cada tipo em bytes

o alinhamento é uma disposição dos dados na memória física, tal como escrito na ajuda "para transferir para as funções dll importadas" - em diferentes compiladores e línguas os tipos de dados podem diferir em tamanho ou antes como são armazenados na memória, pelo que é necessário utilizar a estrutura A pack(4), pelo que cadamembro da estrutura "não subiu para além da sua caixa" - bytes

Eis como se parece com o hubra no artigo:

struct Foo
{
    char ch;
    int value;
};

1 byte: ch

2 byte: vazio

3 byte: vazioESTE échar ch

4 byte: vazio


5 byte: valor[0]

6 byte: valor[1]ESTE é ovalor int;

7 byte: valor[2]

8 byte: valor[3]


 
Igor Makanu:

aparentemente isto é feito para acomodar a utilização interna de sizeof() , ou seja,sizeof() não tem em conta a memória física, limita-se a resumir cada tipo em bytes

Não o faz.

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

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

Não é este o caso.

então o seu exemplo verificou que o tamanho de() contou correctamente o "peso" da estrutura em bytes,

a única coisa que resta verificar é a memória física, mas na minha opinião só funcionará quando chamar dll, não o facto de os programadores não terem optimizado excessivamente o armazenamento de dados na memória ;) - ou seja, se o pacote(4) não for utilizado como previsto no código, pode ser ignorado no código executável

 
Igor Makanu:

então o seu exemplo verificou que o tamanho de() conta correctamente o "peso" da estrutura em bytes

É por isso que surge a questão: como é que o alinhamento funciona realmente? A documentação e Habr não revelaram o algoritmo com os seus exemplos.

Igor Makanu:

A única coisa que resta verificar é a memória física, mas na minha opinião só funcionará quando chamar dll, não o facto de os programadores não terem optimizado excessivamente o armazenamento de dados na memória ;) - ou seja, se o pacote(4) não for utilizado como previsto no código, pode ser ignorado no código executável

A memória física é semelhante.
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:

Isto levanta a questão, como é que o alinhamento funciona realmente? A documentação e o hubr não revelaram o algoritmo com os seus exemplos.

depende do compilador específico, talvez no MQL se possa tentar a união para ver como os dados foram guardados ao usar opacote(4)

 
Igor Makanu:

depende do compilador específico, pode provavelmente tentar procurar em união em MQL para ver como os dados foram guardados ao usar o pacote(4)

Há formas de o fazer e outras formas.


HH Acontece que a definição do alinhamento serve para o tornar inequívoco. Mas não para uso próprio. Bem, e vê-se claramente que a ordem dos campos afecta o consumo de memória e, aparentemente, o desempenho.

 
fxsaber:

HH Acontece que a configuração do alinhamento serve para dar clareza. Mas não para uso próprio.

e isto é"tudo depende do compilador específico" - os programadores recorrem frequentemente a truques para melhorar o desempenho dos seus desenvolvimentos em relação a outros, não existem directivas de compilação na MQL - como desactivar a optimização do código fonte, etc. - não se pode ver a diferença de desempenho ou utilização de RAM do código nativo


SZZ: Não tenho a certeza se o exemplo com escrever para ficheiro funciona sempre correctamente, alguém escreveu recentemente que a MQL utiliza Win API quando escreve para ficheiro, pode haver algumas suposições feitas para a compatibilidade com funções API - mas esse é o meu palpite, não sou um desenvolvedor de compiladores (((

 
fxsaber:

Existem outras formas de o fazer.


Acontece que a definição de um alinhamento serve para o tornar inequívoco. Mas não para uso próprio. E pode ver que a ordem dos campos afecta o consumo de memória.

Está a escavar num sítio errado, o alinhamento não é de todo necessário para si, é necessário para o processador não ter alguma int em duas linhas de cache. O local onde a busca será feita não está regulamentado e depende do compilador, pelo que não se pode confiar na embalagem() ao transferir para o mundo exterior, apenas na busca manual.

 
Vict:

Está a escavar num sítio errado, o alinhamento não é de todo necessário para si, é necessário que o processador não fique intrigado em duas linhas de cache. O local onde a adição é feita não é regulamentado e depende do compilador, pelo que não se pode confiar no pack() ao transferir para o mundo exterior, apenas adição manual.

Tornou-se claro, obrigado a todos vós.

 
fxsaber:

Quero ir até ao fundo da questão.

O que há para descobrir se a documentação diz claramente

O nome da estrutura não pode ser utilizado como identificador (um nome de variável ou função). É favor notar que na MQL5 os elementos de uma estrutura seguem uns aos outros directamente , sem alinhamento. Em C++, tal indicação é feita ao compilador utilizando o

#pragma  pack(1)

E assim por diante...

Portanto, não há qualquer alinhamento na MQL5.

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