Zagadka
Wysłany dnia 24 września 2011 o godzinie 00:07. Komentarzy: 2, kategorie: Natywne, tagi: .

Pisząc kolejny projekt, miałem sobie oto taki kod:

return
	this->Send(&msgSize, sizeof(MessageSizeType)) +
	this->Send(&catLength, sizeof(MessageCatLengthType)) +
	this->Send(category.c_str(), catLength * sizeof(wchar_t)) +
	this->Send(msg.c_str(), msg.length() * sizeof(wchar_t));

Nie wydaje mi się bardzo skomplikowany. Powinno wystarczyć, gdy zaznaczę, że wysyła on jedną „wiadomość” przez sieć – ot, 5 pierwszych bajtów to nagłówek(MessageSizeType – unsigned, MessageCatLengthType – unsigned char) a reszta dane. Oczywiście MUSZĄ być one dostarczone wszystkie, w takiej kolejności w jakiej są, więc wszystko leci po TCP. Pytanie: co tu jest źle?

Błędne jest… dodawanie! Tak, to znaczek „+” dość znacznie uprzykrzał mi życie od pewnego czasu. Wszystko było ok., gdy kompilowałem projekt w trybie DEBUG, gdy przełączałem na RELEASE loterią(przynajmniej wtedy dla mnie) było, czy zadziała, czy nie. Był to jeden z dziwniejszych „błędów”, jakie popełniłem. Co się okazało? Kompilator, w ramach „optymalizacji”(ktoś wytłumaczy mi, jakie to optymalizacje?), przestawiał poszczególne wywołania Send jak mu się to podobało. Efektem były „dzikie” dane, które odbierałem z drugiej strony.

Rozwiązanie:

int totalSend = this->Send(&msgSize, sizeof(MessageSizeType));
totalSend    += this->Send(&catLength, sizeof(MessageCatLengthType));
totalSend    += this->Send(category.c_str(), catLength * sizeof(wchar_t));
totalSend    += this->Send(msg.c_str(), msg.length() * sizeof(wchar_t));
return totalSend;

Wniosek? Nigdy, ale to NIGDY, nie upraszczaj sobie kodu w ten sposób – lepiej dodać tą jedną zmienną, która i tak nie wprowadza żadnego narzutu i mieć pewność, że wszystko zostanie wywołane w takiej kolejności, jak być powinno, niż głowić się później „co tu jest źle”.

  • qwerty
    Wysłany dnia 24 września 2011 o godzinie 00:21

    Dodawanie jest przemienne, a kompilator ma do tego prawo ;) Podobny przykład: http://www.gimpel.com/html/newbugs/bug864.htm

    Odpowiedz
    • Wysłany dnia 24 września 2011 o godzinie 00:54

      Ależ ja wiem, że dodawanie jest przemienne – ale jaki jest sens w tym konkretnym przypadku? ;) Dzięki za link.

      Odpowiedz
Dodaj komentarz

XHTML: Możesz użyć: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>