Příběh o tom, že závorky navíc nikdy neuškodí

Dnes jsem se pokoušel implementovat čtení hodnot ushort z little-endian pole bytů. Kód pro čtení jedné hodnoty byl jednoduchý – posunu druhý byte o 8 bitů doleva a přičtu byte první:


var result = (ushort)(data[position + 1] << 8 + data[position]);

Co by se mohlo pokazit?

Ukázlo se, že dost. Kód dával úplně nesprávné výsledky. Tak jsem použil pro kontrolu BitConverter.ToUInt16 a skutečně, hodnoty byly naprosto odlišné. Podíval jsem se tedy na binární notaci výsledků přes kalkulačku a pak mi to došlo. Nevinně vypadající operátor <<nižší prioritu než operátor + (což potvrdila documentace). To znamená, že můj kód nejprve provedl:


8 + data[position]

A až poté posunul byte data[position + 1] o výsledné číslo doleva. Když jsem následně kód upravil jako:


var result = (ushort)((data[position + 1] << 8) + data[position]); //note the additional parentheses

Vše fungovalo dle očekávání. Ponaučení z tohoto příběhu je – kdykoliv váháte, dvě stisknutí kláves se závorkou vás zachrání před matoucí ladící seancí.

PS: Nakonec jsem kód ještě upravil a nahradil + logickým OR, což nejen lépe vystihuje záměr kódu, ale ani by vynchání závorky v tomto případě nemělo fatální důsledky.


var result = (ushort)((data[position + 1] << 8) | data[position]);

Buy me a coffeeBuy me a coffee

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.