From d26b6bf8fa374d8e6829e76456b239a282224d78 Mon Sep 17 00:00:00 2001 From: Philippe Liard Date: Thu, 28 Jun 2012 09:51:00 +0000 Subject: [PATCH] CPP: Remove unused bit_cast() in basictypes.h. This was also causing a compilation error with GCC 4.8. This CL also removes basictypes.h.orig accidentally added in the previous revision. --- cpp/src/base/basictypes.h | 66 ----- tools/cpp/src/base/basictypes.h | 66 ----- tools/cpp/src/base/basictypes.h.orig | 368 --------------------------- 3 files changed, 500 deletions(-) delete mode 100644 tools/cpp/src/base/basictypes.h.orig diff --git a/cpp/src/base/basictypes.h b/cpp/src/base/basictypes.h index 264fd62d2..eec8203ec 100644 --- a/cpp/src/base/basictypes.h +++ b/cpp/src/base/basictypes.h @@ -270,72 +270,6 @@ struct CompileAssert { // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. - -// bit_cast is a template function that implements the -// equivalent of "*reinterpret_cast(&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(f); -// // i = 0x40490fdb -// -// The classical address-casting method is: -// -// // WRONG -// float f = 3.14159265358979; // WRONG -// int i = * reinterpret_cast(&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(&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 -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. - typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1]; - - Dest dest; - memcpy(&dest, &source, sizeof(dest)); - return dest; -} - // Used to explicitly mark the return value of a function as unused. If you are // really sure you don't want to do anything with the return value of a function // that has been marked WARN_UNUSED_RESULT, wrap it with this. Example: diff --git a/tools/cpp/src/base/basictypes.h b/tools/cpp/src/base/basictypes.h index 264fd62d2..eec8203ec 100644 --- a/tools/cpp/src/base/basictypes.h +++ b/tools/cpp/src/base/basictypes.h @@ -270,72 +270,6 @@ struct CompileAssert { // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. - -// bit_cast is a template function that implements the -// equivalent of "*reinterpret_cast(&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(f); -// // i = 0x40490fdb -// -// The classical address-casting method is: -// -// // WRONG -// float f = 3.14159265358979; // WRONG -// int i = * reinterpret_cast(&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(&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 -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. - typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1]; - - Dest dest; - memcpy(&dest, &source, sizeof(dest)); - return dest; -} - // Used to explicitly mark the return value of a function as unused. If you are // really sure you don't want to do anything with the return value of a function // that has been marked WARN_UNUSED_RESULT, wrap it with this. Example: diff --git a/tools/cpp/src/base/basictypes.h.orig b/tools/cpp/src/base/basictypes.h.orig deleted file mode 100644 index e50f3ff2d..000000000 --- a/tools/cpp/src/base/basictypes.h.orig +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BASICTYPES_H_ -#define BASE_BASICTYPES_H_ -#pragma once - -#include // So we can set the bounds of our types -#include // For size_t -#include // for memcpy - -#ifndef COMPILER_MSVC -// stdint.h is part of C99 but MSVC doesn't have it. -#include // For intptr_t. -#endif - -#ifdef INT64_MAX - -// INT64_MAX is defined if C99 stdint.h is included; use the -// native types if available. -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef int64_t int64; -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; - -const uint8 kuint8max = UINT8_MAX; -const uint16 kuint16max = UINT16_MAX; -const uint32 kuint32max = UINT32_MAX; -const uint64 kuint64max = UINT64_MAX; -const int8 kint8min = INT8_MIN; -const int8 kint8max = INT8_MAX; -const int16 kint16min = INT16_MIN; -const int16 kint16max = INT16_MAX; -const int32 kint32min = INT32_MIN; -const int32 kint32max = INT32_MAX; -const int64 kint64min = INT64_MIN; -const int64 kint64max = INT64_MAX; - -#else // !INT64_MAX - -typedef signed char int8; -typedef short int16; -// TODO: Remove these type guards. These are to avoid conflicts with -// obsolete/protypes.h in the Gecko SDK. -#ifndef _INT32 -#define _INT32 -typedef int int32; -#endif - -// The NSPR system headers define 64-bit as |long| when possible. In order to -// not have typedef mismatches, we do the same on LP64. -#if __LP64__ -typedef long int64; -#else -typedef long long int64; -#endif - -// NOTE: unsigned types are DANGEROUS in loops and other arithmetical -// places. Use the signed types unless your variable represents a bit -// pattern (eg a hash value) or you really need the extra bit. Do NOT -// use 'unsigned' to express "this value should always be positive"; -// use assertions for this. - -typedef unsigned char uint8; -typedef unsigned short uint16; -// TODO: Remove these type guards. These are to avoid conflicts with -// obsolete/protypes.h in the Gecko SDK. -#ifndef _UINT32 -#define _UINT32 -typedef unsigned int uint32; -#endif - -// See the comment above about NSPR and 64-bit. -#if __LP64__ -typedef unsigned long uint64; -#else -typedef unsigned long long uint64; -#endif - -#endif // !INT64_MAX - -typedef signed char schar; - -// A type to represent a Unicode code-point value. As of Unicode 4.0, -// such values require up to 21 bits. -// (For type-checking on pointers, make this explicitly signed, -// and it should always be the signed version of whatever int32 is.) -typedef signed int char32; - -// A macro to disallow the copy constructor and operator= functions -// This should be used in the private: declarations for a class -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -// An older, deprecated, politically incorrect name for the above. -// NOTE: The usage of this macro was baned from our code base, but some -// third_party libraries are yet using it. -// TODO(tfarina): Figure out how to fix the usage of this macro in the -// third_party libraries and get rid of it. -#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName) - -// A macro to disallow all the implicit constructors, namely the -// default constructor, copy constructor and operator= functions. -// -// This should be used in the private: declarations for a class -// that wants to prevent anyone from instantiating it. This is -// especially useful for classes containing only static methods. -#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - DISALLOW_COPY_AND_ASSIGN(TypeName) - -// The arraysize(arr) macro returns the # of elements in an array arr. -// The expression is a compile-time constant, and therefore can be -// used in defining new arrays, for example. If you use arraysize on -// a pointer by mistake, you will get a compile-time error. -// -// One caveat is that arraysize() doesn't accept any array of an -// anonymous type or a type defined inside a function. In these rare -// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is -// due to a limitation in C++'s template system. The limitation might -// eventually be removed, but it hasn't happened yet. - -// This template function declaration is used in defining arraysize. -// Note that the function doesn't need an implementation, as we only -// use its type. -template -char (&ArraySizeHelper(T (&array)[N]))[N]; - -// That gcc wants both of these prototypes seems mysterious. VC, for -// its part, can't decide which to use (another mystery). Matching of -// template overloads: the final frontier. -#ifndef _MSC_VER -template -char (&ArraySizeHelper(const T (&array)[N]))[N]; -#endif - -#define arraysize(array) (sizeof(ArraySizeHelper(array))) - -// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize, -// but can be used on anonymous types or types defined inside -// functions. It's less safe than arraysize as it accepts some -// (although not all) pointers. Therefore, you should use arraysize -// whenever possible. -// -// The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type -// size_t. -// -// ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error -// -// "warning: division by zero in ..." -// -// when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer. -// You should only use ARRAYSIZE_UNSAFE on statically allocated arrays. -// -// The following comments are on the implementation details, and can -// be ignored by the users. -// -// ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in -// the array) and sizeof(*(arr)) (the # of bytes in one array -// element). If the former is divisible by the latter, perhaps arr is -// indeed an array, in which case the division result is the # of -// elements in the array. Otherwise, arr cannot possibly be an array, -// and we generate a compiler error to prevent the code from -// compiling. -// -// Since the size of bool is implementation-defined, we need to cast -// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final -// result has type size_t. -// -// This macro is not perfect as it wrongfully accepts certain -// pointers, namely where the pointer size is divisible by the pointee -// size. Since all our code has to go through a 32-bit compiler, -// where a pointer is 4 bytes, this means all pointers to a type whose -// size is 3 or greater than 4 will be (righteously) rejected. - -#define ARRAYSIZE_UNSAFE(a) \ - ((sizeof(a) / sizeof(*(a))) / \ - static_cast(!(sizeof(a) % sizeof(*(a))))) - - -// Use implicit_cast as a safe version of static_cast or const_cast -// for upcasting in the type hierarchy (i.e. casting a pointer to Foo -// to a pointer to SuperclassOfFoo or casting a pointer to Foo to -// a const pointer to Foo). -// When you use implicit_cast, the compiler checks that the cast is safe. -// Such explicit implicit_casts are necessary in surprisingly many -// situations where C++ demands an exact type match instead of an -// argument type convertable to a target type. -// -// The From type can be inferred, so the preferred syntax for using -// implicit_cast is the same as for static_cast etc.: -// -// implicit_cast(expr) -// -// implicit_cast would have been part of the C++ standard library, -// but the proposal was submitted too late. It will probably make -// its way into the language in the future. -template -inline To implicit_cast(From const &f) { - return f; -} - -// The COMPILE_ASSERT macro can be used to verify that a compile time -// expression is true. For example, you could use it to verify the -// size of a static array: -// -// COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES, -// content_type_names_incorrect_size); -// -// or to make sure a struct is smaller than a certain size: -// -// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); -// -// The second argument to the macro is the name of the variable. If -// the expression is false, most compilers will issue a warning/error -// containing the name of the variable. - -template -struct CompileAssert { -}; - -#undef COMPILE_ASSERT -#define COMPILE_ASSERT(expr, msg) \ - typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] - -// Implementation details of COMPILE_ASSERT: -// -// - COMPILE_ASSERT works by defining an array type that has -1 -// elements (and thus is invalid) when the expression is false. -// -// - The simpler definition -// -// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] -// -// does not work, as gcc supports variable-length arrays whose sizes -// are determined at run-time (this is gcc's extension and not part -// of the C++ standard). As a result, gcc fails to reject the -// following code with the simple definition: -// -// int foo; -// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is -// // not a compile-time constant. -// -// - By using the type CompileAssert<(bool(expr))>, we ensures that -// expr is a compile-time constant. (Template arguments must be -// determined at compile-time.) -// -// - The outter parentheses in CompileAssert<(bool(expr))> are necessary -// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written -// -// CompileAssert -// -// instead, these compilers will refuse to compile -// -// COMPILE_ASSERT(5 > 0, some_message); -// -// (They seem to think the ">" in "5 > 0" marks the end of the -// template argument list.) -// -// - The array size is (bool(expr) ? 1 : -1), instead of simply -// -// ((expr) ? 1 : -1). -// -// This is to avoid running into a bug in MS VC 7.1, which -// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. - - -// bit_cast is a template function that implements the -// equivalent of "*reinterpret_cast(&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(f); -// // i = 0x40490fdb -// -// The classical address-casting method is: -// -// // WRONG -// float f = 3.14159265358979; // WRONG -// int i = * reinterpret_cast(&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(&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 -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. - typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1]; - - Dest dest; - memcpy(&dest, &source, sizeof(dest)); - return dest; -} - -// Used to explicitly mark the return value of a function as unused. If you are -// really sure you don't want to do anything with the return value of a function -// that has been marked WARN_UNUSED_RESULT, wrap it with this. Example: -// -// scoped_ptr my_var = ...; -// if (TakeOwnership(my_var.get()) == SUCCESS) -// ignore_result(my_var.release()); -// -template -inline void ignore_result(const T& ignored) { -} - -// 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 -// declare a static instance of the class, provided the constructor is given -// the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a -// static variable that has a constructor or a destructor because invocation -// order is undefined. However, IF the type can be initialized by filling with -// zeroes (which the loader does for static variables), AND the destructor also -// does nothing to the storage, AND there are no virtual methods, then a -// constructor declared as -// explicit MyClass(base::LinkerInitialized x) {} -// and invoked as -// static MyClass my_variable_name(base::LINKER_INITIALIZED); -namespace base { -enum LinkerInitialized { LINKER_INITIALIZED }; -} // base - -#endif // BASE_BASICTYPES_H_