libc++ std::isfinite() problem

Hi,
I am getting compile errors trying to compile code which tries to do
something equivalent to std::isfinite((int)0). I get:

test.cc:27:3: error: no matching function for call to 'isfinite'
  std::isfinite((int)0);
  ^~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/cmath:376:1: note: candidate template ignored:
substitution failure [with _A1 = int]
isfinite(_A1 __x)

This compiles OK on all versions of libstdc++ that I have tried. Is
libc++'s implementation correct here? Should it be relying on templates
and only allowing specializations that satisfy std::is_floating_point?

Thanks!
Kal

Hi,
I am getting compile errors trying to compile code which tries to do
something equivalent to std::isfinite((int)0). I get:

test.cc:27:3: error: no matching function for call to 'isfinite'
std::isfinite((int)0);
^~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/cmath:376:1: note: candidate template ignored:
substitution failure [with _A1 = int]
isfinite(_A1 __x)

This compiles OK on all versions of libstdc++ that I have tried. Is
libc++'s implementation correct here?

Looking at the C++ standard, std::isfinite is only defined thus:
  
  bool isfinite( float arg );
  bool isfinite( double arg );
  bool isfinite( long double arg );
[ Section 26.8 ]

So, I would say that, yes, libc++'s implementation is correct (to reject what you're trying to do)

Should it be relying on templates
and only allowing specializations that satisfy std::is_floating_point?

I don't see why not.

There's also an isfinite macro defined by the C standard.
It's defined to work on floating point types as well, but since it's a macro, type checking the parameter is harder/looser.
[ Section 7.12.3.2 of the C99 standard ]

-- Marshall

Marshall Clow Idio Software <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
        -- Yu Suzuki

This looks like a libc++ bug to me. Prior to Oct. 2010 libc++ was correct that std::isfinite should only accept floating point arguments. But two paragraphs were reordered in N3126 with the result that std::isfinite (and several other functions) should now accept integral arguments as well. I had not noticed the impact of this paragraph reordering until now.

Howard

Which paragraphs do you have in mind?

In http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3126.pdf

26.8/p10 and the deleted paragraph after p11.

Howard

You mean “The classification/comparison functions behave the same as the C macros with the corresponding names defined in…” and since the C macros seem to accept integer types so should the c++ variants? Is it even defined behavior in the C standard to pass integers to these macros?

No. P11 bullet 2 now applies to isfinite, whereas previously it did not (due to isfinite et al. being moved above p11).

In C (even C11) isfinite still only accepts a floating point argument. So this is a pretty dubious extension of C in C++11 imho. But I will try to get it fixed asap.

Howard

Committed revision 172461.

Howard