2

I am enabling a large code base to alternate between single and double floating point precision via a single typedef. At present, my code is double-oriented:

double foo(double input)
{
    return 1.0/input;
}

A naive switch to programmer-specified precision looks like this:

#ifdef _USE_DOUBLES
typedef double fpType;
#else
typedef float fpType;
#endif

fpType foo(fpType input)
{
    return 1.0/input;
}

Obviously, the "1.0" causes a compiler warning. My best solution so far is to treat every constant thus:

fpType foo(fpType input)
{
    return fpType(1.0)/input;
}

Is there any possibility that the explicit POD constructor invocation will actually be performed at runtime, thus charging me a speed penalty just for solving compiler warnings? I suspect not, since a compile time rewrite from "fType(CONSTANT)" to "CONSTANTf" seems trivial. But I want to make absolutely sure. I use VC, but I want to know about C++ compilers in general.

Also, is there a more elegant solution than mine? The fpType() invocations get ugly when lots of constants feature in one expression:

fpType someVal = fpType(1.0)/(someOtherVal+fpType(0.5))*(someVal      
/fpType(7.66))*fpType(43.33);

I expect there are compiler-specific approaches to this problem, but I seek a compiler-agnostic one, if it exists. Naturally, I would look to warning suppression only as a last resort, perhaps not at all.

[EDIT] I wrote this question misunderstanding "direct initialization", which is explained at Constructor Initialization of primitive data types in CPP.

Community
  • 1
  • 1
phizla
  • 132
  • 1
  • 6
  • 2
    "Is there any possibility that the explicit POD constructor invocation will actually be performed at runtime" - huh? no. – Karoly Horvath Mar 24 '14 at 22:44
  • 1
    Which kind of warning do you get ? My g++ doesn't complain at all even with `--pedantic`. – hivert Mar 24 '14 at 22:45
  • 1
    Are you referring to fpType(1.0) when you mention "POD constructor invocation"? If so, it's a cast, not a constructor invocation. static_cast< fpType >( 1.0 ) would probably be a better choice. – Andy Mar 24 '14 at 22:46
  • 1
    And no, there is no run-time hit for using it. – Andy Mar 24 '14 at 22:47
  • @Andy: Yes, that's the statement. Are you saying that float(K) is semantic sugar for (float)K? – phizla Mar 24 '14 at 22:56
  • @hivert: Cannot verify; I only have access to VC at the moment. – phizla Mar 24 '14 at 22:57
  • @phizla - static_cast< fpType >( K ) is the C++ way to statically cast. It's a compile time check, and hence there is no runtime hit. See http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast – Andy Mar 24 '14 at 23:13
  • In the case of numerical constants, I assume that a C-style cast always translates to a static_cast. – phizla Mar 25 '14 at 00:12
  • It looks like "direct initialization" was the parlance I lacked. See [here](http://stackoverflow.com/questions/10843715/constructor-initialization-of-primitive-data-types-in-cpp). – phizla Mar 25 '14 at 20:15

2 Answers2

3

You may try C++11 user defined literals:

#include <iostream>

#ifdef USE_DOUBLES
constexpr double operator"" _f (double value)
{
    return value;
}
#else
constexpr float operator"" _f (double value)
{
    return value;
}
#endif /*USE_DOUBLE*/


using namespace std;

int main()
{
    cout << 1.2_f << endl;
}
AlexT
  • 1,413
  • 11
  • 11
1

For the literal constants, you could use float type. The conversion to double will happen without any compiler warnings.

fpType foo(fpType input)
{
    return 1.0f/input;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270