Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does range-for decay this array into pointer according to clang-tidy?

Clang-tidy (versions 13.x and 16.x) detects violations of cppcoreguidelines-pro-bounds-array-to-pointer-decay in a weirdly specific situation: when iterating over an array that is accessed through a pointer. Why does that happen? How can range-for even work after an array decays to a pointer?

Minimal example:

int main() {
    int local[] { 1, 2, 3 };

    static int global[] { 1, 2, 3 };

    struct Wrapper {
        int field[3] { 1, 2, 3 };
    } wrapper;

    Wrapper *pointer = &wrapper;

    int (&reference)[3] = pointer->field;

    for (int i : local);
    for (int i : global);
    for (int i : wrapper.field);
    for (int i : pointer->field);
    for (int i : reference);
}
$ clang-tidy-16 main.cpp --checks='-*,cppcoreguidelines-pro-bounds-array-to-pointer-decay'
(...)
main.cpp:16:13: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay]
        for (int i : pointer->field);
                   ^

Why does only pointer->field trip this warning?

like image 788
OLEGSHA Avatar asked Nov 18 '25 15:11

OLEGSHA


1 Answers

Because that is what happens there. According to cppreference a temporary variable auto&& __range = range-expression is created. Due to the rules of auto deduction, this will decay the array to a pointer. But that doesn't matter. If range-expression is an array, then the begin-expr is equal to __range and the end-expr is equal to __range + __bound.

The actual type of __range in this context is irrelevant, as long as (__range, __range + __bound) is an iterable range.

One could argue that all of them should produce this warning, but apparently clang-tidy has suppressed some of them because they are not useful.

like image 51
Mestkon Avatar answered Nov 21 '25 05:11

Mestkon