prohibiting instantiation as a temporary object (C++) - c++

I like using sentry classes in c++, but I seem to have a mental affliction that results in repeatedly writing bugs like the following:
{
MySentryClass(arg);
// ... other code
}
Needless to say, this fails because the sentry dies immediately after creation, rather than at the end of the scope, as intended. Is there some way to prevent MySentryClass from being instantiated as a temporary, so that the above code either fails to compile, or at least aborts with an error message at runtime?

I can't think of an automatic way to detect if you make this mistake or not. You could always create a macro that expands to the correct thing and use that to declare the sentry instead if you keep using it wrong.
#define MY_SENTRY_CLASS(_X) MySentryClass _sentry(_X)
and then use
MY_SENTRY_CLASS(arg);
or put a post-it on your monitor to remind you.

The only thing you could do is make the constructors private and force access through a helper function. This is far less similar than the initial construction syntax and less likely to be mistaken. You could also allocate on the heap (still a waste) but it's much easier to spot. However, if you want your class to be constructible, you can't stop people constructing rvalues of that type.
Edit: IF you know that MySentryClass always takes an argument, you could disallow construction AND and only allow operator=(arguments). This would force you to do
MySentryClass x;
x = arg;
You could do some kind of method chain for it.
MySentryClass x;
x.SetArg1(arg).SetArg2(arg2).construct();

No, there is no exit from this problem. To make objects on the stack, you have to have public constructors, and if you have public constructors, you can make the mistake you are reporting.

