How can I catch (get warned about) an unnamed local object? [duplicate] - c++

While debugging crash in a multithreaded application I finally located the problem in this statement:
CSingleLock(&m_criticalSection, TRUE);
Notice that it is creating an unnamed object of CSingleLock class and hence the critical section object gets unlocked immediately after this statement. This is obviously not what the coder wanted. This error was caused by a simple typing mistake. My question is, is there someway I can prevent the temporary object of a class being created at the compile time itself i.e. the above type of code should generate a compiler error. In general, I think whenever a class tries to do some sort of resource acquisition then the temporary object of that class should not be allowed. Is there any way to enforce it?

Edit: As j_random_hacker notes, it is possible to force the user to declare a named object in order to take out a lock.
However, even if creation of temporaries was somehow banned for your class, then the user could make a similar mistake:
// take out a lock:
if (m_multiThreaded)
{
CSingleLock c(&m_criticalSection, TRUE);
}
// do other stuff, assuming lock is held
Ultimately, the user has to understand the impact of a line of code that they write. In this case, they have to know that they're creating an object and they have to know how long it lasts.
Another likely mistake:
CSingleLock *c = new CSingleLock(&m_criticalSection, TRUE);
// do other stuff, don't call delete on c...
Which would lead you to ask "Is there any way I can stop the user of my class from allocating it on the heap"? To which the answer would be the same.
In C++0x there will be another way to do all this, by using lambdas. Define a function:
template <class TLock, class TLockedOperation>
void WithLock(TLock *lock, const TLockedOperation &op)
{
CSingleLock c(lock, TRUE);
op();
}
That function captures the correct usage of CSingleLock. Now let users do this:
WithLock(&m_criticalSection,
[&] {
// do stuff, lock is held in this context.
});
This is much harder for the user to screw up. The syntax looks weird at first, but [&] followed by a code block means "Define a function that takes no args, and if I refer to anything by name and it is the name of something outside (e.g. a local variable in the containing function) let me access it by non-const reference, so I can modify it.)

First, Earwicker makes some good points -- you can't prevent every accidental misuse of this construct.
But for your specific case, this can in fact be avoided. That's because C++ does make one (strange) distinction regarding temporary objects: Free functions cannot take non-const references to temporary objects. So, in order to avoid locks that blip into and out of existence, just move the locking code out of the CSingleLock constructor and into a free function (which you can make a friend to avoid exposing internals as methods):
class CSingleLock {
friend void Lock(CSingleLock& lock) {
// Perform the actual locking here.
}
};
Unlocking is still performed in the destructor.
To use:
CSingleLock myLock(&m_criticalSection, TRUE);
Lock(myLock);
Yes, it's slightly more unwieldy to write. But now, the compiler will complain if you try:
Lock(CSingleLock(&m_criticalSection, TRUE)); // Error! Caught at compile time.
Because the non-const ref parameter of Lock() cannot bind to a temporary.
Perhaps surprisingly, class methods can operate on temporaries -- that's why Lock() needs to be a free function. If you drop the friend specifier and the function parameter in the top snippet to make Lock() a method, then the compiler will happily allow you to write:
CSingleLock(&m_criticalSection, TRUE).Lock(); // Yikes!
MS COMPILER NOTE: MSVC++ versions up to Visual Studio .NET 2003 incorrectly allowed functions to bind to non-const references in versions prior to VC++ 2005. This behaviour has been fixed in VC++ 2005 and above.

I don't think so.
While it's not a sensible thing to do - as you've found out with your bug - there's nothing "illegal" about the statement. The compiler has no way of knowing whether the return value from the method is "vital" or not.

Compiler shouldn't disallow temporary object creation, IMHO.
Specially cases like shrinking a vector you really need temporary object to be created.
std::vector<T>(v).swap(v);
Though it is bit difficult but still code review and unit testing should catch these issues.
Otherwise, here is one poor man's solution:
CSingleLock aLock(&m_criticalSection); //Don't use the second parameter whose default is FALSE
aLock.Lock(); //an explicit lock should take care of your problem

No, there is no way of doing this. Doing so would break almost all C++ code which relies heavily on creating nameless temporaries. Your only solution for specific classes is to make their constructors private and then always construct them via some sort of factory. But I think the cure is worse than the disease!

