Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is initializing a reference of type "int &" (not const-qualified) with a value of type "bool" some hack?

Tags:

c++

reference

gcc

I came accros this c++ code here:

  // round alternate
  // Bias: none for sequential calls
  bool _is_up = false;
  template <typename FloatType>
  FloatType roundalternate( const FloatType& value, int& is_up = _is_up )
    {
    if ((is_up != is_up))
      return roundhalfup( value );
    return roundhalfdown( value );
    }

And it confuses me, how is this supposed to work? How is this supposed to make an alternate call on each call of this function?

Is this code just plain wrong, or is it supposed to work due to some compiler weirdness? It seems to have compiled fine with g++ but I can't reproduce this at the moment. icc is not accepting it:

rounding.h(183): error: a reference of type "int &" (not const-qualified) cannot be initialized with a value of type "bool"
FloatType roundalternate0( const FloatType& value, int& is_up = _is_up )
                                                                  ^

Update g++ does not seem to accept it either (update to clarify after Ben Voight's answer: g++ can compile the plain file (which icc can not), but fails if you try to invoke without a second argument)

bla.h: In function ‘FloatType rounding::roundalternate(const FloatType&, int&) [with FloatType = char*]’:
bla.h:220:35: error: could not convert ‘rounding::_is_up’ from ‘bool’ to ‘int&’
   rounding::roundalternate(argv[0])

Other people are reporting problems with clang as well

Relevance: I'm trying to compile cufflinks with the intel compiler, and it is failing because this code is in there.

I have no idea how cufflinks could have compiled before with this in it.

update2: Cufflinks compiled fine with g++, not with icc, I've contacted the maintainers, and they have removed the offending piece of code in newer versions.

like image 348
Jens Timmerman Avatar asked Oct 03 '22 09:10

Jens Timmerman


1 Answers

This code obviously is trouble. int& cannot bind to an lvalue of type bool, and cannot bind to an rvalue resulting from a conversion. However, it also compiles without error.

This is because, unlike normal functions, semantic analysis for default arguments in template functions occurs only "when the function is called in a context that requires the value of the default argument", explained in 8.3.6p5, 14.7.1p3, and 14.7.1p13 of the Standard.

That means the compile error will only occur when other code calls this function without providing an actual argument for the second parameter.

like image 199
Ben Voigt Avatar answered Oct 10 '22 20:10

Ben Voigt