Not sure you'll like this solution, but the solution may well be grep:
find /path/to/project -type f -name \*.cpp -print0 | xargs grep -0 'MySentryClass('
Another thing you could do is use sed or perl to preprocess your source file, replacing MySentryClass( with \n#error MySentryClass used incorrectly\n, which hopefully will give you a line number that's close to where the error is. How to do this depends on your build system.

I think the #define is the best method.
But just as an option for not using #define:
Main
int main()
{
try
{
S arg1;
// This will not compile
// MySentry x1 = MySentry::CreateSentry(arg1);
S arg3;
MySentry x2(MySentry::CreateSentry(arg3));
S arg2;
// This will not compile
// MySentry(arg2);
S arg4;
// This will generate a runtime exception
// It will never call start() or end()
//MySentry::CreateSentry(arg4);
}
catch(std::exception const& e)
{
std::cout << "Exception : " << e.what() << "\n";
}
}
Edited. Now works better.
#include <stdexcept>
#include <iostream>
class S
{
public:
void start() {std::cout << "Start\n";}
void end() {std::cout << "End\n";}
};
class MySentry
{
struct Init
{
Init(S& s) : arg(s),bad(true) {}
~Init() {if (bad) {throw std::runtime_error("Bad usage of MySentry");}}
S& arg;
mutable bool bad;
};
public:
static Init CreateSentry(S& arg) { return Init(arg);}
explicit MySentry(Init const& arg)
: obj(arg.arg)
, bad(false)
{
arg.bad = false;
std::cout << "Created\n";
obj.start();
}
MySentry(MySentry const& rhs)
: obj(rhs.obj)
, bad(false)
{
std::cout << "Copied (this may not appear)\n";
std::cout << "If the optimizer kicks in then the copy may be elided.\n";
// But if it did not optimize out then
// We have to mark the temporaty as bad
// And not call end() in its destructor.
// Note: Never call start() here as it will always be called in the
// main private constrctor above
rhs.bad = true;
}
~MySentry()
{
if (!bad)
{
// Everything working
obj.end();
}
std::cout << "Destroyed\n";
}
private:
S& obj;
mutable bool bad;
};

What you are trying to do is perfectly legal in C++ and I don't think there is a way to disallow it.

Related

How to detect mid-function value changes to const parameter?

I ran into a nasty bug in some of my code. Here's the simplified version:
#include <iostream>
class A
{
public:
std::string s;
void run(const std::string& x)
{
// do some "read-only" stuff with "x"
std::cout << "x = " << x << std::endl;
// Since I passed X as a const referece, I expected string never to change
// but actually, it does get changed by clear() function
clear();
// trying to do something else with "x",
// but now it has a different value although I declared it as
// "const". This killed the code logic.
std::cout << "x = " << x << std::endl;
// is there some way to detect possible change of X here during compile-time?
}
void clear()
{
// in my actual code, this doesn't even happen here, but 3 levels deep on some other code that gets called
s.clear();
}
};
int main()
{
A a;
a.s = "test";
a.run(a.s);
return 0;
}
Basically, the code that calls a.run() use to be used for all kinds of strings in the past and at one point, I needed the exact value that object "a.s" had, so I just put a.s in there and then some time later noticed program behaving weird. I tracked it down to this.
Now, I understand why this is happening, but it looks like one of those really hard to trace and detect bugs. You see the parameter declared as const & and suddenly it's value changes.
Is there some way to detect this during compile-time? I'm using CLang and MSVC.
Thanks.
Is there some way to detect this during compile-time?
I don't think so. There is nothing inherently wrong about modifying a member variable that is referred by a const reference, so there is no reason for the compiler to warn about it. The compiler cannot read your mind to find out what your expectations are.
There are some usages where such wrong assumption could result in definite bugs such as undefined behaviour that could be diagnosed if identified. I suspect that identifying such cases in general would be quite expensive computationally, so I wouldn't rely on it.
Redesigning the interface could make that situation impossible For example following:
struct wrapper {
std::string str;
};
void run(const wrapper& x);
x.str will not alias the member because the member is not inside a wrapper.

Delayed update with proxy objects vs. "Avoid unnamed objects with custom construction and destruction"

I have a class complicated which features various setters that modify some internal state. That internal state modification is potentially expensive, so I want to do it not too often. In particular, if several setters are invoked in immediate succession, I want to perform the expensive update of the internal state only once after the last of these setter invocations.
I have solved (or "solved"?) that requirement with a proxy. The following would be a minimal working code example:
#include <iostream>
class complicated
{
public:
class proxy
{
public:
proxy(complicated& tbu) : to_be_updated(&tbu) {
}
~proxy() {
if (nullptr != to_be_updated) {
to_be_updated->update_internal_state();
}
}
// If the user uses this operator, disable update-call in the destructor!
complicated* operator->() {
auto* ret = to_be_updated;
to_be_updated = nullptr;
return ret;
}
private:
complicated* to_be_updated;
};
public:
proxy set_a(int value) {
std::cout << "set_a" << std::endl;
a = value;
return proxy(*this);
}
proxy set_b(int value) {
std::cout << "set_b" << std::endl;
b = value;
return proxy(*this);
}
proxy set_c(int value) {
std::cout << "set_c" << std::endl;
c = value;
return proxy(*this);
}
void update_internal_state() {
std::cout << "update" << std::endl;
expensive_to_compute_internal_state = a + b + c;
}
private:
int a;
int b;
int c;
int expensive_to_compute_internal_state;
};
int main()
{
complicated x;
x.set_a(1);
std::cout << std::endl;
x.set_a(1)->set_b(2);
std::cout << std::endl;
x.set_a(1)->set_b(2)->set_c(3);
}
It produces the following output which is looking like exactly what I wanted:
set_a
update
set_a
set_b
update
set_a
set_b
set_c
update
My questions are: Is my approach legit/best practice?
Is it okay to rely on temporary objects (i.e. the proxy objects which are returned) which will be destroyed at the semicolon?
I'm asking because I have a bad feeling about this for some reason. Maybe my bad feeling comes just from Visual Studio's warning which says:
Warning C26444 Avoid unnamed objects with custom construction and
destruction (es.84).
But maybe/hopefully my bad feelings are unjustified and that warning can just be ignored?
What bothers me the most: Is there any case in which the update_internal_state method will NOT be called (maybe by misusing my class or by some compiler optimization or whatever)?
Lastly: Is there any better approach to implement what I try to achieve with modern C++?
I think your solution is legit, but it has a drawback that it hides from the user of the code, that the update is expensive, so one will more likely write:
x.set_a(1);
x.set_b(2);
than
x.set_a(1)->set_b(2);
I would suggest make setters private and add a friend transaction class, so that modifying object would look like:
complicated x;
{
transaction t(x);
t.set_a(1);
t.set_b(2);
// implicit commit may be also done in destructor
t.commit();
}
If transaction will be the only way to modify complicated - users will more tend to call several setters in a one transaction.
The danger I see here is if your class has any methods that do not return a proxy (or any public members). You disable the update call if operator-> of the proxy is used (which yields the complicated), but this is only safe if that usage of operator-> always yields another proxy object which will take over the updating task. This seems like a huge pitfall for anybody who modifies the class later on.
I think it would be safer if complicated were to keep track of the number of alive proxy objects created on it so that the last proxy to be destroyed performs the update call.
Following Dmitry Gordon's argument of people selecting 'wrong' approach, you might have the matter a bit simpler, though (especially from user's view):
class Demo
{
int m_x
int m_y; // cached value, result of complex calculation
bool m_isDirtyY;
public:
int x() { return m_x; }
void x(int value) { m_x = value; m_isDirtyY = true; }
int y()
{
if(m_isDirtyY)
{
// complex calculations...
m_y = result;
m_isDirtyY = false;
}
return m_y;
}
};
This way, you'll only ever execute the calculations on need, no additional extensions like the proxy objects or explicit transactions.
Depending on your needs, you might perhaps encapsulate this pattern in a separate (template?) class, perhaps receiving an updater object (lambda?) or with a pure virtual update function to repeat less code.
Side note: Setting a value might invalidate more than one cached value – no problem, set more than one dirty flag to true then...

