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