despite that variable length arrays (VLA for short) has been around
for a long time, it is an extension supported by GCC and Clang, and is
not a part of C++ standard, its implementation allocates the dynamically
sized array on stack, hence is a source of potential stack overflow.
when compiling with Clang, it complains. so in this change, we switch
to std::vector<>, which is defined by the C++ standard, and it allocates
the storage on heap, so it is immune to the possible stack overflow problem.
```
/home/kefu/dev/ceph/src/crush/CrushWrapper.h:1613:16: warning: variable length arrays in C++ are a Clang extension [-Wvla-cxx-extension]
1613 | int rawout[maxout];
| ^~~~~~
/home/kefu/dev/ceph/src/crush/CrushWrapper.h:1613:16: note: function parameter 'maxout' with unknown value cannot be used in a constant expression
/home/kefu/dev/ceph/src/crush/CrushWrapper.h:1610:60: note: declared here
1610 | void do_rule(int rule, int x, std::vector<int>& out, int maxout,
| ^
/home/kefu/dev/ceph/src/crush/CrushWrapper.h:1614:15: warning: variable length arrays in C++ are a Clang extension [-Wvla-cxx-extension]
1614 | char work[crush_work_size(crush, maxout)];
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/kefu/dev/ceph/src/crush/CrushWrapper.h:1614:31: note: implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function
1614 | char work[crush_work_size(crush, maxout)];
| ^
2 warnings generated.
```
Signed-off-by: Kefu Chai <tchaikov@gmail.com>
(cherry picked from commit
13169741c318443de0e8e889ff4616fe075a17ef)
void do_rule(int rule, int x, std::vector<int>& out, int maxout,
const WeightVector& weight,
uint64_t choose_args_index) const {
- int rawout[maxout];
- char work[crush_work_size(crush, maxout)];
- crush_init_workspace(crush, work);
+ std::vector<int> rawout(maxout);
+ std::vector<char> work(crush_work_size(crush, maxout));
+ crush_init_workspace(crush, std::data(work));
crush_choose_arg_map arg_map = choose_args_get_with_fallback(
choose_args_index);
- int numrep = crush_do_rule(crush, rule, x, rawout, maxout,
+ int numrep = crush_do_rule(crush, rule, x, std::data(rawout), maxout,
std::data(weight), std::size(weight),
- work, arg_map.args);
+ std::data(work), arg_map.args);
if (numrep < 0)
numrep = 0;
out.resize(numrep);