Isnan in std :: namespace? In general, when is std :: necessary, optional or should be avoided?

With Mingw 4.7.2, I have a library that does not compile due to the isnan call. The compiler says that “everything will be fine” if I use std::isnan , and indeed I am able to compile my file.

But if I checked here (Edit: but maybe I should also check here :-)), std:: doesn't seem necessary. If I add it, will the file be portable?

In general, for each case there is a general way to understand when to put std:: (for portability), is it optional or should be avoided?

Edit

Indeed, among the origins of the problem there are several inclusion headers, and some of the included headers include <cmath> , while this cpp file tries to include <math.h> (when <cmath> already included).

+6
source share
3 answers

It depends on which title you include. If you include the C <math.h> header (which is part of C ++, although marked as deprecated), you can use unqualified C functions, such as isnan . If you, on the other hand, include the C ++ <cmath> header, you guarantee that it will bring all functions from <math.h> to the std , and therefore you must qualify them correctly, for example std::isnan (or use some kind of using directive). Unfortunately, the implementation is allowed, but it is not required to include these functions in the global namespace when <cmath> included (and, thus, this is one of many "works on my machine") - C ++ features and the reason why many people write code like you just tried to compile unsuccessfully).

So, summarize: either turn on <math.h> , or use isnan or turn on <cmath> and use std::isnan , everything else is not portable. Of course, all this applies to any other C header and its corresponding C ++ version.

EDIT: It should be noted that this particular isnan function is isnan supported with C ++ 11 and is not available at all in C ++ 98 (which may be part of your confusion). But that doesn’t change anything in this situation, because in C ++ 98 neither <cmath> nor <math.h> (which was the actual C89 / C90 header, and then, and not the C99 header, which includes C ++ 11 ), there was this function, since they are always synchronized. So maybe this library from your question was trying to use C ++ 98, accepting the isnan function from another C99 implementation (which is not a good idea, since it might contradict parts of C89 / C90 C ++, they didn’t even try to do this) .

+12
source

C has no concept of namespaces. When you write #include <math.h> , all the names declared in the header fall into the global namespace, and you need to write isnan .

C ++ has namespaces. However, when you write #include <math.h> , all the names declared in the header fall into the global namespace, and you need to write isnan , as in C.

Also, when you write #include <cmath> , all the names declared in the header fall into the std , and you need to write std::isnan .

In addition, the C ++ implementation is allowed , and also go the other way: #include <math.h> puts the names in std , as well as in the global namespace; with #include <cmath> putting names in the global namespace , as well as in std . Do not rely on it; the code that does this is not portable. This concession to developers alleviate the situation; which actually means that if you use #include <cmath> , you cannot assume that there will be no isnan in the global namespace, and if you use #include <math.h> you cannot assume that in std there will be no isnan .

+5
source

This is because isnan from C. Using a different type of include will produce different results. Take isnan from the C <math.h> header as an example:

If you use #include <cmath> , it will be placed in the std .

If you use #include <math.h> , it will be placed in the global namespace.

C ++ 11 D.5 C standard library headers

Each C title, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace with the corresponding cname header is placed in the global namespace area. It is not known whether these names are declared or defined in the namespace (3.3.6) of the std namespace and then entered into the global namespace using explicit declarations (7.3.3).

[Example: a heading certainly provides its declarations and definitions in the std namespace. It can also provide these names in the global namespace. The header undoubtedly provides the same declarations and definitions in the global namespace as in the C standard. It can also contain these names in the std namespace. -end example]

+2
source

Source: https://habr.com/ru/post/951326/


All Articles