One of the features of C 20 is Converting from T* to bool should be considered narrowing but perhaps I am not familiar with the history of this and trying to wrap my head around it in terms of what's its use-case/takeaway?
Following is how I have understood narrowing and the use of direct vs copy initialization
bool x = 2; // narrowing
bool x {2}; // can't narrow 2 to bool since {} is more strict than copy initialization
bool x = 1; // fine: 1 == true
bool x {1}; // can narrow 1 to bool
The article says:
1.
char* argument cannot construct bool alternative.
Converting from T* to bool should be considered narrowing.
Is it pointing to the example below? What's its usecase? The following compiles fine but is it implying there's narrowing between char*
to bool
? Was this not a thing before C 20? Doesn't seem it
bool p = new char*;
std::nullptr_t is not convertible to bool, but bool is constructible from std::nullptr_t`
however the following fails (verified here)
bool x = nullptr
CodePudding user response:
Was this not a thing before C 20? Doesn't seem it
Define "before". The proposal added the change as a defect of the standard. That means it propagates backwards through all applicable C revisions. So any new versions of compilers that implement C 17 or earlier should also implement this change.
But if you use an older version of compiler, it won't have this change.
However the following fails (verified here)
bool x = nullptr
Of course it does. "Convertible" and "constructible" aren't the same thing. "Convertible" is short for "implicitly convertible". If A
is implicitly convertible from a B
, that means A x = b;
works.
A
being "constructible" from B
means means A x(b);
works. And bool x(nullptr);
in fact works.
CodePudding user response:
I made a test based on yours:
#include <stdio.h>
int main()
{
bool x = nullptr;
bool y {nullptr};
bool z (nullptr);
}
Using gcc, first case fails: https://godbolt.org/z/edaM6M1Ex
Error is: converting to 'bool' from 'std::nullptr_t' requires direct-initialization
Direct initialization is e.g. described here: https://en.cppreference.com/w/cpp/language/direct_initialization and it is not an initialization that uses "=" sign.
So, while I don't know if this is correct or not from The Standard point of view, I hope it discusses why the compiler behaves this way.