C-style arrays (such as int i[10]
) are not very convenient to use:
- They are fixed size (even C Variable Length Arrays are not truly variable size, and they are not supported in C++)
- If the number of elements in the array can vary, it will lead to manual memory allocation (or people will use fixed-size arrays that "should be
large enough", which is both a waste of memory and a limitation of the program)
- It is very easy to lose the size of the array since an array passed to a function decays into a pointer
The C++ standard library proposes two types that are better than C-style arrays and together cover all the use cases of C-style arrays:
- For fixed-size arrays, where the memory is on the stack, use
std::array
. It is like a C-style array, except that it has normal
argument passing semantics, and the size is always a part of the type. You can roll your version if std::array
is unavailable to you
(before C++11).
- For variable-size arrays, use
std::vector
. It can be resized and handles memory allocation transparently.
- For character strings, you should use
std::string
instead of arrays of characters.
- For arrays of characters that are not strings (e.g., alphabet, exit codes, keyboard control list), prefer
std::array
or
std::vector
as per the first two bullets.
The rule S945 is related to this rule but focuses on passing arguments of an array type. S5025 will flag the use of dynamic
memory allocation that could be replaced by std::vector
.
Noncompliant code example
void f() {
int a[10]; // Noncompliant
}
Compliant solution
void f() {
std::array<int, 10> a1; // If the size really is a constant
// Or
std::vector<int>a2; // For variable size
auto s = "Hello!"; // Compliant by exception
}
Exceptions
This rule will not report the use of C-style arrays in extern "C"
code (since those arrays are often required here for compatibility
with external code) and in the arguments of main
.