Expectations are this code:

#include <iostream>
#include <limits>
#include <stdexcept>
using std::clog;

namespace{

class FloatValue
{
public:
    FloatValue() : m_amount(0.0f)
    {
        clog << "Creating default floating point value.\n";
    }

    explicit FloatValue(float amount) : m_amount(amount)
    {
        clog << "Creating floating point value with amount " << m_amount <<
            ".\n";

        if(std::numeric_limits<float>::infinity() == m_amount){
            throw std::domain_error("Floating point value cannot be infinite");
        }
    }
private:
    float m_amount;
};
    
} // namespace

int main()
{
    const float INFINITE_VALUE = std::numeric_limits<float>::infinity();
    try{
        FloatValue(INFINITE_VALUE);
    }
    catch (const std::domain_error& error) {
        std::cerr << error.what() << std::endl;
    }

    return 0;
}

should print:
Creating floating point value with amount inf
Floating point value cannot be infinite

However when compiling the code the complier issues a warning like:
TestFloatValue.cpp: In function ‘int main()’:
TestFloatValue.cpp:34: warning: unused variable ‘INFINITE_VALUE’

and during execution, the output is:
Creating default floating point value.

What is needed so the code will behave as expected?

Recommended Answers

All 7 Replies

did you try

try{
        FloatValue a(INFINITE_VALUE);
    }

Interesting situation - may be infinity is not considered as a float .
Keep us updated on this.

Think: FloatValue (INFINITE_VALUE) is not FloatValue variable definition. It's an ordinal expression operator with null effect (in "void position"), the same as 0.0; . Evidently, you wanted

FloatValue variable_name(INFINITE_VALUE);

Do that and you will catch an exception ;)

Probably in your code the compiler generates default FloatValue object and kills it at once...

Some remarks: it's a very unreliable method to compare float variable with infinity. But it's the other story. Regrettably, most of C++ compilers do not support C floating point functions and macros for NaN values...

I added a name for the variable and then the program worked as expected. This is very curious. I am using test driven development to implement a class similar to the FloatValue class in my example. The unit test harness contains macros for verify behavior, and I've written test cases like:

VERIFY_NOTHING_IS_THROWN(FloatValue(1.0f));

VERIFY_EXCEPTION_THROWN(FloatValue(-INFINITE_VALUE), std::domain_error);

Both of these cases work fine. In the case where the infinite value is negative the proper constructor get called and the test harness detects the thrown execption. When the infinite value is positive, the default constructor is called and the test fails because no exception is thrown.

I tried this with two different compilers on three different operating systems and got the same results. Both compilers complained about the unused INFINITE_VALUE variable, and both called the default constructor to create the FloatValue instance.

Given the test cases I'm trying to write, I don't know how well it will work to use a named variable. Doing something like:

VERIFY_EXCEPTION_THROWN(FloatValue value(INFINITE_VALUE), std::domain_error);

might result in a warning about an unused variable named 'value'.

I'm wondering if it would help to do something like:

using std::domain_error;

const float INFINITE_VALUE = std::numeric_limits<float>::infinity();

typedef std::auto_ptr<FloatValue> ValuePtr;
ValuePtr valuePtr;
VERIFY_EXCEPTION_THROWN(valuePtr = ValuePtr(new FloatValue(INFINITE_VALUE)), domain_error);
VERIFY_EXCEPTION_THROWN(valuePtr = ValuePtr(new FloatValue(-INFINITE_VALUE)), domain_error);

There is isfinite macro in the standard C (declared in math.h). Alas, most of modern C++ compilers do not implement it.
There is equivalent but non-standard function in VC++ (declared in <cfloat>): _finite(value). Use

if (!_finite(amount))
    throw...

It works in all cases (except funny (void)Class(value): ). May be the intersection of all NaN inspectors in C++ implementations is not null set...

I'm trying to do cross platform development so I don't believe the Visual Studio macro would work for me.

I'm trying to do cross platform development so I don't believe the Visual Studio macro would work for me.

A code based on infinity() can't be platform-independent: infinity value support is optional in C++.
See std::numeric_limits<float>::has_infinity .

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.