• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. title:: clang-tidy - bugprone-sizeof-expression
2
3bugprone-sizeof-expression
4==========================
5
6The check finds usages of ``sizeof`` expressions which are most likely errors.
7
8The ``sizeof`` operator yields the size (in bytes) of its operand, which may be
9an expression or the parenthesized name of a type. Misuse of this operator may
10be leading to errors and possible software vulnerabilities.
11
12Suspicious usage of 'sizeof(K)'
13-------------------------------
14
15A common mistake is to query the ``sizeof`` of an integer literal. This is
16equivalent to query the size of its type (probably ``int``). The intent of the
17programmer was probably to simply get the integer and not its size.
18
19.. code-block:: c++
20
21  #define BUFLEN 42
22  char buf[BUFLEN];
23  memset(buf, 0, sizeof(BUFLEN));  // sizeof(42) ==> sizeof(int)
24
25Suspicious usage of 'sizeof(expr)'
26----------------------------------
27
28In cases, where there is an enum or integer to represent a type, a common
29mistake is to query the ``sizeof`` on the integer or enum that represents the
30type that should be used by ``sizeof``. This results in the size of the integer
31and not of the type the integer represents:
32
33.. code-block:: c++
34
35  enum data_type {
36    FLOAT_TYPE,
37    DOUBLE_TYPE
38  };
39
40  struct data {
41    data_type type;
42    void* buffer;
43    data_type get_type() {
44      return type;
45    }
46  };
47
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());
51    ...
52  }
53
54
55Suspicious usage of 'sizeof(this)'
56----------------------------------
57
58The ``this`` keyword is evaluated to a pointer to an object of a given type.
59The expression ``sizeof(this)`` is returning the size of a pointer. The
60programmer most likely wanted the size of the object and not the size of the
61pointer.
62
63.. code-block:: c++
64
65  class Point {
66    [...]
67    size_t size() { return sizeof(this); }  // should probably be sizeof(*this)
68    [...]
69  };
70
71Suspicious usage of 'sizeof(char*)'
72-----------------------------------
73
74There is a subtle difference between declaring a string literal with
75``char* A = ""`` and ``char A[] = ""``. The first case has the type ``char*``
76instead of the aggregate type ``char[]``. Using ``sizeof`` on an object declared
77with ``char*`` type is returning the size of a pointer instead of the number of
78characters (bytes) in the string literal.
79
80.. code-block:: c++
81
82  const char* kMessage = "Hello World!";      // const char kMessage[] = "...";
83  void getMessage(char* buf) {
84    memcpy(buf, kMessage, sizeof(kMessage));  // sizeof(char*)
85  }
86
87Suspicious usage of 'sizeof(A*)'
88--------------------------------
89
90A common mistake is to compute the size of a pointer instead of its pointee.
91These cases may occur because of explicit cast or implicit conversion.
92
93.. code-block:: c++
94
95  int A[10];
96  memset(A, 0, sizeof(A + 0));
97
98  struct Point point;
99  memset(point, 0, sizeof(&point));
100
101Suspicious usage of 'sizeof(...)/sizeof(...)'
102---------------------------------------------
103
104Dividing ``sizeof`` expressions is typically used to retrieve the number of
105elements of an aggregate. This check warns on incompatible or suspicious cases.
106
107In the following example, the entity has 10-bytes and is incompatible with the
108type ``int`` which has 4 bytes.
109
110.. code-block:: c++
111
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]
115  }
116
117In the following example, the expression ``sizeof(Values)`` is returning the
118size of ``char*``. One can easily be fooled by its declaration, but in parameter
119declaration the size '10' is ignored and the function is receiving a ``char*``.
120
121.. code-block:: c++
122
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*]
126  }
127
128Suspicious 'sizeof' by 'sizeof' expression
129------------------------------------------
130
131Multiplying ``sizeof`` expressions typically makes no sense and is probably a
132logic error. In the following example, the programmer used ``*`` instead of
133``/``.
134
135.. code-block:: c++
136
137  const char kMessage[] = "Hello World!";
138  void getMessage(char* buf) {
139    memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char));  //  sizeof(kMessage) / sizeof(char)
140  }
141
142This check may trigger on code using the arraysize macro. The following code is
143working correctly but should be simplified by using only the ``sizeof``
144operator.
145
146.. code-block:: c++
147
148  extern Object objects[100];
149  void InitializeObjects() {
150    memset(objects, 0, arraysize(objects) * sizeof(Object));  // sizeof(objects)
151  }
152
153Suspicious usage of 'sizeof(sizeof(...))'
154-----------------------------------------
155
156Getting the ``sizeof`` of a ``sizeof`` makes no sense and is typically an error
157hidden through macros.
158
159.. code-block:: c++
160
161  #define INT_SZ sizeof(int)
162  int buf[] = { 42 };
163  void getInt(int* dst) {
164    memcpy(dst, buf, sizeof(INT_SZ));  // sizeof(sizeof(int)) is suspicious.
165  }
166
167Options
168-------
169
170.. option:: WarnOnSizeOfConstant
171
172   When `true`, the check will warn on an expression like
173   ``sizeof(CONSTANT)``. Default is `true`.
174
175.. option:: WarnOnSizeOfIntegerExpression
176
177   When `true`, the check will warn on an expression like ``sizeof(expr)``
178   where the expression results in an integer. Default is `false`.
179
180.. option:: WarnOnSizeOfThis
181
182   When `true`, the check will warn on an expression like ``sizeof(this)``.
183   Default is `true`.
184
185.. option:: WarnOnSizeOfCompareToConstant
186
187   When `true`, the check will warn on an expression like
188   ``sizeof(epxr) <= k`` for a suspicious constant `k` while `k` is `0` or
189   greater than `0x8000`. Default is `true`.
190