Viktor Sehr
Viktor Sehr

Reputation: 13119

C++: How to trigger a compiler error when function return value is unused?

Let's say I have a normalize function defined as:

Vec3f Vec3f::getNormalized() const {
   return (*this)/this->length();
}

Is it somehow possible to create a compile-time error if this function is used without something storing it's return value? ;

v.getNormalized(); // which most definitely is a typo

..instead of..

v = v.getNormalized(); 

Upvotes: 22

Views: 2345

Answers (4)

Luc Touraille
Luc Touraille

Reputation: 82161

I don't think this is possible at compile-time, except by using compiler flags as @Ashwin noted.

However, if it is ok to generate an error at runtime, you could perhaps use some tricks, like using a proxy class:

template <typename T>
struct Return
{
    Return(const T & value) 
      : value_(value), used_(false) 
    {}

    Return(const Return & other) 
      : value_(other.value_), used_(false) 
    { 
        other.used_ = true; 
    }


    Return & operator=(const Return & other)
    {
        other.used_ = true;
        value_ = other.value;
        return *this;
    }

    operator T() const 
    { 
        used_ = true; 
        return value_;
    }

    ~Return() // generates an error if the value hasn't been used
    { 
        assert(used_); 
    }

  private:

    T value_;
    mutable bool used_;
};

Return<int> foo()
{
    return 42;
}

int main()
{
    int i = foo();                   // ok
    std::cout << foo() << std::endl; // ok

    foo();                           // assertion failed
}

You just need to change the return type of your function so that it returns a Return<Vec3f> and you should obtain an error if the result of the function is unused. However, I'm not sure I would recommend that, since it makes the code less clear and can probably be misused as well. As long as your function is well-documented, you should have confidence in your users :)!

Upvotes: 3

Matthieu M.
Matthieu M.

Reputation: 300409

With clang, you can selectively transform a given warning into an error (rather than all).

This is achieved with the -Werror=foo where foo is the name of the warning. Here I think that -Werror=unused-expr is what you'd need.

Upvotes: 2

Ashwin Nanjappa
Ashwin Nanjappa

Reputation: 78568

In GCC, use -Wunused-result to trigger the warning when a function's return value is ignored. And if you want an error instead of warning, use -Werror to convert all warnings into errors. For more information see GCC Warning Options.

There does not seem to be an equivalent warning for the Visual C++ compiler. (If I am wrong, please edit this reply with the Visual C++ information.)

Upvotes: 19

Puppy
Puppy

Reputation: 147036

There's no way to know whether or not the return value was taken. The only way to guarantee that one was passed in is to pass in the return value by reference.

Upvotes: 6

Related Questions