Main MRPT website > C++ reference for MRPT 1.9.9
bit_cast.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 // Copyright 2016 The Chromium Authors. All rights reserved.
11 // Use of this source code is governed by a BSD-style license that can be
12 // found in the LICENSE file.
13 #ifndef BASE_BIT_CAST_H_
14 #define BASE_BIT_CAST_H_
15 #include <string.h>
16 #include <type_traits>
17 //#include "base/compiler_specific.h" // mrpt
18 //#include "base/template_util.h" // mrpt
19 //#include "build/build_config.h" // mrpt
20 // bit_cast<Dest,Source> is a template function that implements the equivalent
21 // of "*reinterpret_cast<Dest*>(&source)". We need this in very low-level
22 // functions like the protobuf library and fast math support.
23 //
24 // float f = 3.14159265358979;
25 // int i = bit_cast<int32_t>(f);
26 // // i = 0x40490fdb
27 //
28 // The classical address-casting method is:
29 //
30 // // WRONG
31 // float f = 3.14159265358979; // WRONG
32 // int i = * reinterpret_cast<int*>(&f); // WRONG
33 //
34 // The address-casting method actually produces undefined behavior according to
35 // the ISO C++98 specification, section 3.10 ("basic.lval"), paragraph 15.
36 // (This did not substantially change in C++11.) Roughly, this section says: if
37 // an object in memory has one type, and a program accesses it with a different
38 // type, then the result is undefined behavior for most values of "different
39 // type".
40 //
41 // This is true for any cast syntax, either *(int*)&f or
42 // *reinterpret_cast<int*>(&f). And it is particularly true for conversions
43 // between integral lvalues and floating-point lvalues.
44 //
45 // The purpose of this paragraph is to allow optimizing compilers to assume that
46 // expressions with different types refer to different memory. Compilers are
47 // known to take advantage of this. So a non-conforming program quietly
48 // produces wildly incorrect output.
49 //
50 // The problem is not the use of reinterpret_cast. The problem is type punning:
51 // holding an object in memory of one type and reading its bits back using a
52 // different type.
53 //
54 // The C++ standard is more subtle and complex than this, but that is the basic
55 // idea.
56 //
57 // Anyways ...
58 //
59 // bit_cast<> calls memcpy() which is blessed by the standard, especially by the
60 // example in section 3.9 . Also, of course, bit_cast<> wraps up the nasty
61 // logic in one place.
62 //
63 // Fortunately memcpy() is very fast. In optimized mode, compilers replace
64 // calls to memcpy() with inline object code when the size argument is a
65 // compile-time constant. On a 32-bit system, memcpy(d,s,4) compiles to one
66 // load and one store, and memcpy(d,s,8) compiles to two loads and two stores.
67 template <class Dest, class Source>
68 inline Dest bit_cast(const Source& source)
69 {
70  static_assert(
71  sizeof(Dest) == sizeof(Source),
72  "bit_cast requires source and destination to be the same size");
73  static_assert(
75  "bit_cast requires the destination type to be copyable");
76  static_assert(
78  "bit_cast requires the source type to be copyable");
79  Dest dest;
80  memcpy(&dest, &source, sizeof(dest));
81  return dest;
82 }
83 #endif // BASE_BIT_CAST_H_
bit_cast
Dest bit_cast(const Source &source)
Definition: bit_cast.h:68
source
GLsizei GLsizei GLchar * source
Definition: glext.h:4082
value
GLsizei const GLfloat * value
Definition: glext.h:4117
mrpt::system::os::memcpy
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
Definition: os.cpp:356



Page generated by Doxygen 1.8.17 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at miƩ 12 jul 2023 10:03:34 CEST