I'm trying to pass x of type T to a function foo
which expects unsigned int
, and I'm not sure what T is because it's a typedef declared in some other module. Both foo
and T
are not something I can modify. I want compiler to warn me if narrowing happens.
So I'm trying:
typedef int T;
void foo(unsigned int x);
void bar(){
T x;
foo(unsigned int{x});
}
unfortunately on gcc 9.2. this gives me a compile error:
<source>: In function 'void bar()':
<source>:5:9: error: expected primary-expression before 'unsigned'
foo(unsigned int{x});
^~~~~~~~
Compiler returned: 1
If I change the offending line to:
foo((unsigned int){x});
then the problem goes away, and I get a correct warning that narrowing takes place:
<source>: In function 'void bar()':
<source>:5:25: warning: narrowing conversion of 'x' from 'T {aka int}' to 'unsigned int' inside { } [-Wnarrowing]
foo((unsigned int){x});
^
Compiler returned: 0
Great! Unfortunatelly this syntax does not work on Visual Studio 2019 16.2.5, as I get: E0029 C4576 C2397 errors in this line. Of which C4576 is "a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax".
So what is the standard explicit type conversion syntax for this case? https://en.cppreference.com/w/cpp/language/explicit_cast says in point 5) that it must be single-word type. What if it is more than one word (long long, unsigned long int, etc.?)
In your case, you can just write unsigned
instead of unsigned int
. But a more general solution is to create a type alias:
void bar(T x) {
using U = unsigned int;
foo(U{x});
}