Errori, bug, domande - pagina 2499

 
fxsaber:

Vorrei andare in fondo a questa storia.

l'allineamento dei dati non è

Print(sizeof(A)); // 2

apparentemente questo è fatto considerando l'uso interno di sizeof(), cioèsizeof() non considera la memoria fisica, semplicemente somma ogni tipo in byte

l'allineamento è una disposizione dei dati nella memoria fisica, come scritto nell'aiuto "da trasferire alle funzioni dll importate" - in diversi compilatori e linguaggi i tipi di dati possono differire per dimensioni o piuttosto per come sono memorizzati nella memoria, quindi dovreste usare struct A pack(4), così ognimembro della struttura "non è salito oltre la sua scatola" - byte

Ecco come appare sull'hubra nell'articolo:

struct Foo
{
    char ch;
    int value;
};

1 byte: ch

2 byte: vuoto

3 byte: vuotoQUESTO èchar ch

4 byte: vuoto


5 byte: valore[0]

6 byte: valore[1]QUESTO è unvalore int;

7 byte: valore[2]

8 byte: valore[3]


 
Igor Makanu:

apparentemente questo è fatto per accomodare l'uso interno di sizeof(), cioèsizeof() non tiene conto della memoria fisica, si limita a sommare ogni tipo in byte

Non lo fa.

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

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

Questo non è il caso.

allora il tuo esempio ha controllato che sizeof() contasse correttamente il "peso" della struttura in byte,

l'unica cosa rimasta da controllare è la memoria fisica, ma secondo me funzionerà solo quando si chiama la dll, non il fatto che gli sviluppatori non abbiano sovra-ottimizzato la memorizzazione dei dati in memoria ;) - cioè se pack(4) non è usato come previsto nel codice, può essere ignorato nel codice eseguibile

 
Igor Makanu:

allora il tuo esempio ha controllato che sizeof() conti correttamente il "peso" della struttura in byte

Ecco perché la domanda sorge spontanea: come funziona effettivamente l'allineamento? La documentazione e Habr non hanno rivelato l'algoritmo con i loro esempi.

Igor Makanu:

L'unica cosa rimasta da controllare è la memoria fisica, ma secondo me funzionerà solo quando si chiama la dll, non il fatto che gli sviluppatori non hanno ottimizzato troppo la memorizzazione dei dati in memoria ;) - cioè se pack(4) non è usato come previsto nel codice, può essere ignorato nel codice eseguibile

La memoria fisica è simile.
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:

Questo porta alla domanda: come funziona effettivamente l'allineamento? La documentazione e hubr non hanno rivelato l'algoritmo con i loro esempi.

dipende dal compilatore specifico, forse in MQL si può provare l'unione per vedere come sono stati salvati i dati quando si usapack(4)

 
Igor Makanu:

dipende dal compilatore specifico, probabilmente puoi provare a guardare in union in MQL per vedere come sono stati salvati i dati quando si usa pack(4)

Ci sono offsetof e altri modi per farlo.


HH Si scopre che impostare un allineamento serve a renderlo non ambiguo. Ma non per uso personale. Bene, e si vede chiaramente che l'ordine dei campi influisce sul consumo di memoria e, apparentemente, sulle prestazioni.

 
fxsaber:

Si scopre che l'impostazione dell'allineamento ha lo scopo di dare univocità. Ma non per uso personale.

e questo è"tutto dipende dal compilatore specifico" - gli sviluppatori spesso vanno per trucchi per migliorare le prestazioni dei loro sviluppi rispetto ad altri, non ci sono direttive del compilatore in MQL - come disabilitare l'ottimizzazione del codice sorgente, ecc. - non si può vedere la differenza nelle prestazioni o nell'uso della RAM del codice nativo


SZZ: non sono sicuro che l'esempio con la scrittura su file funzioni sempre correttamente, qualcuno recentemente ha scritto che MQL usa Win API quando scrive su file, ci possono essere alcune supposizioni fatte per la compatibilità con le funzioni API - ma questa è la mia ipotesi, non sono uno sviluppatore di compilatori (((

 
fxsaber:

Ci sono altri modi per farlo.


Si scopre che impostare un allineamento serve a renderlo non ambiguo. Ma non per uso personale. E potete vedere che l'ordine dei campi influisce sul consumo di memoria.

State scavando da qualche parte in modo sbagliato, l'allineamento non è affatto necessario per voi, è necessario per il processore per non ottenere qualche int su due linee di cache. Il luogo in cui il fetching sarà fatto non è regolato e dipende dal compilatore, quindi non si può fare affidamento su pack() quando si trasferisce al mondo esterno, solo sul fetching manuale.

 
Vict:

State scavando da qualche parte in modo sbagliato, l'allineamento non è affatto necessario per voi, è necessario per il processore non ottenere qualche int su due linee di cache. Il luogo in cui viene fatta l'aggiunta non è regolato e dipende dal compilatore, quindi non si può fare affidamento su pack() quando si trasferisce al mondo esterno, solo sull'aggiunta manuale.

È diventato chiaro, grazie a tutti.

 
fxsaber:

Voglio andare in fondo alla questione.

Cosa c'è da capire se la documentazione dice chiaramente

Il nome della struttura non può essere usato come identificatore (un nome di variabile o di funzione). Si noti che in MQL5 gli elementi di una struttura si susseguono direttamente , senza allineamento. In C++, tale indicazione è fatta al compilatore usando l'opzione

#pragma  pack(1)

E così via...

Quindi, non c'è alcun allineamento in MQL5.

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