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.
Related
this is a VERY simplified version of the question to make it obvious what i am asking. I cannot seem to find it on Stack Overflow but i am probably searching using the wrong words!
Here is a Template Class with the obvious parts removed.
template <class T, bool clip = true>
class BOUNDED_VAL {
public:
BOUNDED_VAL(T initialMin, T intialMax) :locked(false) {
assert_or_throw(intialMax >= initialMin, HD_ERR_MINMAX_REVERSED);
min = initialMin;
max = intialMax;
value = initialMin;
};etc.
// assert_or_throw is a typedef which asserts during debug builds to prevent programmer mistakes (especially my own) or throws a rich catachable runtime error for user input just in case something gets around user input limit checking during release builds (A hard wall). Belt and braces approach...
Now i know i can set this up as an initialised private class member variable like so:
private:
BOUNDED_VAL<int> testBoundInt = BOUNDED_VAL<int>(0, 10);
BUT
Does this create a new BOUNDED_VAL and then copy it over the member variable (or compiler smooshes this away during optimisation)?
Is there a more succinct way of doing it which i am just not finding? I know the following do not work but for example:
private:
BOUNDED_VAL<int> testBoundInt(0,10);
or
private:
BOUNDED_VAL<int>(0,10) testBoundInt;
I am self taught in C++ so it might be an obvious question...but you never know...
Many Thanks
I know the following do not work but for example:
private:
BOUNDED_VAL<int> testBoundInt(0,10);
But this will work, provided your compiler was written in the last decade:
BOUNDED_VAL<int> testBoundInt{0,10};
It looks like you might be using an outdated textbook to learn C++ that does not cover uniform initialization syntax from the current version of C++. You are strongly encouraged to get updated learning material.
Does this [copy initialization] create a new BOUNDED_VAL and then copy it over the member variable (or compiler smooshes this away during optimisation)?
This actually depends on the C++ version your compiler supports, and is configured to use. Depending on several factors it gets "smooshed" away, or we take a scenic trip to the countryside, where an object gets constructed, then a second object gets copy-constructed, and the first object deleted.
But this is now a secondary topic, since uniform initialization syntax solves the original problem.
I have a basic POD struct with some fields
struct A{
int a,
int b,
};
The nature of my use case requires that these fields change every so often (like 1-2 months, regular but not often). This means that I want to check the field usages of the struct after the changes to make sure everything is still fine.
The compiler checks that all field usages are valid, something like a.c will fail at compile time.
However, some of my functions should access and handle ALL of the fields of A. So while the compiler verifies that all usages are valid, it doesn't validate that all the fields are used.
This work/checking must be done manually (if there is a way to do this at compile time, please enlighten me). So our current design tries to make this as easy as possible. We grouped most of the relevant functions into one folder/library so we could check over them in one place. However, some usages are embedded in private class functions that would honestly be more of a pain to refactor out into the common lib than the benefits it brings.
It's reasonable to just rely on documentation saying "Hey, after changing struct A, check the function foo in class FooThing". But I'm looking to see if we can get some type of compile time warnings.
My idea was to basically drop a static_assert next each relevant function that would check the size of A. Most changes should change the size, so an unchanged static_assert would fail at compile time, pointing me to the general area of the function. Then I could just change the function and the assert.
So besides the function foo for example, I would have something like static_assert(sizeof(A) == 16) or whatever size. This isn't foolproof, as it's possible that changes to struct might not change the total size, but I'm not looking for something really rigorous here, just something that could be helpful 90% of the time.
The main reason why this doesn't work for me is that int and other data types don't have a specified size from the standard. This is a problem for me since my project is cross platform.
In short, I am looking for a way to signal at compile time to check certain functions after a struct's definition has been changed.
One possibility is to put a version number into the struct itself, like so:
struct A{
int a;
int b;
static constexpr int major_version = 1;
};
Then, in calling code, you place assertions that check the value of the major version:
void doSomething(A a)
{
static_assert(A::major_version == 1, "Unexpected A major version");
// Do something with a
}
Then, any time you make an update to A that you think merits re-inspection of all calling code, you increment A::major_version, and then the static_assert will fire anywhere you haven't changed it.
lets consider the following code:
struct Foo {
Foo(Bar b1, Bar b2) : b1(b1), b2(b2) {}
void work() {
b1.work();
b2.work();
//something
}
Bar& b1;
Bar& b2;
};
struct Bar {
void work() { /* something */ }
};
int main() {
Bar a, b;
a.work();
//something...
Foo c(a,b);
c.work();
//something...
}
The way I wrote that (or intended to write it), a.work() will get executed twice. But let's say, I, as the programmer know, that executing it twice is a waste of execution time and let's say this was part of a far more complex piece of software where it would be far too troublesome to keep track manually what work is and isn't done.
Obviously I could store some boolean flag in Bar and check every single time whether the work has been done already, but I want to know, if there is some way where I can already catch that at compile time. Because at compile time it is already clear that the work had been done.
Another approach. Have a function pointer within the Bar object and in work() function call the pointer. In the constructor, define the pointer to be the actual work function. At the end of the function, reassign the pointer to be an empty function.
In this case, the first execution will do the job. But later executions will do nothing (also not checking the boolean flag)
struct Bar {
typedef void (*Bar::fptr_t)();
Bar() : fptr(actual_work) {}
void actual_work() {
/*something*/;
fptr = &Bar::empty_work;
}
void empty_work() {}
void work() {fptr();}
fptr_t fptr;
};
Something like above.
No, not really.
The compiler is capable of some static analysis, and if you could ask it to diagnose this condition, it may be able to do so in some simple cases. But as soon as you have a non-trivial flow (runtime if conditions, for example), that goes out of the window very quickly. That's probably part of the reason that nobody has created such a programmable feature for compilers: high complexity, with negligible utility.
It may be possible to program some third-party static analysers (or create one!) to diagnose your simple case, but again that's a lot of work for handling only the most trivial cases that you can already spot with your eyes.
Instead, you could make work() happen in the Bar constructor. Then it's impossible to do the work twice on the same object. However, performing large quantities of work in a constructor is often frowned upon.
I would indeed keep a state flag within Bar, and return false from a subsequent work(), by maintaining the value of that flag accordingly. As a bonus, stick an assertion in the function before returning false so that you catch violations during your testing.
The state flag doesn't have to be a boolean; it can be an enum. Robust state machines inside your objects can be very helpful.
That being said, I'd advise revisiting your current approach where you pass references to things into other things that do work on them; it's not an easy-to-follow design, and this is only a simple example of your design! You may wish to consider passing some single-use proxy type instead.
Actually, at compile time it isn't obvious, whether the code was executed or not. Suppose you have an if statement and within it, you call a.work(). How does the compiler know, whether at that time the a.work() was executed? As you say, don't think, that the if statement is very simple (suppose, it is looking for some external signal and executes the code depending on that signal). The best way to avoid the behavior is to keep a boolean.
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!
Let say I have a basic 2D vector class something like
class vector2
{
int x, y;
}
these two values could be used to represent a position as well as a width and height. does C++ provide a away for me to impliment a function such as vector2::getXpos() and then also define vector2::getWidth() and have it use the same implementation.
I know that I could just make both of these function inline, but the compiler might decide to not inline these functions. so if getWidth just called getXpos you would end up with two function calls.
A more relistic example of what I would want to use this for is getLength() and erm... getSpan() (thinking of like a screen here for when you say 40" tv)
I would assume that this would be a simple case of something like a special function definition... I did find this page but this sounds like it is a C feature... and a bit of a hack to get working.
EDIT
I am not asking about the mechanics of inline functions... I basicaly want to do something functionally like
class MyClass
{
void ActaullyDoStuff();
public:
void foo(){ActaullyDoStuff();}
void bar(){ActuallyDoStuff();}
}
but where I can just write something like
class MyBetterClass
{
public:
void foo(){ /* BLOCK OF CODE */ }
void bar(){ /* DO WHAT EVER foo() DOES */ }
}
I want bar() to be another way of just doing foo() so that the same functional code can have different, more appropriate names depending on the situation.
but the compiler might decide to not
inline these functions
Then the compiler probably has a good reason to do so.
I think this is a non problem, just have the function with the alternative name call the "real" function, and the compiler will most likely inline it.
EDIT:
If that didn't convince you, it is possible to use __forceinline in visual studio.
Here is the way to force inline in GCC.
EDIT2:
class MyBetterClass
{
public:
void foo(){ /* BLOCK OF CODE */ }
__forceinline void bar(){ foo(); /* DO WHAT EVER foo() DOES */ }
}
Using C++11 you could do:
//works for non-template non-overloaded functions:
const auto& new_fn_name = old_fn_name;
Other solutions:
How do I assign an alias to a function name in C++?
It appears you're not thinking about this in an object oriented way. I have to second mjfgates advice that you really don't want to do this.
What you want to do is abstract the idea of a vector into a class and implement the common methods you might want to use with a vector. In fact, you may want to consider implementing your class example above as a "Point" class and then have a "Vector" class aggregate two point classes.
Using your example, your class would not be well defined if it was used for two different purposes. Let's say you want to make a method on some class to draw vector2. You would have to know which instances of vector2 are representing a starting point and which ones are representing a width/height. You'd probably also need a third representation to represent direction. The easier way is to implement the vector in terms of getStartPoint, getEndPoint, and any other methods that will do calculations appropriate for the vector. Then the consumer doesn't need to know about the internal working of the vector2 class, they just call the methods to get the information they need.
Your referenced link is AFAIK not a C feature either, but something specific to that particular compiler.
C++ provides such a mechanism: it happens to be inlined functions! Worrying about the compiler not optimizing away the redundant call in an inlineable function is definitely premature optimization. Inline, then measure if you're worried about performance.
If you're absolutely insisting on eliminating the merest chance of a redundant call, you might do something with preprocessor #defines... but beware: macros do not respect class boundaries, and your header files will sooner or later stomp on some other, unrelated code. Better not go there.
you could use preprocessor #defines.... if you're into the world's worst bugs. You'll get the equivalent of guaranteed inline if you want, or just aliases if you want that too.
So, you want to have two functions, on the same object, that return exactly the same data, as the same data type.
Don't DO that.
Providing more than one path to the same data is one of those things that sounds like it might be convenient for whoever's going to be using your object-- until you think about it. What happens is that six months down the road, somebody turns up a bug in one of the two functions, and you fix that function but not the other one, so the bug's still there. Or the programmer who's writing clients for your object is driven half-insane wondering what the difference is between getLength() and getSpan().
The one time I'd do this would be when implementing an interface that requires a duplicate of an existing member function. In that case, the interface's function is going to be virtual, so the notion of inlining goes out the window.