forked from boostorg/endian
Add examples.
This commit is contained in:
@ -94,8 +94,17 @@ study
|
|||||||
engineering trade-offs, use <a href="arithmetic.html">endian arithmetic types</a>. They are safe, easy
|
engineering trade-offs, use <a href="arithmetic.html">endian arithmetic types</a>. They are safe, easy
|
||||||
to use, and easy to maintain. Use the
|
to use, and easy to maintain. Use the
|
||||||
<a href="#Anticipating-need"> <i>
|
<a href="#Anticipating-need"> <i>
|
||||||
anticipating need</i></a> design pattern locally around performance hot spots like lengthy loops,
|
anticipating need</i></a> design pattern locally around performance hot spots
|
||||||
if needed. </p>
|
like lengthy loops, if needed.</p>
|
||||||
|
|
||||||
|
<h3><a name="Background">Background</a> </h3>
|
||||||
|
|
||||||
|
<p>A dealing with endianness usually implies a program portability or a data
|
||||||
|
portability requirement, and often both. That means real programs dealing with
|
||||||
|
endianness are usually complex, so the examples shown here would really be
|
||||||
|
written as multiple functions spread across multiple translation units. They
|
||||||
|
would involve interfaces that can not be altered as they are supplied by
|
||||||
|
third-parties or the standard library. </p>
|
||||||
|
|
||||||
<h3><a name="Characteristics">Characteristics</a></h3>
|
<h3><a name="Characteristics">Characteristics</a></h3>
|
||||||
|
|
||||||
@ -111,12 +120,73 @@ alignment requirements.</p>
|
|||||||
types like <code>int</code> or <code>unsigned short</code> to hold values. That
|
types like <code>int</code> or <code>unsigned short</code> to hold values. That
|
||||||
breaks the implicit invariant that the C++ language rules apply. The usual
|
breaks the implicit invariant that the C++ language rules apply. The usual
|
||||||
language rules only apply if the endianness of the object is currently set to the native endianness for the platform. That can
|
language rules only apply if the endianness of the object is currently set to the native endianness for the platform. That can
|
||||||
make it very hard to reason about complex logic flow, and result in difficult to
|
make it very hard to reason about logic flow, and result in difficult to
|
||||||
find bugs.</p>
|
find bugs.</p>
|
||||||
|
|
||||||
|
<p>For example:</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>struct data_t // big endian
|
||||||
|
{
|
||||||
|
int32_t v1; // description ...
|
||||||
|
int32_t v2; // description ...
|
||||||
|
... additional character data members (i.e. non-endian)
|
||||||
|
int32_t v3; // description ...
|
||||||
|
};
|
||||||
|
|
||||||
|
data_t data;
|
||||||
|
|
||||||
|
read(data);
|
||||||
|
big_to_native_inplace(data.v1);
|
||||||
|
big_to_native_inplace(data.v2);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
++v1;
|
||||||
|
third_party::func(data.v2);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
native_to_big_inplace(data.v1);
|
||||||
|
native_to_big_inplace(data.v2);
|
||||||
|
write(data);
|
||||||
|
</pre>
|
||||||
|
<p>The programmer didn't bother to convert <code>data.v3</code> to native
|
||||||
|
endianness because that member isn't used. A later maintainer needs to pass
|
||||||
|
<code>data.v3</code> to the third-party function, so adds <code>third_party::func(data.v3);</code>
|
||||||
|
somewhere deep in the code. This causes a silent failure because the usual
|
||||||
|
invariant that an object of type <code>int32_t</code> holds a value as
|
||||||
|
described by the C++ core language does not apply.</p>
|
||||||
|
</blockquote>
|
||||||
<p><b>Endian buffer and arithmetic types</b> hold values internally as arrays of
|
<p><b>Endian buffer and arithmetic types</b> hold values internally as arrays of
|
||||||
characters with an invariant that the endianness of the array never changes.
|
characters with an invariant that the endianness of the array never changes.
|
||||||
That makes these types easier to use and programs easier to maintain.</p>
|
That makes these types easier to use and programs easier to maintain. </p>
|
||||||
|
<p>Here is the same example, using an endian arithmetic type:</p>
|
||||||
|
<blockquote>
|
||||||
|
<pre>struct data_t
|
||||||
|
{
|
||||||
|
big_int32_t v1; // description ...
|
||||||
|
big_int32_t v2; // description ...
|
||||||
|
... additional character data members (i.e. non-endian)
|
||||||
|
big_int32_t v3; // description ...
|
||||||
|
};
|
||||||
|
|
||||||
|
data_t data;
|
||||||
|
|
||||||
|
read(data);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
++v1;
|
||||||
|
third_party::func(data.v2);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
write(data);
|
||||||
|
</pre>
|
||||||
|
<p>A later maintainer can add <code>third_party::func(data.v3)</code>and it
|
||||||
|
will just-work.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
@ -177,18 +247,18 @@ needed they are often very useful and workarounds are painful. For example,</p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Non-portable code like this:<blockquote>
|
<p>Non-portable code like this:<blockquote>
|
||||||
<p><code>struct S {<br>
|
<pre>struct S {
|
||||||
uint16_t a; // big endian<br>
|
uint16_t a; // big endian
|
||||||
uint32_t b; // big endian<br>
|
uint32_t b; // big endian
|
||||||
} __attribute__ ((packed));</code>
|
} __attribute__ ((packed));</pre>
|
||||||
</p></blockquote>
|
</blockquote>
|
||||||
<p>Can be replaced with portable code like this:</p>
|
<p>Can be replaced with portable code like this:</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><code>struct S {<br>
|
<pre>struct S {
|
||||||
big_uint16_ut a;<br>
|
big_uint16_ut a;
|
||||||
big_uint32_ut b;<br>
|
big_uint32_ut b;
|
||||||
};</code>
|
};</pre>
|
||||||
</p></blockquote>
|
</blockquote>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@ -293,7 +363,7 @@ arithmetic approach</a>.</p>
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Last revised:
|
<p>Last revised:
|
||||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->02 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38888" --></p>
|
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->03 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38890" --></p>
|
||||||
<p>© Copyright Beman Dawes, 2011, 2013, 2014</p>
|
<p>© Copyright Beman Dawes, 2011, 2013, 2014</p>
|
||||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>
|
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>
|
||||||
|
Reference in New Issue
Block a user