1 .. title:: clang-tidy - bugprone-sizeof-expression
3 bugprone-sizeof-expression
4 ==========================
6 The check finds usages of ``sizeof`` expressions which are most likely errors.
8 The ``sizeof`` operator yields the size (in bytes) of its operand, which may be
9 an expression or the parenthesized name of a type. Misuse of this operator may
10 be leading to errors and possible software vulnerabilities.
12 Suspicious usage of 'sizeof(K)'
13 -------------------------------
15 A common mistake is to query the ``sizeof`` of an integer literal. This is
16 equivalent to query the size of its type (probably ``int``). The intent of the
17 programmer was probably to simply get the integer and not its size.
23 memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int)
25 Suspicious usage of 'sizeof(expr)'
26 ----------------------------------
28 In cases, where there is an enum or integer to represent a type, a common
29 mistake is to query the ``sizeof`` on the integer or enum that represents the
30 type that should be used by ``sizeof``. This results in the size of the integer
31 and not of the type the integer represents:
43 data_type get_type() {
48 void f(data d, int numElements) {
49 // should be sizeof(float) or sizeof(double), depending on d.get_type()
50 int numBytes = numElements * sizeof(d.get_type());
55 Suspicious usage of 'sizeof(this)'
56 ----------------------------------
58 The ``this`` keyword is evaluated to a pointer to an object of a given type.
59 The expression ``sizeof(this)`` is returning the size of a pointer. The
60 programmer most likely wanted the size of the object and not the size of the
67 size_t size() { return sizeof(this); } // should probably be sizeof(*this)
71 Suspicious usage of 'sizeof(char*)'
72 -----------------------------------
74 There is a subtle difference between declaring a string literal with
75 ``char* A = ""`` and ``char A[] = ""``. The first case has the type ``char*``
76 instead of the aggregate type ``char[]``. Using ``sizeof`` on an object declared
77 with ``char*`` type is returning the size of a pointer instead of the number of
78 characters (bytes) in the string literal.
82 const char* kMessage = "Hello World!"; // const char kMessage[] = "...";
83 void getMessage(char* buf) {
84 memcpy(buf, kMessage, sizeof(kMessage)); // sizeof(char*)
87 Suspicious usage of 'sizeof(A*)'
88 --------------------------------
90 A common mistake is to compute the size of a pointer instead of its pointee.
91 These cases may occur because of explicit cast or implicit conversion.
96 memset(A, 0, sizeof(A + 0));
99 memset(point, 0, sizeof(&point));
101 Suspicious usage of 'sizeof(...)/sizeof(...)'
102 ---------------------------------------------
104 Dividing ``sizeof`` expressions is typically used to retrieve the number of
105 elements of an aggregate. This check warns on incompatible or suspicious cases.
107 In the following example, the entity has 10-bytes and is incompatible with the
108 type ``int`` which has 4 bytes.
112 char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // sizeof(buf) => 10
113 void getMessage(char* dst) {
114 memcpy(dst, buf, sizeof(buf) / sizeof(int)); // sizeof(int) => 4 [incompatible sizes]
117 In the following example, the expression ``sizeof(Values)`` is returning the
118 size of ``char*``. One can easily be fooled by its declaration, but in parameter
119 declaration the size '10' is ignored and the function is receiving a ``char*``.
123 char OrderedValues[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
124 return CompareArray(char Values[10]) {
125 return memcmp(OrderedValues, Values, sizeof(Values)) == 0; // sizeof(Values) ==> sizeof(char*) [implicit cast to char*]
128 Suspicious 'sizeof' by 'sizeof' expression
129 ------------------------------------------
131 Multiplying ``sizeof`` expressions typically makes no sense and is probably a
132 logic error. In the following example, the programmer used ``*`` instead of
137 const char kMessage[] = "Hello World!";
138 void getMessage(char* buf) {
139 memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char)); // sizeof(kMessage) / sizeof(char)
142 This check may trigger on code using the arraysize macro. The following code is
143 working correctly but should be simplified by using only the ``sizeof``
148 extern Object objects[100];
149 void InitializeObjects() {
150 memset(objects, 0, arraysize(objects) * sizeof(Object)); // sizeof(objects)
153 Suspicious usage of 'sizeof(sizeof(...))'
154 -----------------------------------------
156 Getting the ``sizeof`` of a ``sizeof`` makes no sense and is typically an error
157 hidden through macros.
161 #define INT_SZ sizeof(int)
163 void getInt(int* dst) {
164 memcpy(dst, buf, sizeof(INT_SZ)); // sizeof(sizeof(int)) is suspicious.
170 .. option:: WarnOnSizeOfConstant
172 When `true`, the check will warn on an expression like
173 ``sizeof(CONSTANT)``. Default is `true`.
175 .. option:: WarnOnSizeOfIntegerExpression
177 When `true`, the check will warn on an expression like ``sizeof(expr)``
178 where the expression results in an integer. Default is `false`.
180 .. option:: WarnOnSizeOfThis
182 When `true`, the check will warn on an expression like ``sizeof(this)``.
185 .. option:: WarnOnSizeOfCompareToConstant
187 When `true`, the check will warn on an expression like
188 ``sizeof(expr) <= k`` for a suspicious constant `k` while `k` is `0` or
189 greater than `0x8000`. Default is `true`.
191 .. option:: WarnOnSizeOfPointerToAggregate
193 When `true, the check will warn on an expression like
194 ``sizeof(expr)`` where the expression is a pointer
195 to aggregate. Default is `true`.