Home Ask Login Register

Developers Planet

Your answer is one click away!

Alexei February 2016

C++ implicit numeric type demoting

Recently, I have noticed that C/C++ seems to be very permissible with numeric type conversion, as it implicitly casts a double to int.

Test:

Environment: cpp.sh, Standard C++ 14, Compilation warnings all set

Code:

int intForcingFunc(double d) {
    return d;                       // this is allowed
}

int main() {
    double d = 3.1415;
    double result = intForcingFunc(d);
    printf("intForcingFunc result = %f\n", result);

    int localRes = d;               // this is allowed
    printf("Local result = %d\n", localRes);

    int staticCastRes = static_cast<int>(d);                // also allowed
    printf("Static cast result = %d\n", staticCastRes);
}

No warnings are issues during compilation.

Documentation mentions tangentially the subject, but misses the exact case of the question:

C++ is a strong-typed language. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion, known in C++ as type-casting.

I have also tried in a managed language (C#) and all these cases are not allowed (as expected):

static int intForcingFunc(double d)
{
    // Not legal: Cannot implicitly convert type 'double' to 'int'
    // return d;
    return Convert.ToInt32(d);
}

static void Main(string[] args)
{
    double d = 3.1415;
    double result = intForcingFunc(d);
    Console.WriteLine("intForcingFunc result = " + result);

    // Not legal: Cannot implicitly convert type 'double' to 'int'
    // int localRes = d;
    int localRes = (int)d;
    Console.WriteLine("local result = " + result);

    Console.ReadLine();
}

Why is this behavior allowed in a strong-typed l

Answers


zenith February 2016

Unfortunately, this behavior is inherited from C, which notoriously "trusts the programmer" in these things.

The exact warning flag for implicit floating-point to integer conversions is -Wfloat-conversion, which is also enabled by -Wconversion. For some unknown reason, -Wall, -Wextra, and -pedantic (which cpp.sh provides) don't include these flags.

If you use Clang, you can give it -Weverything to enable literally all warnings. If you use GCC, you must explicitly enable -Wfloat-conversion or -Wconversion to get a warning when doing such conversions (among other useful flags you will want to enable).

If you want, you can turn it to an error with e.g. -Werror-conversion.


C++11 even introduced a whole new safer initialization syntax, known as uniform initialization, which you can use to get warnings for the implicit conversions in your example without enabling any compiler warnings:

int intForcingFunc(double d) {
    return {d};  // warning: narrowing conversion of 'd' from 'double' to 'int' inside { }
}

int main() {
    double d{3.1415};  // allowed
    int localRes{d};  // warning: narrowing conversion of 'd' from 'double' to 'int' inside { }
}

Post Status

Asked in February 2016
Viewed 3,240 times
Voted 9
Answered 1 times

Search




Leave an answer


Quote of the day: live life