Home > Back-end >  C 20: Narrowing between T* to bool
C 20: Narrowing between T* to bool

Time:11-21

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.

  • Related