I am writing an implementation of the Haskell Maybe Monad in C++11.
However I got stuck when I tried to test the code. When I construt a value of the type with the pseudo constructor Just and then try to evaluate it with using the function fromJust (that should just "unpack" the value placed inside the Maybe) the program stops and eventually terminates silently.
So i tried to debug it; here is the output for the code of testMaybe.cpp:
c1
yeih2
value not null: 0xf16e70
I added a couple of print statements to evaluate where the program stops, and it seems to stop at the exact point where I dereference the pointer to return the value. (I have marked it in the code.)
At first I thought that the value in the maybe might have been deconstructed by the time i want to dereference the pointer, which, to my understanding, would result in undefined behaviour or termination. However, I was unable to find the place where that would have happened.
Can you please give me a hint on why this is happening?
testMaybe.cpp:
#include<iostream>
#include "Maybe.hpp"
using namespace std;
using namespace Functional_Maybe;
int main() {
Maybe<string> a{Maybe<string>::Just("hello") };
if(!isNothing(a)) cout << "yeih2 " << fromJust(a) << endl;
return 0;
}
Maybe.hpp
#pragma once
#include<stdexcept>
#include<iostream>
using namespace std;
namespace Functional_Maybe {
template <typename T>
class Maybe {
const T* value;
public:
Maybe(T *v) : value { v } {} //public for return in join
const static Maybe<T> nothing;
static Maybe<T> Just (const T &v) { cout << "c1" << endl; return Maybe<T> { new T(v) }; }
T fromJust() const {
if (isNothing()) throw std::runtime_error("Tried to extract value from Nothing");
cout << "\nvalue not null: " << value << " " << *value << endl;
// ^ stops here
return *value;
}
bool isNothing() const { return value==nullptr; }
~Maybe() { if (value != nullptr) delete value; }
};
template <typename T>
bool isNothing(Maybe<T> val) {
return val.isNothing();
}
template <typename T>
T fromJust(Maybe<T> val) {
return val.fromJust();
}
}
You class template Maybe owns resources (the dynamically allocated T), but does not follow the Rule of Three: the (implicitly defined) copy and move operations do shallow copies only, which leads to use-after-free and double-free problems. You should either implement proper copy and move operations (cosntructors and assignment operators) for your class, or use std::unique_ptr<const T> as the type of value, and remove your manual destructor (thereby following the preferred Rule of Zero).
Side note: have you looked into std::optional (or, in pre-C++17 versions, boost::optional)? They seem to be doing something very similar (or even identical) to your proposed class, and you might want to use them instead (or use them internally in your class if that suits you better). They might even be more efficient, using small object optimisation to avoid dynamic memory allocation in some cases.
Related
I am trying to track the value of a variable that I will input in an API function.
One option is to overload the assignment operator and put some code there. But how would I overload an assigment operator on a member variable of a class?
#include <iostream>
using namespace std;
template <class T>
class MonitoredVariable1
{
public:
MonitoredVariable1() { }
MonitoredVariable1(const T& value) : m_value(value) {}
operator T() const { return m_value; }
T val;
T& operator = (const T& value)
{
val = value;
m_value = value;
std::cout << "value updated" << " \n"; //THIS NEVER GET PRINTED!!!
return val;
}
private:
T m_value;
};
int main()
{
MonitoredVariable1<double> MonitoredVariable;
MonitoredVariable.val = 10.2;
std::cout << "main done..." << " \n";
return 0;
}
To monitor changes to the variable, you need to be assigning to the class, not the contained variable.
First, get rid of val. Only have the private m_value value. This way all accesses have to go thru your member functions that can track the changes.
operator= should return a reference to the class (return *this;), not the value.
Assignment is to the class object:
MonitoredVariable = 10.2;
You can only overload assignment on a class. But you can make that variable to be of a class type with overloaded assignment, like:
class Monitor {
class Monitored {
double x;
public:
Monitored &operator= (double v) {
std::cout << "Assigned " << v << std::endl;
x = v;
return *this; // don’t forget this!
}
operator double() const {
std::cout << "Accessed " << x << std::endl;
return x;
}
};
Monitored val;
};
You may need to overload more operators, and also to pass a reference to Monitor into val (there are tricks to calculate it instead if you’re short on memory).
You can (in modern C++) even overload the & operator, but unless the API function is a template, it has to return pointer. Watching for access through it is very environment-specific.
During debugging, you can usually set a memory watchpoint that will pause program execution on writing to, or even on reading from, a particular memory location (for GDB, see Setting Watchpoints; VS should have a similar feature). That requires hardware support (or debugger-interpreter which is insanely slow), though, so the overall number of watchpoints is often very limited.
Without a debugger, you may be able to make a one-shot watch using memory protection tricks (like protecting the page containing the variable, and unprotecting it on first SEGV) but that’s all too fragile for normal use.
My solution I gonna use to add “C++ Extension Methods” to JNI jobjects to make NDK code more readable like (Uniform Function Call Syntax) is:
Subclass the class that I want to add extension methods.
For invoking the “Extension Methods” make a pointer of type ExtensionsClass to point to OriginalClass - (Although the pointed object is’nt an ExtensionsClass).
The overload is minimal & we can access public methods of the Original class.
#include <iostream>
// Represents a class external to my source
class Person {
public:
Person(){
privateage = 20;
}
int age() { return privateage; }
private:
int privateage;
short anotherField;
};
class PersonExtensions : private Person {
public:
inline int size() { return 5 + age(); }
//NoFieldsOnExtensionClass
};
int main() {
Person person;
PersonExtensions* pE = (PersonExtensions*) &person;
std::cout << pE -> size() << std::endl;
std::cout << (*pE).size() << std::endl;
std::cout << sizeof(Person) << std::endl;
std::cout << sizeof(PersonExtensions) << std::endl;
return 0;
}
Do you think that this incorrect pointer assignment, since “Extension Method” only accessed public members of extended class & extension class don’t going to have any Field variables, can represent a problem in the future?
The size of the object are the same.
Thanks a lot.
This is undefined behaviour.
Yes that can break at any point.
Consider overloading ->* or something instead.
Or just using a free function.
If you really want infix notation:
template<class T, class F>
struct extension_method_t {
F f;
friend auto operator->*( T& t, extension_method_t const& self ) {
return [&t,&self](auto&&...args)->decltype(auto) {
return self.f( t, decltype(args)(args)... );
};
}
};
template< class T, class F >
extension_method_t<T,F> extension_method( F f ) {
return {std::move(f)};
}
then:
auto size = extension_method<Person>([](auto& person)->int{
return 5+person.age();
});
Person p;
std::cout << (p->*size)() << "\n"; // prints p.age()+5
here we don't have an extension method, but we do have an extension method pointer.
What you are doing in your question code is Undefined Behavior, so an especially an optimizing compiler might do really "fun" things with it. In other words, don't do it, it might break at any time even if it works when you test it. Only way to make sure it would actually work would be to examine the produced assembly code after each compilation to make sure it does what you want, and this is essentially impossible, so it is never safe.
You are using private inheritance. So for same effect you can just do this:
class PersonExtensions {
public:
PersonExtensions(Person *person) : _person(person) {}
inline int size() { return 5 + _person->age(); }
private:
Person *_person;
};
If you instead used public inheritance (so you could just call Person methods through PersonExtensions), then you'd need to add a getter for _person (for cases where real Person is needed), and/or add delegates for Person methods (for so called static polymorphism).
std::vector has the member function at() as a safe alternative to operator[], so that bound checking is applied and no dangling references are created:
void foo(std::vector<int> const&x)
{
const auto&a=x[0]; // What if x.empty()? Undefined behavior!
const auto&a=x.at(0); // Throws exception if x.empty().
}
However, std::unique_ptr lacks the corresponding functionality:
void foo(std::unique_ptr<int> const&x)
{
const auto&a=*x; // What if bool(x)==false? Undefined behavior!
}
It would be great, if std::unique_ptr had such a safe alternative, say member ref() (and cref()) which never returns a dangling reference, but rather throws an exception. Possible implementation:
template<typename T>
typename add_lvalue_reference<T>::type
unique_ptr<T>::ref() const noexcept(false)
{
if(bool(*this)==false)
throw run_time_error("trying to de-refrence null unique_ptr");
return this->operator*();
}
Is there any good reason why the standard doesn't provide this sort of thing?
unique_ptr was specifically designed as a lightweight pointer class with null-state detection (e.g. stated in optional in A proposal to add a utility class to represent optional objects (Revision 3))
That said, the capability you're asking is already in-place since operator* documentation states:
// may throw, e.g. if pointer defines a throwing operator*
typename std::add_lvalue_reference<T>::type operator*() const;
The pointer type is defined as
std::remove_reference<Deleter>::type::pointer if that type exists, otherwise T*
Therefore through your custom deleter you're able to perform any on-the-fly operation including null pointer checking and exception throwing
#include <iostream>
#include <memory>
struct Foo { // object to manage
Foo() { std::cout << "Foo ctor\n"; }
Foo(const Foo&) { std::cout << "Foo copy ctor\n"; }
Foo(Foo&&) { std::cout << "Foo move ctor\n"; }
~Foo() { std::cout << "~Foo dtor\n"; }
};
struct Exception {};
struct InternalPtr {
Foo *ptr = nullptr;
InternalPtr(Foo *p) : ptr(p) {}
InternalPtr() = default;
Foo& operator*() const {
std::cout << "Checking for a null pointer.." << std::endl;
if(ptr == nullptr)
throw Exception();
return *ptr;
}
bool operator != (Foo *p) {
if(p != ptr)
return false;
else
return true;
}
void cleanup() {
if(ptr != nullptr)
delete ptr;
}
};
struct D { // deleter
using pointer = InternalPtr;
D() {};
D(const D&) { std::cout << "D copy ctor\n"; }
D(D&) { std::cout << "D non-const copy ctor\n";}
D(D&&) { std::cout << "D move ctor \n"; }
void operator()(InternalPtr& p) const {
std::cout << "D is deleting a Foo\n";
p.cleanup();
};
};
int main()
{
std::unique_ptr<Foo, D> up(nullptr, D()); // deleter is moved
try {
auto& e = *up;
} catch(Exception&) {
std::cout << "null pointer exception detected" << std::endl;
}
}
Live Example
For completeness' sake I'll post two additional alternatives/workarounds:
Pointer checking for a unique_ptr via operator bool
#include <iostream>
#include <memory>
int main()
{
std::unique_ptr<int> ptr(new int(42));
if (ptr) std::cout << "before reset, ptr is: " << *ptr << '\n';
ptr.reset();
if (ptr) std::cout << "after reset, ptr is: " << *ptr << '\n';
}
(This would probably be the clanest way to deal with the issue)
An alternative solution, although messier, is to use a wrapper type which takes care of the exception handling
I suspect the real answer is simple, and the same one for lots of "Why isn't C++ like this?" questions:
No-one proposed it.
std::vector and std::unique_ptr are not designed by the same people, at the same time, and are not used in the same way, so don't necessarily follow the same design principles.
I can't say, why the committee decided not to add a safe dereferenciation method - the answer is probably "because it wasn't proposed" or "because a raw pointer hasn't one either". But it is trivial to write a free function template on your own that takes any pointer as an argument, compares it against nullptr and then either throws an excepion or returns a reference to the pointed to object.
If you don't delete it via a pointer to base class, it should be even possible to derive publicly from a unique_ptr and just add such a member function.
Keep in mind however that using such a checked method everywhere might incur a significant performance hit (same as at). Usualy you want to validate your parameters at most once, for which a single if statement at the beginning is much better suited.
There is also the school that says you should not throw exceptions in response to programming errors. Maybe the peopke in charge of designing unique_ptr belonged to this school, while the people designing vector(which is much much older) didn't.
One of the main goals of a smart pointer API design is to be a drop-in replacement with added value, no gotchas or side effects, and close to zero overhead. if (ptr) ptr->... is how safe access to bare pointer is usually done, the same syntax works nicely with smart pointers thus requiring no code change when one is replaced with the other.
An additional check for validity (say, to throw an exception) put inside a pointer would interfere with branch predictor and thus may have a knock-on effect on the performance, which may not be considered a zero cost drop-in replacement anymore.
You do have
operator bool()
Example from:
cplusplusreference
// example of unique_ptr::operator bool
#include <iostream>
#include <memory>
int main () {
std::unique_ptr<int> foo;
std::unique_ptr<int> bar (new int(12));
if (foo) std::cout << "foo points to " << *foo << '\n';
else std::cout << "foo is empty\n";
if (bar) std::cout << "bar points to " << *bar << '\n';
else std::cout << "bar is empty\n";
return 0;
}
unique_ptr is a simple wrapper to a raw pointer, no need to throw an exception when you can just check a boolean condition easily.
Edit:
Apparently operator* can throw.
Exceptions
1) may throw, e.g. if pointer defines a throwing operator*
Maybe someone could shed some lights on hot to define a throwing operator*
Following from the suggestion of MikeMB, here is a possible implementation of a free function for dereferencing pointers and unique_ptrs alike.
template<typename T>
inline T& dereference(T* ptr) noexcept(false)
{
if(!ptr) throw std::runtime_error("attempt to dereference a nullptr");
return *ptr;
}
template<typename T>
inline T& dereference(std::unique_ptr<T> const& ptr) noexcept(false)
{
if(!ptr) throw std::runtime_error("attempt to dereference an empty unique_ptr)");
return *ptr;
}
I have created a type list. I then create a class using a template passing the type list. When I call the print function of the class with a some types not specified they are casted. How can I enforce the exact type at compile time? So if I use an unlisted type I get a compiler error.
Thanks.
template <class T, class U>
struct Typelist
{
typedef T Head;
typedef U Tail;
};
class NullType
{
};
typedef Typelist<int,Typelist<float,Typelist<char*,NullType> > > UsableTypes;
template<class T>
class MyClass
{
public:
void print(T::Head _Value) { std::cout << _Value; }
void print(T::Tail::Head _Value) { std::cout << _Value; }
void print(T::Tail::Tail::Head _Value) { std::cout << _Value; }
private:
};
MyClass<UsableTypes> testclass;
void TestMyClass()
{
int int_val = 100000;
float flt_val = 0.1f;
char* char_val = "Hi";
short short_val = 10;
std::string str_val = "Hello";
testclass.print( int_val ); // OK 8-)
std::cout << endl;
testclass.print( flt_val ); // OK 8-)
std::cout << endl;
testclass.print( char_val ); // OK 8-)
std::cout << endl;
testclass.print( short_val); // this compiles OK and works ??? 8-(
std::cout << endl;
testclass.print( str_val ); // compile error 8-)
std::cout << endl;
}
#Kerrek SB: Hi I thought it was going to help me with my next step, which was creating the print function depending on the t_list contents, Types and amounts of types. But I'm struggling to separate compile time processing and runtime processing. What I am trying to do is create a print function for each type in the list. So if the list has two types, two print functions will be created and if there are five types then five print functions will be created one for each type.
When I do this:
typedef Typelist<int,Typelist<float,Typelist<char*,NullType> > > UsableTypes;
MyClass<UsableTypes> newclass
Does this create three instance of MyClass one for each type in the list or does it create one instance and I have to create a print function for each type?
I feel I almost have all the blocks in my mind but just can’t fit them together. Any help you can offer would be gratefully received. Thanks.
Add a private function template
template<typename T> void print(T);
which doesn't need an implementation. This should catch all types for which no explicit print exists, and since it is private, it will give an error message.
You would have to make your print function into a template and then check whether the types match:
template <typename U>
void print(const U & u)
{
// use std::is_same<typename std::decay<T::Head>::type, typename std::decay<U>::type>::value
}
Here I'm stealing is_same and decay from <type_traits>, but if you don't have C++11, you can either take them from TR1 or from Boost, or just write them yourself, as they're very simple type modifier classes.
The conditional would best go into a static_assert, which is another C++11 feature, but there exist similar constructions for C++98/03 that produce a compile-time error under a certain condition.
You could take your arguments by non-const reference, forcing them to be the exact same type. However you can no longer use it with const variables or literals.
My target was to make properties in C++ like in C# - with non-trivial set/get behavior.
Here, object of Property holds refs to master of the prop and its set/get methods.
Realisation, content of Property.h:
#include <iostream>
using namespace std;
namespace First {
template <class Master, class Type>
struct Property
{
Master &master;
const Type (Master::*&get) () const;
Type (Master::*&set)(Type value);
Property
(
Master &master,
const Type (Master::*get) () const,
Type (Master::*set)(Type value)
):
get(get),
set(set),
master(master)
{ }
operator const Type() const { cout << "inside" << endl; return (master.*get)(); }
Type operator = (Type value)
{
return (master.*set)(value);
}
};
// Test chamber.
class R
{
float x;
const float getx() const { cout << "returning " << 0 << endl; return 0; }
float setx(float value) { cout << "setting " << value << " in place of " << x << endl; return x = value; }
public:
Property<R, float> X;
R(): X(*this, &R::getx, &R::setx) { }
};
}
I also created .cpp file:
#include "Property.h"
using namespace First;
int main()
{
R r;
r.X = 10;
float y = r.X;
}
The program makes "assign" step, printing 'setting 0 to 10', but segfaults on call to "retrieve" step, no difference what code (or no at all) inside 'R::getx()'.
~/Sources$ ./a.out
setting 10 in place of 0
inside
zsh: segmentation fault ./a.out
It seems that call to (master.*get()) itself causes a failure. What is wrong in this code?
UPD: A tested out that any other call to master's functions leads to segfault, only one call of (master.*set) successes. Seems that this call invalidates state of object, member-to-ptr, Property itself or Moon phase.
const Type (Master::*&get) () const;
Type (Master::*&set)(Type value);
Remove & from the above definitions. Because of &, each of these bound to the constructor parameters which do not exist after the constructor returns.
Also note that it seems that (master.*set)(value) works, its because you're unlucky. Its actually invokes undefined behavior. But you're lucky that very soon you come to know the problem when (master.*get)() fails, giving segfault.
Use:
const Type (Master::*get) () const;
Type (Master::*set)(Type value);
It should work now, without any problem, as it would cause copy of the addresses in the initialization-list, rather than referring to the parameters!
segfault : http://ideone.com/46RrU (your original code)
no fault : http://ideone.com/PljI4 (after fixing)