Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is isnan ambiguous and how to avoid it?

Since isnan can be either a macro (in C++98) or a function defined in namespace std (in C++11), an obvious (and possibly naive) way to write the code that works in both cases is illustrated by this simple example

#include <cmath>

int main() {
  double x = 0;
  using namespace std;
  isnan(x);
}

However, compiling it gives errors both in GCC (with -std=c++11) and Clang:

test.cc: In function ‘int main()’:
test.cc:6:10: error: call of overloaded ‘isnan(double&)’ is ambiguous
   isnan(x);
          ^
test.cc:6:10: note: candidates are:
In file included from /usr/include/features.h:374:0,
                 from /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h:39,
                 from /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h:426,
                 from /usr/include/c++/4.8/cmath:41,
                 from test.cc:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:234:1: note: int isnan(double)
 __MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
 ^
In file included from test.cc:1:0:
/usr/include/c++/4.8/cmath:626:3: note: constexpr bool std::isnan(long double)
   isnan(long double __x)
   ^
/usr/include/c++/4.8/cmath:622:3: note: constexpr bool std::isnan(double)
   isnan(double __x)
   ^
/usr/include/c++/4.8/cmath:618:3: note: constexpr bool std::isnan(float)
   isnan(float __x)
   ^

Why is this ambiguous in C++11 and how to make it work with both C++98 and C++11 preferably without too much conditional compilation?

like image 947
vitaut Avatar asked Nov 18 '15 01:11

vitaut


People also ask

What are the causes of ambiguity in requirements?

Another cause of ambiguity is when a requirement is vague and does not include specific details. Again, miscommunication may result from not using proper content and grammar structure while writing the specifications. Here is a list of best practices to create well-written requirements that avoid ambiguity, confusion, and misunderstandings. 1.

How do you avoid ambiguity and disappointment in your design?

Therefore, to avoid ambiguity and disappointment, you need to be specific on what is your idea of “easily accessible.” If you say that products must be displayed on the front page, there is no room for interpretation, and your requirement now is crystal clear. Several factors may contribute to ambiguity like,...

When to avoid ambiguity in a formal essay?

When to Avoid Ambiguity. Avoid ambiguity as much as possible in formal essays. Of course, sometimes things will accidentally be left unclear, and that’s OK. But as much as you can, try to make sure that your sentences have only one possible meaning, and aren’t open to the wrong interpretation.

What is an ambiguous question?

An ambiguous question is defined as one where there is no specific query, it could have more than one meaning, asking for several responses, or not clearly defining the subject/object. Here are some examples with reasons why they aren’t good questions:


Video Answer


1 Answers

This is a libstdc++ bug documented in the bug report std functions conflicts with C functions when building with c++0x support (and using namespace std) with a reproducing sample very similar to the OP's:

#include <stdlib.h>
#include <cmath>
#include <stdio.h>

using namespace std;

int main(int argc, char** argv)
{
    double number = 0;
    if (isnan(number))
    {
        printf("Nan\n");
    }
    return 0;
}

and one of the comments says:

I don't think that's the problem, because libstdc++ has always declared the names in the global namespace even though it wasn't valid in C++03 - we haven't changed that for C++0x (all that happened is the standard was relaxed to reflect the reality of actual implementations)

This may eventually get fixed until then the solution provided from the bug report is as follows:

Qualify isnan explicitly, by calling either ::isnan or std::isnan

Using ::isnan as far as I can tell works pre C++11 and in C++11.

Of course this is a libstdc++ specific solution, it looks valid in libc++ as well but if you need to support a compiler where this does not work you will probably have to resort to using #if/#else.

Note, as indicated by M.M having isnan marked constexpr is non-conforming, this is a known issue as well although it does not contribute to this particular issue.

Also see related bug reports: [C++11] call of overloaded ‘isnan’ is ambiguous and Recognize builtins with bool return type. The second discusses possible libstdc++ solutions.

Update

If you want a gcc/clang solution it looks like they both support __builtin_isnan, see gcc docs on builtins for more information. Also see this glibc bug report on replacing isnan et al with the builtin.

like image 161
Shafik Yaghmour Avatar answered Sep 19 '22 10:09

Shafik Yaghmour