No default constructor and errors out - c++

Error received:
error: no matching function for call to ‘stout::SCGI::SCGI()’
Code:
#include <gtest/gtest.h>
#include <vector>
#include "../../../../stout/cgi/scgi/scgi.hpp"
class SCGITest : public ::testing::Test
{
protected:
int string_length;
std::vector<char> netstring;
stout::SCGI scgi;
public:
SCGITest()
{
const char *c_netstring =
"70:CONTENT_LENGTH\00027\0"
"SCGI\0001\0"
"REQUEST_METHOD\0POST\0"
"REQUEST_URI\0/deepthought\0"
","
"What is the answer to life?";
string_length = 102;
for(int i = 0; i < string_length; ++i)
{
netstring.push_back(c_netstring[i]);
}
// SHOULD CALL stout::SCGI::SCGI(const std::vector<char>&)
this->scgi = stout::SCGI scgi {netstring};
scgi.init();
}
};
TEST_F(SCGITest, NetstringSize)
{
EXPECT_EQ(netstring.size(), string_length);
}
TEST_F(SCGITest, SCGILength)
{
EXPECT_EQ(scgi.get_length(), 70);
}
TEST_F(SCGITest, SCGIContentLength)
{
EXPECT_EQ(scgi.get_header("CONTENT_LENGTH"), "27");
}
TEST_F(SCGITest, SCGIVersion)
{
EXPECT_EQ(scgi.get_header("SCGI"), "1");
}
TEST_F(SCGITest, SCGIRequestMethod)
{
EXPECT_EQ(scgi.get_header("REQUEST_METHOD"), "POST");
}
TEST_F(SCGITest, SCGIRequestURI)
{
EXPECT_EQ(scgi.get_header("REQUEST_URI"), "/deepthought");
}
TEST_F(SCGITest, SCGIRequestBody)
{
EXPECT_EQ(scgi.get_request_body(), "What is the answer to life?");
}
Question:
When I try and construct and object of type stout::SCGI::SCGI using the constructor stout::SCGI::SCGI(const std::vector<char>&) it fails in the above code with the error message shown at the top of this post.
It seems that before the constructor has finished it has already tried to call the default (empty) constructor for the scgi private member variable. I do not want an empty constructor on my class and have had to temporarily add one to fix this issue while I investigate it.
I've read other questions regarding this issue but can't seem to find a solution for this particular case.
If it matters I'm compiling the above code using G++ 4.9.2 on Arch Linux with the -std=c++14 flag.

Your stout::SCGI type has no default constructor, yet you are not initialising this->scgi. Sure, you're assigning to it at the end of your constructor body, but that's not at all the same thing.
You need to initialise any members that are const or which cannot be default-constructed:
struct Foo
{
stout::SCGI scgi;
Foo()
: scgi(/* ctor arguments here */) // this is a "member initialisation list"
{};
};
Also, the following is simply not valid syntax:
this->scgi = stout::SCGI scgi {netstring};
That lone scgi is clearly superfluous. At best, you want:
this->scgi = stout::SCGI{netstring};
However, once you're initialising this->scgi instead of waiting to assign to it, then this goes away completely.

What is scgi supposed to be here? I think you just want
this->scgi = stout::SCGI {netstring};

Related

Stateless lambdas as static local variable

I am trying to write a templated wrapper class around a stateless lambda. Something like this:
template <class TFuncOp>
class Adapter
{
public:
void Op()
{
TFuncOp func; // not possible before C++20
func();
}
};
Since this isn't possible before default constructible lambdas arrive with C++20, I used this technique to make my class work: Calling a stateless lambda without an instance (only type)
So the final solution looks like this:
template <class TFuncOp>
class Adapter
{
public:
static TFuncOp GetOpImpl( TFuncOp *pFunc = 0 )
{
static TFuncOp func = *pFunc;
return func;
}
void Op()
{
GetOpImpl()();
}
};
template <class TFuncOp>
Adapter<TFuncOp> MakeAdapter(TFuncOp func )
{
// Removing the line below has no effect.
//Adapter<TFuncOp>::GetOpImpl( &func );
return Adapter<TFuncOp>();
}
int main()
{
auto adapter = MakeAdapter( [] { printf("Hello World !\n"); } );
adapter.Op();
return 0;
}
This code works on all major compilers (clang, gcc, msvc). But with one surprising discovery. Initialization (or lack thereof) of the static local instance of the lambda in GetOpImpl() has no effect. It works fine either way.
Can anyone explain how this works? Am I invoking UB if I use the static local instance of the lambda without initializing it?
In any case, accessing a nullptr is never a good idea as it is UB.
But we can see that typical implementations generate code which simply works. I try to explain why:
First, it has nothing to do with lambdas. It is simply the not needed using of a copy constructor on a class which has no data. As you have no data, the generated code will not access the passed object. In your case, you "copy" the object which the pointer TFuncOp *pFunc = 0 points to, which is a nullptr which will crash if the object must be accessed. As there is no data to access, a typical implementation will not genrate any code which will access the nullptr at all. But it is still UB.
The same works with all other types in the same way and has nothing special with a lambda!
struct Empty
{
void Do() { std::cout << "This works the same way" << std::endl; }
// int i; // << if you add some data, you get a seg fault
};
int main()
{
Empty* ptr = nullptr;
Empty empty = *ptr; // get seg fault here, because default copy constructor access the nullptr, but typically only if copy ctor needs to access!
empty.Do();
}
And a lambda which has no captured data, is an empty structure with a operator()().
That all is a answer why it seems to work.