Relying on deterministic destruction, avoiding destruction on return

I have been trying to rework my logging class. However, I'm facing a problem.
I want to expose this interface to users:
mylog() << "hello";
The idea is that mylog is an instance of Logger, which defines some useful characteristics for a defined log type. Its operator() function would return an instace of type LogStream. However, I would like to output the newline character automatically at the end, so I had the idea to do that in LogStream's destructor.
My current implementation looks like this (LogStream and Logger being largely dumbed down):
#include <iostream>
struct LogStream
{
~LogStream() { std::cout << '\n'; }
template<class T>
LogStream& operator<<(const T& t)
{
std::cout << t;
return *this;
}
};
struct Logger
{
LogStream operator()()
{
return LogStream{} << "message: ";
}
};
int main()
{
Logger log;
log() << "hello!";
}
Interstingly, I figured out with this piece of code that my previous implementation depended on RVO. The compiler was always performing copy-elision, so the destructor did behave the way I want. However, with this piece of code, the newline character is being printed twice, because the copy constructor is being called when the copy occurs in operator().
The problem disappears when I do not return the temporary instance, and instead put this in operator()'s body:
LogStream stream;
stream << "message: ";
return stream;
Now the RVO makes it work the way I want.
I later on = delete'd the copy constructors, because it made more sense anyway, which effectively causes the code to fail to compile.
What are my options to provide the interface I want, without using the hacky solution to rely on RVO?
Add a constructor to LogStream that takes a char const *.
LogStream(char const* c) { std::cout << c; }
Then, instead of creating a temporary LogStream within operator(), use list-initialization to initialize the return value itself.
LogStream operator()()
{
return {"message: "};
}
The temporary is thus avoided along with the extra new line.
Live demo (note that even using -fno-elide-constructors to disable copy elision doesn't result in the extra newline).

How to preload data before main

My goal is to quickly deal with various race conditions that can cause problems if a given function is called in 2 separate threads around the same time. My quick-fix is to just guarantee the functions have been initialized by calling them before main(). This is the solution I've come up with, but I feel I'm likely re-inventing the wheel. Is there an already-available option in the MSVC2010 STL? (no boost, yet) Or is there perhaps a better way to quickly deal with these issues without having to add significant thread safety code to each function in this situation?
template <typename T, T func>
struct PreLoaderHelper
{
PreLoaderHelper()
{
wcout << L"Preload helper constructor" << endl;
func();
}
};
template <typename T, T func>
struct PreLoader
{
static PreLoaderHelper<T, func> _helper;
};
template <typename T, T func>
PreLoaderHelper<T, func> PreLoader<T, func>::_helper;
#define PRELOAD(fn) template struct PreLoader<decltype(&fn), fn>;
void foo() { wcout << L"inside foo" << endl; }
void bar() { wcout << L"inside bar" << endl; }
vector<wstring> & foobar()
{
static vector<wstring> sPresidents;
if(sPresidents.size() == 0)
{
sPresidents.push_back(L"George Washington");
sPresidents.push_back(L"John Addams");
sPresidents.push_back(L"Thomas Jefferson");
}
return sPresidents;
}
wstring foofoo(const wstring &) { wcout << L"inside foofoo" << endl; return L"foofoo";}
PRELOAD(foo);
PRELOAD(bar);
PRELOAD(foobar);
PRELOAD(foo);
int main()
{
return 0;
}
The first question: do you really have to call them before
entering main? Why not just call them the first thing in main,
before starting any threads?
Otherwise: the classical idiom is to use them in an initializer
to a static variable. The usual way is to call them from a
constructor; if you have additional data which must be
initialized, this is doubtlessly the best way. If not,
something as simple as:
static bool initialized = (function(), true);
will do the trick.
Formally, this only guarantees that they will be initialized
before anything else in the same translation unit has been used,
but practically, this will guarantee that the function is called
before main, or during the loading of the DLL, if it is in a DLL
other than the one with main.
You can do this:
int dummy = (foo(), (void)0, bar(), 0);
int main()
{
// foo() and bar() have already been called
}
Furthermore, C++11 guarantees that the following variant causes only one single call, race-free:
void call_foo()
{
static int dummy = (call_foo(), 0);
}
void some_thread_function() { call_foo(); }
If you are using C++11 then remember that:
static function variable initialization is thread safe.
You can use list initialization semantics.
Try:
std::vector<std::wstring>& plop1()
{
// Thread safe
// Guaranteed to be done once
// No setup required
// No cost if not used.
static std::vector<std::wstring> sPresidents =
{
L"George Washington",
L"John Addams",
L"Thomas Jefferson"
};
return sPresidents;
}
I would highly recommend using proper synchronization using critical sections for your situation. Entering and exiting critical sections does not add a lot of code and handles the situation gracefully.
In case you do not want to continue with your original approach of initializing functions before main(), you can use global variable initialization as it occurs prior to main function call. There is a nice article about this approach at
http://blog.fishingcactus.com/index.php/2009/01/28/fixing-c-static-and-global-variable-initialization/#sthash.pmBtrYD8.dpbs

Duplicating C/C++ functions at compile time

If I have a function A(), I am interested in finding a convenient method to create a function B() that has the exact same functionality as A(), differing only in name. The new function would be for a one-time use. The intent is to differentiate between calls to the same function in a somewhat primitive sampling profiler, and the duplicated function would only be used in this context. That is, it would never touch production code and only be used for tinkering.
First guess would be a macro that declares a function named B and creates an inlined call to A() inside of it. The problem here is that I'm not aware of a method in GCC to force an arbitrary function call to inline; it seems all inlining options are for function declarations rather than calls.
There may be some esoteric way to do it with templates, or possibly by tricking the compiler into inlining. I'm not sure it's possible. Any thoughts? Unfortunately the new C++ standard is not available, if it would make a difference.
Using templates
template<int x>
void A()
{
// ..
}
int main()
{
A<0>();
A<1>();
return 0;
}
Update
The compiler can be too smart and create only one body for A<0> and A<1>. At least Visual C++ 2010 does it in Release mode. To prevent it, just use the template parameter inside the function template body in logs or asserts. For example,
#include <iostream>
template<int x>
void A()
{
::std::cout << x << std::endl;
// ..
}
int main()
{
A<0>();
A<1>();
auto v0 = A<0>;
auto v1 = A<1>;
::std::cout << v0 << std::endl;
::std::cout << v1 << std::endl;
::std::cout << (v0 == v1) << std::endl;
return 0;
}
This works using templates:
#include <iostream>
template<typename T>
void foo() {
static int x = 0;
std::cout << &x << std::endl;
}
int main(int argc, char **argv) {
foo<int>();
foo<float>();
return 0;
}
If you execute that, you'll see two different values printed, reflecting the compiler generated code for both calls, even though the template parameter is unused. nm on the object file confirms this.
If this is a one-time debug hack, then why not:
#define A_CONTENT \
... // whatever
void A()
{
A_CONTENT
}
void B()
{
A_CONTENT
}
...
A(); // Call to A
B(); // Call to B
Macros are generally grim, but we're not talking about production code here, so who cares?
Having been down this road myself, the short answer is that even if you get the compiler to emit two identical duplicates of a function, the optimizing linker will notice that they're identical and fold them back together into one implementation. (And if you've turned off optimization in the linker, then your profile isn't valid anwyay).
In the context of a sampling profiler, I've found the easier approach is to make two tiny wrappers for the function instead:
void Func() { .... }
_declspec(noinline)
void A_Func( return Func(); }
void B_Func( return Func(); }
void C_Func( return Func(); }
Then when your profiler samples the callstack, you'll be able to differentiate between the different callsites of this function in a very straightforward way..
You could always define a macro, for example in Chromium we do the following to reuse code:
#define CHROMEG_CALLBACK_1(CLASS, RETURN, METHOD, SENDER, ARG1) \
static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, \
gpointer userdata) { \
return reinterpret_cast<CLASS*>(userdata)->METHOD(sender, one); \
} \
\
virtual RETURN METHOD(SENDER, ARG1);
And we call them like:
CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnExposeEvent, GdkEventExpose*);
CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnButtonPressed, GdkEventButton*);
You can do something similar to do what you wanted. The above example shows us using two different implementations but with one common code base. For GTK callbacks.
It's a little unclear what you're really trying to do, but a really ugly solution would be to declare the body of A as a macro and then you can "inline" this macro within whatever functions you like.
Also, macros are evil. Never use them unless you really have to.
Why do you care so much about inlining it? If you create a wrapper function, there is a pretty good chance the compiler will inline it anyway. At the very least, you're unlikely to get a function frame constructed.
C++11 also lets you do this:
void A() {
...
}
...
auto B = [] () -> void { A(); };
You can now use B syntactically as though it was a function wrapping A.