I have this code:
#include <iostream>
using namespace std;
int main()
{
string name = "John ";
int age = 32;
name += age;
cout << name << endl;
return 0;
}
The code compiles successfully but betrays at run time as it silently ignores the concatenation part and prints:
John
I know that we need to use stringstream for the task. But why does the above code compile? Because the following code:
#include <iostream>
using namespace std;
int main()
{
string name = "John ";
int age = 55;
name = name + age;
cout << name << endl;
return 0;
}
duly throws and error:
error: no match for ‘operator+’ in ‘name + age’
I know from Java that a += b
is different from a = a + b
as the former construct typecasts the result to the type of a. Reference. But I don't think this would matter in C++ as we can always do:
int a = 1;
float f = 3.33;
a = a + f;
without worrying about a possible loss of precision warning unlike Java. Need citation for this in C++.
So now if we assume that name += age;
expands to name = string (name + age);
then also the code should not have compiled simply because name + age is not legal.
You need to use the -Wconversion
flag(It is not clear to me why this is not included in -Wall) also see the Options to Request or Suppress Warnings for more details. When I add that flag I see the following warning when using gcc
:
warning: conversion to 'char' from 'int' may alter its value [-Wconversion]
name += age;
^
and we can see that indeed operator += does support char and therefore the converted value is indeed being add to the end of name
, it is not ignoring the operation at all. In C++ operator + for std::string is a different operator than operator +=.
In this specific case:
name += age;
would translate to something like this:
name.operator+=(static_cast<char>(age)) ;
and if we had a expression using operator + without an error like this one:
name = name + static_cast<char>( age );
would translate to:
operator+( name, static_cast<char>( age ) ) ;
The reason why this fails for operator + in your example is covered well in this answer, basically template functions won't perform conversions and so require an exact match with the possible exception of const/volatile qualifiers.
Update on Wconversion
gcc
has a Wconversion Wiki with a FAQ, it is a bit dated but it does answer why this check is not included with the -Wall
flag:
Implicit conversions are very common in C. This tied with the fact that there is no data-flow in front-ends (see next question) results in hard to avoid warnings for perfectly working and valid code. Wconversion is designed for a niche of uses (security audits, porting 32 bit code to 64 bit, etc.) where the programmer is willing to accept and workaround invalid warnings. Therefore, it shouldn't be enabled if it is not explicitly requested.
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