CURRENT: CLANG 3.3 and -stad=c++11 and -stdlib=libc++: isnan()/isninf() oddity

O. Hartmann ohartman at zedat.fu-berlin.de
Wed Jul 10 18:32:08 UTC 2013


On Wed, 10 Jul 2013 18:04:16 +0100
David Chisnall <theraven at FreeBSD.org> wrote:

> On 10 Jul 2013, at 17:33, "O. Hartmann" <ohartman at zedat.fu-berlin.de>
> wrote:
> 
> > Hi David,
> > 
> > thanks for the fast response.
> > 
> > The code I was told to check with is this:
> > 
> > #include <iostream>
> > #include <typeinfo>
> > #include <cmath>
> > 
> > int
> > main(void)
> > {
> > 
> >        std::cout << typeid(isnan(1.0)).name() << "\n";
> > 
> > }
> > 
> > 
> > If I compile it with 
> > 
> > c++ -o testme -std=c++11 -stdlib=libc++ source.cc
> > 
> > and run the binary, the result is "i" which I interpret as "INT".
> 
> I believe there is a bug, which is that the math.h things are being
> exposed but shouldn't be, however it is not the bug that you think it
> is.  Try this line instead:
> 
>        std::cout << typeid(std::isnan(1.0)).name() << "\n";
> 
> We have a libm function, isnan(), and a libc++ function,
> std::isnan().  The former is detected if you do not specify a
> namespace.  I am not sure what will happen if you do:
> 
> #include <iostream>
> #include <typeinfo>
> #include <cmath>
> using namespace std;
> 
> int
> main(void)
> {
> 
>        cout << typeid(isnan(1.0)).name() << "\n";
> 
> }
> 
> This is considered bad form, but does happen in some code.  I am not
> certain what the precedence rules are in this case and so I don't
> know what happens.
> 
> To properly fix this, we'd need to namespace the libm functions when
> including math.h in C++.  This would also include fixing tweaking the
> macros.  
> 
> A fix for your code is to ensure isnan() and isinf() are explicitly
> namespaced.  Potentially, this may also work:
> 
> using std::isinf;
> using std::isnan;
> 
> David
> 

I tried in the test code I provided using 


#include <iostream>
#include <typeinfo>
#include <cmath>

int
main(void)
{

        std::cout << typeid(std::isnan(1.0)).name() << "\n";

}

now std::isnan().

The result is the same, it flags "INT".

Using 

#include <iostream>
#include <typeinfo>
#include <cmath>

using namespace std;

int
main(void)
{

        std::cout << typeid(std::isnan(1.0)).name() << "\n";

}

which is considered "bad coding" also results in "INT" (it gives "i").

So, is this woth a PR?

Oliver
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-current/attachments/20130710/45242659/attachment.sig>


More information about the freebsd-current mailing list