[COVERITY][C++] Non-static class member "A._M_elems" is not initialized in this constructor nor in any functions that it calls - c++11

I am having an issue with a coverity warning that occurs in the constructor of my C++11 class.
In the class Model, I define the type Trajectory and declare it privately.
template<unsigned int T, unsigned int K>
class Model
{
public:
typedef Eigen::Matrix<float, DEGREE, AXIS> State;
typedef Eigen::Matrix<float, AXIS_COUNT, K> Sample;
typedef std::array<std::array<Sample, T>, DEGREE> Trajectory;
private:
Settings _settings;
State _state;
Trajectory _trajectory;
...
Later in the constructor section I define two constructors, the second one inherits from the first one. In the first one, I initialize the _trajectory variable in the double for loop.
...
public:
Model(const Settings& settings, const State& initialState) :
_settings(settings),
_state(initialState)
{
for (unsigned int i = 0; i < DEGREE; i++)
for (unsigned int j = 0; j < T; j++)
_trajectory[i][j].setZero();
};
Model(const Settings& settings) :
Model(settings, State::Zero()){};
~Model() = default;
...
This class is called by a handler which initializes Model with the second constructor. Everything works fine, however, once I run the coverity check, I receive the following error.
Non-static class member "_trajectory._M_elems" is not initialized in this constructor nor in any functions that it calls.
It is called at the line Model(settings, State::Zero()){};
I have tried many options but I cannot figure out how to initialize _trajectory properly without receiving this error.
I have tried this:
public:
Model(const Settings& settings, const State& initialState) :
_settings(settings),
_state(initialState),
_trajectory({})
this
public:
Model(const Settings& settings, const State& initialState) :
_settings(settings),
_state(initialState),
_trajectory({{}})
this
public:
Model(const Settings& settings, const State& initialState) :
_settings(settings),
_state(initialState),
_trajectory(Trajectory{{}})
and other combinations. None works.
Waiting for some legend to give me a hint.

Related

Why am I getting a bad_function_call exception when using std::function as a comparison function object in std::map

I am getting a std::__1::bad_function_call: std::exception when I execute the code below.
I have tried initializing std::function in the constructor and initializing it directly when defined as a class variable. In both cases I get the aforementioned exception.
Note that if I define a function object (a class with a bool operator () function defined), the code works properly. How can I capture a lambda into std::function so that no exception is thrown? Also, what is causing the exception in the code below?
#include <map>
using namespace std;
class foo {
public:
foo() {cmp = [](const int &a, const int &b){return a > b;};}
//function<bool(const int &a, const int &b)> cmp = [](const int &a, const int &b){return a > b;};
function<bool(const int &a, const int &b)> cmp;
map<int, int, decltype(cmp)> rbtree;
};
int main() {
foo* obj = new foo();
obj->rbtree[5] = 5;
obj->rbtree[1] = 5;
obj->rbtree[5] = 5;
}
You may be looking for something like this:
class foo {
public:
using Cmp = function<bool(int a, int b)>;
map<int, int, Cmp> rbtree { [](int a, int b){return a > b;} };
};
Demo

varadic argument templated object creation on container not working

Below is a example (not the entire class, just relevant parts)
class Container {
private:
size_t m_next_id;
std::unordered_map m_objects;
public:
template<typename Type, typename... Args> size_t create(Args... args) { return this->add(new Type (args...)); }
size_t add(Base * obj) { m_objects.emplace(m_next_id, obj); return m_next_id++; }
}
Say I have the following
class Base;
class A : Base;
class B : Base;
// etc.
Then the following calls work with out error
container.create<B, Vector2f, float>({1, 0}, 0);
container.add(new B({0, 1}, 0));
container.create<B>(Vector2f{0, 1}, 1); // EDIT no initializer list
However the following produce a compile time error
container.create<B>({1, 0}, 1);
Error:
error: no matching function for call to 'Container::create(<brace-enclosed initializer list>, const int&)'
container.create<B>({1, 0}, 1);
^
note: candidate: size_t Container::create(Args ...) [with Type = B; Args = {}; size_t = long long unsigned int]
template<typename Type, typename... Args> size_t create(Args... args) { return this->add(new Type (args...)); }
^~~~~~
note: candidate expects 0 arguments, 2 provided
I'm unsure why the template isn't able to work with this pattern, nor how to fix it so it would work how I want, based on examples I've seen using std emplace functions this should be able to work.
EDIT:
Base on the fact that the version with out an initializer list, works fine, I can conclude the problem is because of the initializer list. However I don't see why this would be a problem, shouldn't this be able to construct the appropriate type based on B's constructor where B is invoked?

clang - how to declare a static const int in header file?

Given the following template in a header file, and a couple of specializations:
template<typename> class A {
static const int value;
};
template<> const int A<int>::value = 1;
template<> const int A<long>::value = 2;
and building with clang-5, it results in errors for each source unit that included the file, all complaining about multiple definitions for A<int>::value and A<long>::value.
At first, I thought that maybe the template specializations needed to be put in a specific translation unit, but on checking the spec, this apparently should be allowed, because the value is a constant integer.
Am I doing something else wrong?
EDIT: if I move the definition into a single translation unit, then I can no longer use the value of A<T>::value in the context of a const int (eg, where its value is being used to calculate the value of another const assignment) , so the value really needs to be in a header.
In c++11 you maybe can go that way:
template<typename> class B {
public:
static const int value = 1;
};
template<> class B<long> {
public:
static const int value = 2;
};
template<typename T> const int B<T>::value;
If you only want to specialize the value var, you can use CRTP for that.
From C++17 you can make your definition inline:
template<> inline const int A<int>::value = 1;
template<> inline const int A<long>::value = 2;
Also from c++17 you can remove the 'template const int B::value;' for constexpr:
template<typename> class C {
public:
static constexpr int value = 1;
};
template<> class C<long> {
public:
static constexpr int value = 2;
};
// no need anymore for: template<typename T> const int C<T>::value;
And another solution for c++11 can be to use a inline method instead of inline vars which are allowed from c++17:
template<typename T> class D {
public:
static constexpr int GetVal() { return 0; }
static const int value = GetVal();
};
template <> inline constexpr int D<int>::GetVal() { return 1; }
template <> inline constexpr int D<long>::GetVal() { return 2; }
template< typename T>
const int D<T>::value;
In addition to your last edit:
To use your values also in other dependent definitions it seems to be the most readable version if you use the inline constexpr methods.
Edit: "Special" version for clang, because as OP tells us, clang complains with "specialization happening after instantiation". I don't know if clang or gcc is wrong in that place...
template<typename T> class D {
public:
static constexpr int GetVal();
static const int value;
};
template <> inline constexpr int D<int>::GetVal() { return 1; }
template <> inline constexpr int D<long>::GetVal() { return 2; }
template <typename T> const int D<T>::value = D<T>::GetVal();
int main()
{
std::cout << D<int>::value << std::endl;
std::cout << D<long>::value << std::endl;
}
I told already that CRTP is possible if not the complete class should be redefined. I checked the code on clang and it compiles without any warning or error, because OP comments that he did not understand how to use it:
template<typename> class E_Impl {
public:
static const int value = 1;
};
template<> class E_Impl<long> {
public:
static const int value = 2;
};
template<typename T> const int E_Impl<T>::value;
template < typename T>
class E : public E_Impl<T>
{
// rest of class definition goes here and must not specialized
// and the values can be used here!
public:
void Check()
{
std::cout << this->value << std::endl;
}
};
int main()
{
E<long>().Check();
std::cout << E<long>::value << std::endl;
E<int>().Check();
std::cout << E<int>::value << std::endl;
}

Migrating from VS to GCC: change in use of typename?

I'm building a large project on Debian 6.0.6 (with gcc 4.4.5) that was initially built in Microsoft VS (2008, I think).
What seems to be the problem is that when I declare a member as
typedef typename std::set<T>::iterator iterator, and then later use this iterator, gcc appears to interpret this as (const T*).
The part of the class containing the typename designation:
template <class entityType>
class entityArray
{
private: std::set<entityType> m_array;
public: typedef typename std::set<entityType>::iterator iterator;
...
public:
entityType* At( const char* name);
...
};
plus a few other classes that are needed for the discussion:
class entity
{
private:
entity* m_parent;
int m_ncid;
std::string m_name;
public:
entity () { m_ncid = 0; m_parent = NULL;}
virtual ~entity () {};
...
};
class attribute : public entity
{
public:
attribute(){};
virtual ~attribute(){};
};
class var : public entity
{
private:
entityArray<attribute> m_atts;
public:
var(){}
virtual ~var(){}
...
};
class dim : public entity
{
public:
dim() {};
virtual ~dim() {};
};
class group : public entity
{
private:
entityArray<var> m_vars;
entityArray<dim> m_dims;
...
public:
dim* DimAt( const char* dimname ) { return m_dims.At(dimname);}
};
Now an iterator is initialized through a call to the function DimAt which in turn calls At. The At function in the first class is defined as:
template <class entityType>
entityType* entityArray<entityType>::At( const char* name )
{
entityType dummy;
iterator iter;
entityType* ptr;
... define dummy ...
iter = m_array.find( dummy );
ptr = (iter != m_array.end()) ? &(*iter) : NULL;
return ptr;
}
Compiling the above produces
error: invalid conversion from const dim* to dim*., referring to &(*iter).
I realize that typename is required for declaring iterator, since the type is a dependent and qualified name, but I don't see why this substitution (const *) is being performed by the compiler. I would appreciate any help that you could provide. Thanks!
This has absolutely nothing to do with typename.
The standard allows std::set<T>::iterator and std::set<T>::const_iterator to be the same type, and with GCC the types are the same.
The reason is that modifying an element of a std::set e.g. by *iter = val might invalidate the ordering of the set elements, breaking the invariant that the elements of the set are always in order. By making the iterator type a constant iterator instead of a mutable iterator it's not possible to alter the element, preventing you from corrupting the set's ordering.
So with GCC's implementation, when you dereference the iterator using *iter you get a const entitType& and when you take its address using &*iter you get a const entityType*

Compilation error when using boost serialization library

I have been struggling with this error for a long time.
The following is my code snippet.
//This is the header file
template<typename TElem>
class ArrayList {
public:
/** An accessible typedef for the elements in the array. */
typedef TElem Elem;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & ptr_;
ar & size_;
ar & cap_;
}
Elem *ptr_; // the stored or aliased array
index_t size_; // number of active objects
index_t cap_; // allocated size of the array; -1 if alias
};
template <typename TElem>
class gps_position
{
public:
typedef TElem Elem;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & degrees;
ar & minutes;
ar & seconds;
}
private:
Elem degrees;
index_t minutes;
index_t seconds;
};
// This is the .cc file
#include <string>
#include <fstream>
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/serialization.hpp>
#include "arraylist.h"
int main() {
// create and open a character archive for output
std::ofstream ofs("filename");
// create class instance
// gps_position<int> g(35.65, 59, 24.567f);
gps_position<float> g;
// save data to archive
{
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
//oa << g;
// archive and stream closed when destructors are called
}
// ... some time later restore the class instance to its orginal state
/* gps_position<int> newg;
{
// create and open an archive for input
std::ifstream ifs("filename");
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia >> newg;
// archive and stream closed when destructors are called
}*/
ArrayList<float> a1;
ArrayList<int> a2;
a1.Init(22);
a2.Init(21);
// a1.Resize(30);
// a1.Resize(12);
// a1.Resize(22);
// a2.Resize(22);
a1[21] = 99.0;
a1[20] = 88.0;
for (index_t i = 0; i < a1.size(); i++) {
a1[i] = i;
a1[i]++;
}
std::ofstream s("test.txt");
{
boost::archive::text_oarchive oa(s);
oa << a1;
}
return 0;
}
The following is the compilation error i get.
In file included from /usr/include/boost/serialization/split_member.hpp:23,
from /usr/include/boost/serialization/nvp.hpp:33,
from /usr/include/boost/serialization/serialization.hpp:17,
from /usr/include/boost/archive/detail/oserializer.hpp:61,
from /usr/include/boost/archive/detail/interface_oarchive.hpp:24,
from /usr/include/boost/archive/detail/common_oarchive.hpp:20,
from /usr/include/boost/archive/basic_text_oarchive.hpp:32,
from /usr/include/boost/archive/text_oarchive.hpp:31,
from demo.cc:4:
/usr/include/boost/serialization/access.hpp: In static member function ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = float]’:
/usr/include/boost/serialization/serialization.hpp:74: instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = float]’
/usr/include/boost/serialization/serialization.hpp:133: instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = float]’
/usr/include/boost/archive/detail/oserializer.hpp:140: instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = float]’
demo.cc:105: instantiated from here
/usr/include/boost/serialization/access.hpp:109: error: request for member ‘serialize’ in ‘t’, which is of non-class type ‘float’
Please help me out.
You can't serialize a raw pointer to a float, which is what you're trying to do here. In fact you're not actually serializing the array anyway when you try to serialize a1 - you only try to serialize the pointer to the head of it.
I don't know what you're trying to accomplish, but can you just make a1 and a2 raw float arrays? Boost can serialize those natively.
float a1[21];
a1[21] = 99.0;
for (index_t i = 0; i < 21; i++) {
a1[i] = i;
a1[i]++;
}
std::ofstream s("test.txt");
boost::archive::text_oarchive oa(s);
oa << a1;
The better option is probably to change your ArrayList definition to use std::vector<Elem> instead of a raw Elem *. Boost::Serialization also already knows how to serialize all STL containers.
For further information see the Boost serialization reference manual.

Resources