You can cause a compiler warning using [[nodiscard]]
class CSingleLock {
public:
[[nodiscard]] CSingleLock (std::mutex*, bool) { }
};
If you create a temporary clang will warn you saying:
warning: ignoring temporary created by a constructor declared with 'nodiscard' attribute [-Wunused-value]
CSingleLock(&m, true);
^~~~~~~~~~~~~~~~~~~~~
GCC 9.3 seems to have a problem with [[nodiscard]] on constructors though. It still gives additional warnings if you don't use the result. The problem is fixed in gcc 10+ and it produces a similar (but less-specific) warning.
Another possible solution: by define a macro function with the same name as the class, you can trigger a static assertion with a helpful message when someone forgets the variable name. live here
class CSingleLock {
public:
CSingleLock (std::mutex*, bool) { }
};
// must come after class definition
#define CSingleLock(...) static_assert(false, \
"Temporary CSingleLock objects are forbidden, did you forget a variable name?")
The macro won't match when there is a variable name. However, this doesn't help in the case of uniform initialization; you can't catch CSingleLock{&m, true}. PfhorSlayer's answer works with uniform initialization so it is safer to use, at the cost of a more confusing error message. I would still reccomend that solution over mine. Unfortunately all these macro solutions fail when the type is in a namespace.

I see that in 5 years nobody has come up with the most simple solution:
#define LOCK(x) CSingleLock lock(&x, TRUE);
...
void f() {
LOCK(m_criticalSection);
And now only use this macro for creating locks. No chance to create temporaries any more! This has the added benefit that the macro can be easily augmented to perform any kind of checking in debug builds, for example detecting inappropriate recursive locking, recording file and line of the lock, and much more.

What about the following? Slightly abuses the preprocessor, but it's clever enough that I think it should be included:
class CSingleLock
{
...
};
#define CSingleLock class CSingleLock
Now forgetting to name the temporary results in an error, because while the following is valid C++:
class CSingleLock lock(&m_criticalSection, true); // Compiles just fine!
The same code, but omitting the name, is not:
class CSingleLock(&m_criticalSection, true); // <-- ERROR!

Related

Compile time check for consecutive functions call

Suppose we have a class like this:
class OProcess {
...
void Process1();
void Process2(); // call only if Process1 wasn't called
...
}
such that function Process2() can be called only when function Process1() has NOT been called already.
Is there a way to check that Process class is used correctly at compile-time? I.e. compiler must give an error if Process1() CAN BE called before Process2() for some instance of OProcess object.
P.S. I understand that there can be code like this:
if (variable == 1000)
Process1();
Process2();
and compiler can't be sure that Process1() will be called before Process2(). But here compiler can be sure that Process1() CAN be called before Process2() for some values of variable. And I need it to make an error or at least warning.
The short answer is Somewhat.
The long answer is: C++ does not implement Linear Typing, thus uniqueness checks cannot be done at compile-time (fully). Still, reading this description gives us a trick: to implement this in the compiler, language designer forbid aliasing and enforce consumption.
So, if you agree that some runtime checks are allowed, then this can be done by having processes consume the object:
class OProcess {
public:
};
std::unique_ptr<OProcessed1> process1(std::unique_ptr<OProcess> op);
std::unique_ptr<OProcess> process2(std::unique_ptr<OProcess> op);
Where OProcessed1 is a proxy over OProcess presenting a restricted interface that exposes only those operations allowed on OProcess after that Process1 was called.
The runtime part of the checks is that:
void func(std::unique_ptr<OProcess> op) {
process1(std::move(op));
process2(std::move(op));
}
will compile, even though it is undefined behavior to do anything other than destruction/assignment to op after moving from it.
The correct way to do it is either make init private and reduce the risk you mention,
or use dependency injection, as 'init' methods, or any logic at all inside the constructor, are bad practice in terms of clean code
Another trick is to have ProcessBase that defines init and calls it in it's constructor. ProcessBase's constructor is called before the derived constructor, thus making sure that init is called before any logic is made in the derived class.
Edit:
You may want to change the logic to have both methods private and have one method called process3() that will call the other methods in the correct order.
Another option is to use the decorator design pattern and wrap one method in a class and have your decorator call them by order.

What are the consequences of having a static pointer to this

I have a class that contains functions that need to run as threads. The proper way to do this (form what I understand) is have these functions declared as static. To use methods from this class I need a to have an instance to that class, so I create a static variable that is initialized to self in the constructor. What are the implications in efficiency and program logic?
class Foo
{
private: Foo* this_instance;
Foo()
{
this_instance=this;
}
void FooBar()
{
...
}
static void* Bar()
{
if (this_instance==NULL) return 1; //throws are not catched are they?
this_instance->FooBar();
return 0;
}
}
Not actual code but to make my question clearer.
The application actually works and I checked it with helgrind/memcheck and the errors are not related to the issue at hand. I'm asking this question because all solutions seem like workarounds, including this one. Others are like the one mentioned by doctor love, other using helper static method.
I am wondering if my approach would result in epic failures at some point in time, for some reason unknown to me and obvious to other more experienced programmers.
You do not need functions to be static to use them in threads. You could bind instance functions or pass the this pointer, or use C++11 with a lambda.
If you use raw threads you will have to catch exceptions in the thread - they will not propagate to the code that started the thread.
In C++11 you can propagate the exceptions, using current_exception and rethrow_exception. See here
EDIT
If you have a static pointer for each type, you can only have one instance of it, yet your code does nothing to prevent the static pointer being reset. Why bother having a class instance in the first place - surely just pass in the parameters? I think it's cleaner to have free functions to do the work. If you think it's not worth the effort, it's your code. What do your co-workers think of your design?

What is easiest way to force compiler to throw error?

To the folks marking this as duplicate: it is not; the other question addresses enums which are compile-time constants. This is not a constant integral expression thus the solution would be very different. Please see my code below more carefully before suggesting this has already been answered in another question, as it has not in any way. I am checking the value of a member variable on an object, information created at runtime, and I'm curious what I can do with that in this context.
I'm at a point where I need to use something to make the compiler fail if the user of my API does something she should not.
I don't know if that's possible, it is? The options I mention above are primarily run-time, right?
For example, suppose you have a function:
void doSomethingIncredible(AwesomeClass amazingObject)
{
//perform life-changing work here except:
if (amazingObject.isntAmazing) //a bool property of object
//uh oh, life sucks, I refuse to compile this
Now calling this function will change how you live your life in all respects, except for occasions in which amazingObject has a particular property switched on, for example, in which case, I want the compiler to not even allow this to pass, i.e. cannot run the program.
Somewhere in the body of the function is a c++ mechanism that forces compiling to fail, which alerts the user that you cannot use this function for such an inferior un-amazing object.
Is this possible?
To clarify, this is something I want to do a compile time based the contents of a variable, as shown in my example above. The suggestion to use static_assert does not apply here.
You can either static_assert() a condition at compile time (C++11)
static_assert(false, "Hey user! You suck!");
or use
#if (some_erroneous_condition_to_be_avoided)
#error "Hey user! You suck!"
#endif
if you have a GNU-compatible compiler (g++, clang++, etc.)
The only way I can see to get it compile time checked is to subclass AwesomeClass and restrict the new class' creation to only be able to create objects where amazingObject.isntAmazing is never true. Then change the signature to;
void doSomethingIncredible(AwesomeAndAmazingClass amazingObject)
That will prevent the call to the method for objects that are simply awesome but not amazing.
As a maybe more illustrative example (not compiled, so consider pseudo code);
class Thing {
protected:
Color _color;
Shape _shape;
public:
Thing(Color color, Shape shape) {
_color=color; _shape=shape;
}
}
class GreenThing : Thing {
public:
GreenThing(Shape shape) : Thing(Color.Green, shape) {}
}
void doSomethingIncredible(GreenThing specialThing)
{
// specialThing here is still a Thing, but also compile time
// checked to also always be a GreenThing
}
It is impossible. The value of the variable is decided at runtime, but you want to throw a compile-time error depending on the runtime value.

C++ Detecting an implicit cast of 0 to a class

I am calling a function in a API that returns a Answer object. Under some conditions, the API will return EMPTY_answer, which is defined as such:
#define EMPTY_answer ((Answer)0)
of course, attempting to access a Answer variable or function from an EMPTY_answer object crashes the application.
Trying to test for it using if(lAnswer == EMPTY_answer) also crashes the application. Is there any way to detect if the API is returning EMPTY_answer?
Edit:
I didn't code the api and I can't modify it in any way, I'm just digging through .h files trying to figure this out. And yes, I am aware that casting 0 to a class is a bit too creative to put it mildly. I just noticed that the == operator is overridden
(...)
class ExportedByJS0CORBA Answer
{
(...)
int __stdcall operator==(Answer *ipt) const;
}
the function being called is
static SubClassOfAction Query();
I'm simplifying names and quite a few layers of inheritance
To be more precise, it crashes with a Segmentation Fault.
Instead of doing a very ugly cast which is almost guaranteed to trigger undefined behavior, just make a static global variable which is used as the "empty" answer. You don't need to use this object in any way, just make it exist so it can be used as a sentinel.
In Answer.h:
extern const Answer EMPTY_answer;
In Answer.cpp:
const Answer EMPTY_answer; // use any constructor parameters that will be appropriate
If Answer is a class type, as the text of your questions suggest, then (Answer) 0 will construct a temporary Answer object using the constructor that accepts 0 as an argument (apparently such constructor exists). In this case attempting to access the members of that object will not crash anything, unless Answer class is specifically implemented to crash in this case (intentionally or unintentionally). So your "Of course..." claim makes no sense whatsoever. There's no immediate reason for such code to crash.
If you observe crashed in someAnswer == EMPTY_answer comparison, that would either mean that the implementation of == operator is buggy, or that either the LHS or the RHS are not valid objects. For example, it might turn out that it is illegal (by design) to construct an Answer object by conversion from 0. If so, then you should simply stop using (Answer) 0 in your code and find another, correctly supported object value to indicate an empty answer.
your original method of just checking for EMPTY_answer is the right way to solve this. Your real problem is why that crashes. What type is lAnswer? Or Answer for that matter... you can't cast 0 to a class like that.

C++ static initialization order

When I use static variables in C++, I often end up wanting to initialize one variable passing another to its constructor. In other words, I want to create static instances that depend on each other.
Within a single .cpp or .h file this is not a problem: the instances will be created in the order they are declared. However, when you want to initialize a static instance with an instance in another compilation unit, the order seems impossible to specify. The result is that, depending on the weather, it can happen that the instance that depends on another is constructed, and only afterwards the other instance is constructed. The result is that the first instance is initialized incorrectly.
Does anyone know how to ensure that static objects are created in the correct order? I have searched a long time for a solution, trying all of them (including the Schwarz Counter solution), but I begin to doubt there is one that really works.
One possibility is the trick with the static function member:
Type& globalObject()
{
static Type theOneAndOnlyInstance;
return theOneAndOnlyInstance;
}
Indeed, this does work. Regrettably, you have to write globalObject().MemberFunction(), instead of globalObject.MemberFunction(), resulting in somewhat confusing and inelegant client code.
Update: Thank you for your reactions. Regrettably, it indeed seems like I have answered my own question. I guess I'll have to learn to live with it...
You have answered your own question. Static initialization order is undefined, and the most elegant way around it (while still doing static initialization i.e. not refactoring it away completely) is to wrap the initialization in a function.
Read the C++ FAQ items starting from https://isocpp.org/wiki/faq/ctors#static-init-order
Maybe you should reconsider whether you need so many global static variables. While they can sometimes be useful, often it's much simpler to refactor them to a smaller local scope, especially if you find that some static variables depend on others.
But you're right, there's no way to ensure a particular order of initialization, and so if your heart is set on it, keeping the initialization in a function, like you mentioned, is probably the simplest way.
Most compilers (linkers) actually do support a (non-portable) way of specifying the order. For example, with visual studio you can use the init_seg pragma to arrange the initialization into several different groups. AFAIK there is no way to guarantee order WITHIN each group. Since this is non-portable you may want to consider if you can fix your design to not require it, but the option is out there.
Indeed, this does work. Regrettably, you have to write globalObject().MemberFunction(), instead of globalObject.MemberFunction(), resulting in somewhat confusing and inelegant client code.
But the most important thing is that it works, and that it is failure proof, ie. it is not easy to bypass the correct usage.
Program correctness should be your first priority. Also, IMHO, the () above is purely stylistic - ie. completely unimportant.
Depending on your platform, be careful of too much dynamic initialization. There is a relatively small amount of clean up that can take place for dynamic initializers (see here). You can solve this problem using a global object container that contains members different global objects. You therefore have:
Globals & getGlobals ()
{
static Globals cache;
return cache;
}
There is only one call to ~Globals() in order to clean up for all global objects in your program. In order to access a global you still have something like:
getGlobals().configuration.memberFunction ();
If you really wanted you could wrap this in a macro to save a tiny bit of typing using a macro:
#define GLOBAL(X) getGlobals().#X
GLOBAL(object).memberFunction ();
Although, this is just syntactic sugar on your initial solution.
dispite the age of this thread, I would like to propose the solution I've found.
As many have pointed out before of me, C++ doesn't provide any mechanism for static initialization ordering. What I propose is to encapsule each static member inside a static method of the class that in turn initialize the member and provide an access in an object-oriented fashion.
Let me give you an example, supposing we want to define the class named "Math" which, among the other members, contains "PI":
class Math {
public:
static const float Pi() {
static const float s_PI = 3.14f;
return s_PI;
}
}
s_PI will be initialized the first time Pi() method is invoked (in GCC). Be aware: the local objects with static storage have an implementation dependent lifecyle, for further detail check 6.7.4 in 2.
Static keyword, C++ Standard
Wrapping the static in a method will fix the order problem, but it isn't thread safe as others have pointed out but you can do this to also make it thread if that is a concern.
// File scope static pointer is thread safe and is initialized first.
static Type * theOneAndOnlyInstance = 0;
Type& globalObject()
{
if(theOneAndOnlyInstance == 0)
{
// Put mutex lock here for thread safety
theOneAndOnlyInstance = new Type();
}
return *theOneAndOnlyInstance;
}