7

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.

johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • Have you seen this? http://stackoverflow.com/q/6765770/2065121 – Roger Rowland May 12 '13 at 05:32
  • @RogerRowland Worth noting that none of the answers to that question demonstrate how to actually use the static_assert properly, so I'd consider that question an incomplete resolution to my question here. You can see my comment to the answer by H2C03 – johnbakers May 12 '13 at 05:45
  • 1
    Is the bool flag `isntAmazing` a compile time constant? You can make compiler error out for the info only if something you know at compile time. For the runtime values, you need runtime assertions. Describe more about the type of the `AwesomeClass`, so that someone can help you. – iammilind May 12 '13 at 05:52
  • @Fellowshee - yes I know, that's why I didn't suggest it was a duplicate, just indicating that it may be a useful read. – Roger Rowland May 12 '13 at 05:57

3 Answers3

20

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.)

Melebius
  • 6,183
  • 4
  • 39
  • 52
  • It is unclear to me how to actually use the `static_assert` properly. The first parameter requires an integral constant expression but I'm not sure how to create such an expression when I merely want to test if a particular variable is true or false. This is not considered a proper expression for the assert. – johnbakers May 12 '13 at 05:44
  • 3
    @Fellowshee If you want to check if a variable is true or false, then you can't use `static_assert`. You will have to verify that at runtime. –  May 12 '13 at 05:46
  • Does MSVC not support `#error`? It's a standard pp directive (look for "# error" if you try to find it). – chris May 12 '13 at 05:52
  • 2
    `#error` condition isn't applicable for this question, because that's something during preprocessing stage, which comes even before actual compilation – iammilind May 12 '13 at 05:53
3

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
}
Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • Great solution that demonstrates that, even when everyone else says it cannot be done at compile time, a novel use of c++ features demonstrates that a lot is possible with some thought – johnbakers May 12 '13 at 06:02
1

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.

Richard
  • 546
  • 4
  • 6