== Why is this an issue?

`sizeof` returns the size in bytes of a type. One common usage pattern, especially in C, is to use `sizeof` to determine the size of an array. However, arrays decay to pointers when passed as arguments to a function, and if `sizeof` is applied to such an argument, it will return the size of the pointer, not of the array. A similar issue happens when the array is used in an arithmetic operation.

This rule raises issues when:

* `sizeof` is used to compute the array size of a pointer passed as a function argument.
* `sizeof` is called on the result of an arithmetic operation involving an array.

Note: {cpp}17 provides a `std::size` function that will correctly compute the number of elements of an array and fail to compile if provided with a pointer. It is simpler and safer to use this variant when available. {cpp}20 also provides the functions `std::ssize`, `std::ranges::size`, and `std::ranges::ssize` with similar effects.

=== Noncompliant code example

[source,cpp]
----
void fun(int *data, int array[10]) {
  size_t const dataSize = sizeof data / sizeof(int); // Noncompliant, type of data is int *
  size_t const arraySize = sizeof array / sizeof(int); // Noncompliant, type of array is int * too
  int primes[] = { 1, 2, 3, 5, 7, 13, 17, 19};
  size_t const primesSize2 = sizeof(primes + 1) / sizeof(int); // Noncompliant, type of primes + 1 is int *
}
----


=== Compliant solution

[source,cpp]
----
// Computing dataSize is now the responsibility of the caller
void fun(int *data, int dataSize, int (&array)[10]) {
  size_t const arraySize = sizeof array / sizeof(int); // Compliant, no decay
  int primes[] = { 1, 2, 3, 5, 7, 13, 17, 19};
  size_t const primesSize = std::size(primes); // Better variant in C++17
  size_t const primesSize2 = sizeof primes / sizeof(int) + 1; // Compliant, type of primes is int[8]
}
----


== Resources

* https://wiki.sei.cmu.edu/confluence/x/CdYxBQ[CERT, ARR01-C.] - Do not apply the `sizeof` operator to a pointer when taking the size of an array
* CWE - https://cwe.mitre.org/data/definitions/467[CWE-467 - Use of sizeof() on a Pointer Type]



ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

* Remove this calculation inside the "sizeof".
* Remove this use of "sizeof" with a numeric constant.
* Remove the inner "sizeof".
* Refactor this use of "sizeof" on expression of a pointer type.
* Remove any possible side effects from this "sizeof".
* Don't use "sizeof" with an operand of a "void" type.


'''
== Comments And Links
(visible only on this page)

=== deprecates: S2215

=== deprecates: S1913

=== is related to: S922

=== on 29 Jun 2015, 10:25:19 Massimo PALADIN wrote:
\[~ann.campbell.2] could you please verify this spec?

=== on 29 Jun 2015, 11:51:01 Ann Campbell wrote:
\[~massimo.paladin], I've made a few edits which you'll want to double-check, but I don't like the code example. I would have expected to see a ``++malloc++`` rather than an array declaration. Something like the following which is (when correctly written) a common idiom:

----
int size = 42;
char *cp = malloc(sizeof(char * size));  // Noncompliant
----
and

----
int size = 42;
char *cp = malloc(size * sizeof(char));
----

=== on 29 Jun 2015, 13:22:24 Ann Campbell wrote:
check it over, please [~massimo.paladin]

=== on 30 Jun 2015, 15:12:24 Ann Campbell wrote:
\[~massimo.paladin] I've edited the description some. Please double-check me.


Also I favor moving ``++sizeof++`` out of RSPEC-2665 and consolidating all the bad arguments to ``++sizeof++`` here. That would leave RSPEC-2665 as: "alignof" should not be used with operands of a "void" type

=== on 2 Jul 2015, 20:26:02 Ann Campbell wrote:
FYI [~massimo.paladin] I suggest a title of: Valid arguments should be passed to "sizeof"

It's slightly more specific

=== on 3 Jul 2015, 06:51:54 Massimo PALADIN wrote:
\[~ann.campbell.2] title updated.

endif::env-github,rspecator-view[]
