Idąc za ciosem:
wkleiłem to dziś koło południa: Programistyczne WTF jakie Was spotkały
Okazuje się, że toto cudo techniki wynika z wymogów API. Generalnie kwiat inżynierii kodu znaleziony został w pluginie wczytywanym przez appkę napisaną w Delphi 7.
Ona takiego czegoś oczekuje. W praktyce: do pluginu powinna "wchodzić" tablica (wskaźnk) struktur (pascalowy record po stronie Delphi), plugin ją wypełnia, appka robi sobie z nią dalej co tam chce. No ale nie, appka oczekuje, że zamiast iterowania jak cywilizowany człowiek, będzie przesuwać się o pole len czy inny size w tymże rekordzie/strukturze, (bo optymalizacja miejsca jest ważna. Zwłaszcza pojedynczych bajtów w dobie wielu gigabajtów ramu ;)). Chciałbym to fixnąć, bo doświadczenie podpowiada mi, że to jest błędogenne jak diabli.
Można to połatać na etapie plugina ileś typów wiadomości, odpowiednio potem castować ale to rzeźba ohydna.
I teraz moje pytanie brzmi: w C/C++ takie akcje to jest ewidentny UB. Czy w Pascalu można sobie radośnie tak jeździć po pamięci, czy to po prostu wieloletni fart, że działa? Google nie daje jednoznacznych odpowiedzi, ew. nie do końca wiem gdzie szukać.
Fundamentalne kwestia jest taka: czy to w ogóle jest poprawne, jeżeli Size <> SizeOf(Msg)
Msg := Pointer(LongInt(Msg) + Size); ?
Odpowiednik tego potworka w C++ wyglądałby
struct Header
{
int field1;
int field2;
int size;
};
struct Msg
{
struct Header header;
char payload[0xffff];
};
size_t payload_size = 8;
//dwie wiadomosci
void* buffer = malloc(2* (sizeof(struct Header) + payload_size));
struct Message* msg= buffer;
msg->header.size = payload_size;
msg->payload[0]= 'x';
/... ciach ...
msg->payload[7]= 'z';
sendMsg(msg);
msg = reinterpret_cast<struct Message*>(
reinterpret_cast<int>(msg) + sizeof(struct Header) + payload_size);
msg->header.size = payload_size;
//analogicznie jak wcześniej