Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: base/macros.h

Issue 647753003: Make ARRAYSIZE_UNSAFE() just use arraysize(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added bug Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file contains macros and macro-like constructs (e.g., templates) that 5 // This file contains macros and macro-like constructs (e.g., templates) that
6 // are commonly used throughout Chromium source. (It may also contain things 6 // are commonly used throughout Chromium source. (It may also contain things
7 // that are closely related to things that are commonly used that belong in this 7 // that are closely related to things that are commonly used that belong in this
8 // file.) 8 // file.)
9 9
10 #ifndef BASE_MACROS_H_ 10 #ifndef BASE_MACROS_H_
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 // that wants to prevent anyone from instantiating it. This is 43 // that wants to prevent anyone from instantiating it. This is
44 // especially useful for classes containing only static methods. 44 // especially useful for classes containing only static methods.
45 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 45 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
46 TypeName(); \ 46 TypeName(); \
47 DISALLOW_COPY_AND_ASSIGN(TypeName) 47 DISALLOW_COPY_AND_ASSIGN(TypeName)
48 48
49 // The arraysize(arr) macro returns the # of elements in an array arr. 49 // The arraysize(arr) macro returns the # of elements in an array arr.
50 // The expression is a compile-time constant, and therefore can be 50 // The expression is a compile-time constant, and therefore can be
51 // used in defining new arrays, for example. If you use arraysize on 51 // used in defining new arrays, for example. If you use arraysize on
52 // a pointer by mistake, you will get a compile-time error. 52 // a pointer by mistake, you will get a compile-time error.
53 //
54 // One caveat is that arraysize() doesn't accept any array of an
55 // anonymous type or a type defined inside a function. In these rare
56 // cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is
57 // due to a limitation in C++'s template system. The limitation might
58 // eventually be removed, but it hasn't happened yet.
59 53
60 // This template function declaration is used in defining arraysize. 54 // This template function declaration is used in defining arraysize.
61 // Note that the function doesn't need an implementation, as we only 55 // Note that the function doesn't need an implementation, as we only
62 // use its type. 56 // use its type.
63 template <typename T, size_t N> 57 template <typename T, size_t N>
64 char (&ArraySizeHelper(T (&array)[N]))[N]; 58 char (&ArraySizeHelper(T (&array)[N]))[N];
65 59
66 // That gcc wants both of these prototypes seems mysterious. VC, for 60 // That gcc wants both of these prototypes seems mysterious. VC, for
67 // its part, can't decide which to use (another mystery). Matching of 61 // its part, can't decide which to use (another mystery). Matching of
68 // template overloads: the final frontier. 62 // template overloads: the final frontier.
69 #ifndef _MSC_VER 63 #ifndef _MSC_VER
70 template <typename T, size_t N> 64 template <typename T, size_t N>
71 char (&ArraySizeHelper(const T (&array)[N]))[N]; 65 char (&ArraySizeHelper(const T (&array)[N]))[N];
72 #endif 66 #endif
73 67
74 #define arraysize(array) (sizeof(ArraySizeHelper(array))) 68 #define arraysize(array) (sizeof(ArraySizeHelper(array)))
75 69
76 // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize, 70 // DEPRECATED: Just use |arraysize()|, now that C++11 has removed the
77 // but can be used on anonymous types or types defined inside 71 // limitations that forced the use of |ARRAYSIZE_UNSAFE()|.
78 // functions. It's less safe than arraysize as it accepts some 72 // TODO(viettrungluu): Convert all instances and delete. crbug.com/423134
79 // (although not all) pointers. Therefore, you should use arraysize 73 #define ARRAYSIZE_UNSAFE(a) arraysize(a)
80 // whenever possible.
81 //
82 // The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type
83 // size_t.
84 //
85 // ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error
86 //
87 // "warning: division by zero in ..."
88 //
89 // when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer.
90 // You should only use ARRAYSIZE_UNSAFE on statically allocated arrays.
91 //
92 // The following comments are on the implementation details, and can
93 // be ignored by the users.
94 //
95 // ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in
96 // the array) and sizeof(*(arr)) (the # of bytes in one array
97 // element). If the former is divisible by the latter, perhaps arr is
98 // indeed an array, in which case the division result is the # of
99 // elements in the array. Otherwise, arr cannot possibly be an array,
100 // and we generate a compiler error to prevent the code from
101 // compiling.
102 //
103 // Since the size of bool is implementation-defined, we need to cast
104 // !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
105 // result has type size_t.
106 //
107 // This macro is not perfect as it wrongfully accepts certain
108 // pointers, namely where the pointer size is divisible by the pointee
109 // size. Since all our code has to go through a 32-bit compiler,
110 // where a pointer is 4 bytes, this means all pointers to a type whose
111 // size is 3 or greater than 4 will be (righteously) rejected.
112
113 #define ARRAYSIZE_UNSAFE(a) \
114 ((sizeof(a) / sizeof(*(a))) / \
115 static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
116 74
117 75
118 // Use implicit_cast as a safe version of static_cast or const_cast 76 // Use implicit_cast as a safe version of static_cast or const_cast
119 // for upcasting in the type hierarchy (i.e. casting a pointer to Foo 77 // for upcasting in the type hierarchy (i.e. casting a pointer to Foo
120 // to a pointer to SuperclassOfFoo or casting a pointer to Foo to 78 // to a pointer to SuperclassOfFoo or casting a pointer to Foo to
121 // a const pointer to Foo). 79 // a const pointer to Foo).
122 // When you use implicit_cast, the compiler checks that the cast is safe. 80 // When you use implicit_cast, the compiler checks that the cast is safe.
123 // Such explicit implicit_casts are necessary in surprisingly many 81 // Such explicit implicit_casts are necessary in surprisingly many
124 // situations where C++ demands an exact type match instead of an 82 // situations where C++ demands an exact type match instead of an
125 // argument type convertible to a target type. 83 // argument type convertible to a target type.
126 // 84 //
127 // The From type can be inferred, so the preferred syntax for using 85 // The From type can be inferred, so the preferred syntax for using
128 // implicit_cast is the same as for static_cast etc.: 86 // implicit_cast is the same as for static_cast etc.:
129 // 87 //
130 // implicit_cast<ToType>(expr) 88 // implicit_cast<ToType>(expr)
131 // 89 //
132 // implicit_cast would have been part of the C++ standard library, 90 // implicit_cast would have been part of the C++ standard library,
133 // but the proposal was submitted too late. It will probably make 91 // but the proposal was submitted too late. It will probably make
134 // its way into the language in the future. 92 // its way into the language in the future.
135 template<typename To, typename From> 93 template<typename To, typename From>
136 inline To implicit_cast(From const &f) { 94 inline To implicit_cast(From const &f) {
137 return f; 95 return f;
138 } 96 }
139 97
140 // The COMPILE_ASSERT macro can be used to verify that a compile time 98 // The COMPILE_ASSERT macro can be used to verify that a compile time
141 // expression is true. For example, you could use it to verify the 99 // expression is true. For example, you could use it to verify the
142 // size of a static array: 100 // size of a static array:
143 // 101 //
144 // COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES, 102 // COMPILE_ASSERT(arraysize(content_type_names) == CONTENT_NUM_TYPES,
145 // content_type_names_incorrect_size); 103 // content_type_names_incorrect_size);
146 // 104 //
147 // or to make sure a struct is smaller than a certain size: 105 // or to make sure a struct is smaller than a certain size:
148 // 106 //
149 // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); 107 // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
150 // 108 //
151 // The second argument to the macro is the name of the variable. If 109 // The second argument to the macro is the name of the variable. If
152 // the expression is false, most compilers will issue a warning/error 110 // the expression is false, most compilers will issue a warning/error
153 // containing the name of the variable. 111 // containing the name of the variable.
154 112
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 206
249 // Use these to declare and define a static local variable (static T;) so that 207 // Use these to declare and define a static local variable (static T;) so that
250 // it is leaked so that its destructors are not called at exit. If you need 208 // it is leaked so that its destructors are not called at exit. If you need
251 // thread-safe initialization, use base/lazy_instance.h instead. 209 // thread-safe initialization, use base/lazy_instance.h instead.
252 #define CR_DEFINE_STATIC_LOCAL(type, name, arguments) \ 210 #define CR_DEFINE_STATIC_LOCAL(type, name, arguments) \
253 static type& name = *new type arguments 211 static type& name = *new type arguments
254 212
255 } // base 213 } // base
256 214
257 #endif // BASE_MACROS_H_ 215 #endif // BASE_MACROS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698