When compiling C++ with overloaded function definitions why is the promotion behaviour different between signed and unsigned integer types? Is this expected behaviour?
In the example below, the call to "fail" in main is ambiguous but the call to "pass" is not.
unsigned int fail(unsigned int a) {
return a;
}
unsigned int fail(unsigned short a) {
return a;
}
int pass(int a) {
return a;
}
int pass(short a) {
return a;
}
int main(){
unsigned char a;
char b;
fail(a);
pass(b);
return 0;
}
Sample output (from clang, VS compiler gives something similar):
fail.cpp:22:3: error: call to 'fail' is ambiguous
fail(a);
^~~~
fail.cpp:1:14: note: candidate function
unsigned int fail(unsigned int a) {
^
fail.cpp:5:14: note: candidate function
unsigned int fail(unsigned short a) {
^
1 error generated.
According to integral promotion (emphasis mine):
The following implicit conversions are classified as integral promotions:
signed char
[...] can be converted toint
;unsigned char
[...] can be converted toint
if it can hold its entire value range, andunsigned int
otherwise;char
can be converted toint
orunsigned int
depending on the underlying type:signed char
orunsigned char
(see above);Note that all other conversions are not promotions; for example, overload resolution chooses
char
->int
(promotion) overchar
->short
(conversion).
In your case, given that int
is able to hold the entire value range of both signed char
and unsigned char
, only int pass(int a)
is a promotion which is more preferable than the remaining three which are conversions, and there is no preference among the conversions.
Those implicit conversions
indeed follow different rules.
char
-> int
is a promotion
char
-> short
is a conversion
and promotion is chosen over conversion because it forbids any precision loss. That's why pass
passes.
Whereas
unsigned char
-> unsigned int
is a promotion only if int
can't represent the full range of values unsigned char
s can; if not, the promotion is unsigned char
-> int
. I suspect that, in your case, int
can indeed represent all values in the range of unsigned char
. This means that fail
has a choice between two two-steps conversion paths: unsigned char
-> int
-> unsigned int
and unsigned char
-> int
-> unsigned short
and can't decide between them.
source: http://en.cppreference.com/w/cpp/language/implicit_conversion
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With