In my header file, within a class body, I declare a vector of tuples where everything is constant. This is just data that I'm going to walk through as I do a task...
class Foo {
public:
...
static const std::vector<std::tuple<const char*, int>> _data;
In the corresponding source file, I populate the data...
const std::vector<std::tuple<const char*, int>>
Foo::_data
{
std::make_tuple("One", 1),
std::make_tuple("Two", 2),
...
std::make_tuple("Many", 10)
};
This throws a clang-tidy
error cert-err58-cpp
...
/path/to/src/Foo.cpp:783:14: warning: initialization of '_data' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
Foo::_data
^
/path/to/gcc-9.2.0/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../include/c++/9.2.0/bits/stl_vector.h:622:7: note: possibly throwing constructor declared here
vector(initializer_list<value_type> __l,
^
I get that there are cases that a vector
might not find space to store the data, so would throw an exception. Here, there is no way for me to try/catch
it though. That feels overkill for this anyway. What is the best solution here...?
Using std::array
instead of std::vector
just pushes the problem down to make_tuple
...
EDIT: Here is the code that I settled on. No source file additions. This is the header file...
static constexpr std::array<std::pair<const char*, int>, 10> _data {
{
{{"One", 1},
{"Two", 2},
...
{"Ten", 10}}
};
In my header file, within a class body, I declare a vector of tuples where everything is constant. This is just data that I'm going to walk through as I do a task...
class Foo {
public:
...
static const std::vector<std::tuple<const char*, int>> _data;
In the corresponding source file, I populate the data...
const std::vector<std::tuple<const char*, int>>
Foo::_data
{
std::make_tuple("One", 1),
std::make_tuple("Two", 2),
...
std::make_tuple("Many", 10)
};
This throws a clang-tidy
error cert-err58-cpp
...
/path/to/src/Foo.cpp:783:14: warning: initialization of '_data' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
Foo::_data
^
/path/to/gcc-9.2.0/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../include/c++/9.2.0/bits/stl_vector.h:622:7: note: possibly throwing constructor declared here
vector(initializer_list<value_type> __l,
^
I get that there are cases that a vector
might not find space to store the data, so would throw an exception. Here, there is no way for me to try/catch
it though. That feels overkill for this anyway. What is the best solution here...?
Using std::array
instead of std::vector
just pushes the problem down to make_tuple
...
EDIT: Here is the code that I settled on. No source file additions. This is the header file...
static constexpr std::array<std::pair<const char*, int>, 10> _data {
{
{{"One", 1},
{"Two", 2},
...
{"Ten", 10}}
};
Share
Improve this question
edited Feb 21 at 23:27
Lance E.T. Compte
asked Feb 21 at 0:08
Lance E.T. CompteLance E.T. Compte
1,2191 gold badge16 silver badges40 bronze badges
4
- If you could catch the exception what would you do with it? Abort the program? That’s exactly what would happen if you didn’t catch it. This seems like an utterly pointless warning. Don’t waste your time on it. – Pete Becker Commented Feb 21 at 1:22
- I get it Pete, but it's automated... Don't you wanna be me! :-) – Lance E.T. Compte Commented Feb 21 at 1:30
- 1 In fairness, avoiding dynamic memory allocation during application startup can be a legitimate goal. But that's not because it might throw an exception... – Pete Becker Commented Feb 21 at 14:47
- @PeteBecker, My edit shows the final code and I do like it much better. No dynamic memory allocation! – Lance E.T. Compte Commented Feb 21 at 16:15
1 Answer
Reset to default 2a vector of tuples where everything is constant
Why not an array of tuples where everything is constant?
class Foo {
public:
static const std::array<std::tuple<const char*, int>, 10> _data;
};
const std::array<std::tuple<const char*, int>, 10>
Foo::_data
{{
{"One", 1},
{"Two", 2},
...
{"Ten", 10},
}};
With constexpr
class Foo {
public:
static constexpr std::array<std::tuple<const char*, int>, 10> _data = {{
{"One", 1},
{"Two", 2}
}};
};