gcc8 is throwing compilation error due to non-trivially copyable type

class mapInfo
{
public:
mapInfo();
~mapInfo();
public:
int dataType_m;
private:
int *frequency;
};
//constructor is defined here.
mapInfo::mapInfo() :
dataType_m(0),
frequency(NULL)
{
}
//destructor is defined here
mapInfo::~mapInfo()
{
free(frequency);
frequency = NULL;
}
Result_t Maps::add(mapInfo &mapInfo_r)
{
if (maps_mp == NULL)
{
numMaps_m = 1;
maps_mp = (mapInfo *) calloc(1, sizeof(mapInfo));
}
else
{
numMaps_m++;
maps_mp = (mapInfo *) realloc(maps_mp, numMaps_m*sizeof(mapInfo));
}
maps_mp[numMaps_m-1] = mapInfo_r; // Default copy constructor
return 1;
}
While compiling with gcc8, getting the following compilation error. It looks like defining the destructor like above giving the compilation error for gcc8.
How to resolve this?
error: 'void* realloc(void*, size_t)' moving an object of non-trivially copyable type 'class xyyz::mapInfo'; use 'new' and 'delete' instead [-Werror=class-memaccess].
That’s simply not proper C++. Rewrite your code as follows (I’m guessing here with regards to the type of frequency, but definitely don’t use free on it):
#include <vector>
class map_info
{
public:
map_info();
private:
int data_type;
std::vector<int> frequency;
};
std::vector<map_info> maps_mp;
map_info::map_info() : data_type(0), frequency() {}
// …
void maps::add(map_info& map_info)
{
maps_mp.push_back(map_info);
}
maps_mp = (mapInfo *) realloc(maps_mp, numMaps_m*sizeof(mapInfo));
This is not sensible. You can't just move an object from one aree of memory to another if that object is non-trivial.
For example, consider a string object that keeps a pointer to the string. It could look like this:
class MyString
{
char* inner_ptr;
char buf[64];
...
};
And it might have a constructor like this:
MyString::MyString (const char* j)
{
if (strlen(j) < 64)
inner_ptr = buf;
else
inner_ptr = malloc (strlen(j) + 1);
strcpy(inner_ptr, j);
}
And a destructor like this:
MyString::~MyString()
{
if (buf != inner_ptr)
free (inner_ptr);
}
Now, think about what happens if you call relloc on an array of these. The short strings will still have their inner_ptrs pointing to the old object's buffer, which you just deallocated.
The error message explains this issue reasonable well. It is simply not legal to use realloc to move a non-trivial object. You have to construct a new object because the object needs a chance to handle the change in its address.

Avoid use of undefined object in c++

If I create a class in c++, it is possible to call a function of an object of this class, even if this class does not exists.
For example:
Class:
class ExampleClass
{
private:
double m_data;
public:
void readSomeData(double param)
{
m_data = param;
}
}
Any function where this class is used:
int main()
{
ExampleClass* myClass;
myClass->readSomeData(2.5);
}
Ofcourse this wouldn't function, because myClass is not defined.
To avoid such situations, I check if ExampleClass objects are a null_ptr
example:
void readSomeData(double param)
{
if(this == null_ptr)
return;
m_data = param;
}
But gcc says:
'this' pointer cannot be null in well-defined C++ code; comparison may
be assumed to always avaluate to false.
Ofcourse that is only a warning, but I think it is not nice to have this warning. Is there a better way to check if the pointer of a class is defined?
Testing it in the class is the wrong way, the warning is correct about that if your code is well defined then this must not be null, so the test should happen at the time when you call the member function:
int main()
{
ExampleClass* myClass = nullptr; // always initialize a raw pointer to ensure
// that it does not point to a random address
// ....
if (myClass != nullptr) {
myClass->readSomeData(2.5);
}
return 0;
}
If a pointer must not be null at a certain part of your code then you should do it according to CppCoreGuideline: I.12: Declare a pointer that must not be null as not_null
Micorosoft provides an Guidelines Support Library that has an implementation for not_null.
Or if possible then don't use pointers at all but std::optional.
So a code setup could look like this:
#include <gsl/gsl>
struct ExampleClass {
void readSomeData(double ){}
};
// now it is clear that myClass must not and can not be null within work_with_class
// it still could hold an invalid pointe, but thats another problem
void work_with_class(gsl::not_null<ExampleClass*> myClass) {
myClass->readSomeData(2.5);
}
int main()
{
ExampleClass* myClass = nullptr; // always initialize a raw pointer to ensure
// that it does not point to a random address
// ....
work_with_class(myClass);
return 0;
}
The best way is not use pointers at all:
int main()
{
ExampleClass myClass;
myClass.readSomeData(2.5);
}
That way there's no need for any check, and in fact, checking this inside the function is moot.
If you need nullability, use std::optional instead.
Either don't use pointers as Bartek Banachewicz has pointed out, or properly initialize and check the pointer:
int main()
{
ExampleClass* myClass= 0;
if (myClass)
myClass->readSomeData(2.5);
return 0;
}
Of course you still have to add the instantiation of the object at some point, otherwise the code is nonsense.

