Bug 888573 - Remove bit_cast; r=Waldo

This commit is contained in:
Ms2ger 2013-07-10 11:54:35 +02:00
parent 343818a218
commit dd8f07a495
2 changed files with 6 additions and 70 deletions

View File

@ -236,72 +236,6 @@ enum Ownership {
TAKE_OWNERSHIP
};
// bit_cast<Dest,Source> is a template function that implements the
// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
// very low-level functions like the protobuf library and fast math
// support.
//
// float f = 3.14159265358979;
// int i = bit_cast<int32_t>(f);
// // i = 0x40490fdb
//
// The classical address-casting method is:
//
// // WRONG
// float f = 3.14159265358979; // WRONG
// int i = * reinterpret_cast<int*>(&f); // WRONG
//
// The address-casting method actually produces undefined behavior
// according to ISO C++ specification section 3.10 -15 -. Roughly, this
// section says: if an object in memory has one type, and a program
// accesses it with a different type, then the result is undefined
// behavior for most values of "different type".
//
// This is true for any cast syntax, either *(int*)&f or
// *reinterpret_cast<int*>(&f). And it is particularly true for
// conversions betweeen integral lvalues and floating-point lvalues.
//
// The purpose of 3.10 -15- is to allow optimizing compilers to assume
// that expressions with different types refer to different memory. gcc
// 4.0.1 has an optimizer that takes advantage of this. So a
// non-conforming program quietly produces wildly incorrect output.
//
// The problem is not the use of reinterpret_cast. The problem is type
// punning: holding an object in memory of one type and reading its bits
// back using a different type.
//
// The C++ standard is more subtle and complex than this, but that
// is the basic idea.
//
// Anyways ...
//
// bit_cast<> calls memcpy() which is blessed by the standard,
// especially by the example in section 3.9 . Also, of course,
// bit_cast<> wraps up the nasty logic in one place.
//
// Fortunately memcpy() is very fast. In optimized mode, with a
// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
// code with the minimal amount of data movement. On a 32-bit system,
// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
// compiles to two loads and two stores.
//
// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
//
// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
// is likely to surprise you.
template <class Dest, class Source>
inline Dest bit_cast(const Source& source) {
// Compile time assertion: sizeof(Dest) == sizeof(Source)
// A compile error here means your Dest and Source have different sizes.
MOZ_STATIC_ASSERT(sizeof(Dest) == sizeof(Source),
"Only bit-cast between identically-sized types!");
Dest dest;
memcpy(&dest, &source, sizeof(dest));
return dest;
}
// The following enum should be used only as a constructor argument to indicate
// that the variable has static storage class, and that the constructor should
// do nothing to its state. It indicates to the reader that it is legal to

View File

@ -46,29 +46,31 @@
#include "base/cpu.h"
#include "base/singleton.h"
#include "base/system_monitor.h"
#include "mozilla/Casting.h"
using base::Time;
using base::TimeDelta;
using base::TimeTicks;
using mozilla::BitwiseCast;
namespace {
// From MSDN, FILETIME "Contains a 64-bit value representing the number of
// 100-nanosecond intervals since January 1, 1601 (UTC)."
int64_t FileTimeToMicroseconds(const FILETIME& ft) {
// Need to bit_cast to fix alignment, then divide by 10 to convert
// Need to BitwiseCast to fix alignment, then divide by 10 to convert
// 100-nanoseconds to milliseconds. This only works on little-endian
// machines.
return bit_cast<int64_t, FILETIME>(ft) / 10;
return BitwiseCast<int64_t>(ft) / 10;
}
void MicrosecondsToFileTime(int64_t us, FILETIME* ft) {
DCHECK(us >= 0) << "Time is less than 0, negative values are not "
"representable in FILETIME";
// Multiply by 10 to convert milliseconds to 100-nanoseconds. Bit_cast will
// Multiply by 10 to convert milliseconds to 100-nanoseconds. BitwiseCast will
// handle alignment problems. This only works on little-endian machines.
*ft = bit_cast<FILETIME, int64_t>(us * 10);
*ft = BitwiseCast<FILETIME>(us * 10);
}
int64_t CurrentWallclockMicroseconds() {