Access variable outside try-catch block

I have the following code:
class ClassA
{
public:
ClassA(std::string str);
std::string GetSomething();
};
int main()
{
std::string s = "";
try
{
ClassA a = ClassA(s);
}
catch(...)
{
//Do something
exit(1);
}
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
I would like the last line could access the a variable. How could I achieve that, given ClassA doesn't have default constructor ClassA() and I would not like to use pointers? Is the only way to add a default constructor to ClassA?
You can't or shouldn't. Instead you could just use it within the try block, something like:
try
{
ClassA a = ClassA(s);
std::string result = a.GetSomething();
}
catch(...)
{
//Do something
exit(1);
}
The reason is that since a goes out of scope after the try block referring to the object after that is undefined behavior (if you have a pointer to where it were).
If you're concerned with a.GetSomething or the assignment throws you could put a try-catch around that:
try
{
ClassA a = ClassA(s);
try {
std::string result = a.GetSomething();
}
catch(...) {
// handle exceptions not from the constructor
}
}
catch(...)
{
//Do something only for exception from the constructor
exit(1);
}
You can use some sort of optional or just use std::unique_ptr.
int main()
{
std::string s = "";
std::unique_ptr<ClassA> pa;
try
{
pa.reset(new ClassA(s));
}
catch
{
//Do something
exit(1);
}
ClassA& a = *pa; // safe because of the exit(1) in catch() block
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
Of course, just extending the try block to include the usage of a is the simplest solution.
Also, if you were really planning to exit(1) or otherwise abort the program on failure then simply don't put a try block here at all. The exception will propagate up, aborting the program if it is not caught .
One alternative is to use std::optional . This is the same sort of concept as using a pointer, but it uses automatic allocation and so you are less likely to create a memory leak. This is currently experimental status; you can use boost::optional instead if your compiler doesn't have std::experimental::optional:
#include <experimental/optional>
using std::experimental::optional;
using std::experimental::in_place;
// ...
optional<ClassA> a;
try
{
a = optional<ClassA>(in_place, s);
}
catch(...)
{
// display message or something
}
std::string result;
if ( a )
result = a->GetSomething();
I'd like to reiterate though that this is a bit of a spaghetti style and it'd be better to design your code differently so you aren't continually testing whether construction succeeded or failed.
This requires ClassA be movable or copyable. The in_place is a special argument which invokes a perfect forwarding constructor for the remaining arguments. Without in_place you can only give an actual ClassA as constructor argument, it doesn't consider implicit conversions to ClassA. (This is how optional avoids the ambiguity between copy-construction and list-initialization from object of the same type).

Late non-copyable member initialization

I'm trying to initialize a object's member that cannot be assigned nor copied. I need some other tasks to be performed first and the initialization depends on it, so I have to delay it.
#include <boost/process.hpp>
class A{
std::unique_ptr<boost::process::child> child_;
std::unique_ptr<boost::process::pistream> is;
A(std::string exec, boost::process::context process_context){
// Stuff that needs to be done first
// ...
child_ = std::make_unique<boost::process::child>(start_child(exec, process_context));
is = std::make_unique<boost::process::pistream>(child_->get_stdout()); // <- error
}
boost::process::child start_child(std::string exec, boost::process::context process_context);
};
The error I get from this is:
error C2280:
'std::basic_ios>::basic_ios(const
std::basic_ios> &)' : attempting to
reference a deleted function
If I understand this correctly, somewhere in that line a copy is happening, which isn't allowed.
The unique pointers are not required. I just use them to avoid another error (no default initialization) but I would be happy to accept suggestions both with or without them.
You can use boost::optional<> for lazy initialization like this.
Live On Coliru
#include <memory>
#include <boost/optional.hpp>
struct pistream { };
struct child {
pistream& get_stdout() { return is; }
pistream is;
};
struct context { };
class A {
std::unique_ptr<child> child_;
boost::optional<pistream&> is;
A(std::string, context) {
// Stuff that needs to be done first
// ...
child_ = std::make_unique<child>();
is = child_->get_stdout();
}
};
The problem is that std::unique_ptr wants ownership of the pistream, so it tries to take a copy, which as you have discovered isn't allowed. If you think about it, this makes sense: you certainly don't want std::unique_ptr<b::p::pistream> deleting _child's stream in its destructor.
The easiest solution would be to just use a regular, non-owning pointer instead, say:
class A{
std::unique_ptr<boost::process::child> child_;
boost::process::pistream* is = nullptr;
A(std::string exec, boost::process::context process_context){
// ...
child_ = std::make_unique<boost::process::child>(start_child(exec, process_context));
is = &child_->get_stdout();
}
};
Of course, you'd want to check that is is not nullptr before actually using it, but the same is true for a unique_ptr.