我有以下代码:

#include <iostream>

char add(char a, int b)
{
    return a + b;
}

int main(void)
{
    long long a = 100000000;
    long long b = 20;

    int x = add(a, b);

    std::cout << x << std::endl;

    return 0;
}

而且我不明白为什么我的代码编译时没有任何警告。

带有该标志的 GCC 编译器不应该-Wall给我类型不匹配错误吗?

1

  • 注意:有时(但不是这次),您必须强制编译器更仔细地查看您的代码以获取错误警告,并且必须打开或启动优化器。


    – 


最佳答案
2

这不是一个错误,而是一个有效的隐式转换,尽管它涉及缩小类型。例如,-Weverything在 clang 中,你可以得到关于此问题的警告,它将发出

<source>:13:17: warning: implicit conversion loses integer precision: 'long long' to 'char' [-Wimplicit-int-conversion]
   13 |     int x = add(a, b);
      |             ~~~ ^
<source>:13:20: warning: implicit conversion loses integer precision: 'long long' to 'int' [-Wshorten-64-to-32]
   13 |     int x = add(a, b);
      |             ~~~    ^    

6

  • 谢谢。但我的下一个问题是:如果编译器会转换类型,为什么还会存在函数重载?


    – 

  • 4
    函数重载与隐式转换略有不同。参数可隐式转换这一事实仅意味着该重载是重载解析的有效候选者,尽管在解析选择哪个特定重载时仍存在排名,而隐式转换是标准的一部分。请参阅


    – 

  • @Noah – 此外,类型转换来自 C,它没有那么多类型,也没有函数重载。C++ 只是为了兼容性而保留它。


    – 

  • 1
    @BoP — C++ 具有隐式类型转换,因为它们很有用。您确实不想每次需要转换时都必须编写强制类型转换。


    – 

  • @PeteBecker:Rust 不敢苟同。;-) (是的,这有时对 Rust 来说真的很麻烦,但它确实可以防止各种类似的问题)


    – 


-Wall不包括所有警告。如果您需要此特定警告,则应使用以下命令明确请求-Wconversion

78623032.cpp: In function ‘char add(char, int)’:
78623032.cpp:5:14: warning: conversion from ‘int’ to ‘char’ may change value [-Wconversion]
    5 |     return a + b;
      |            ~~^~~
78623032.cpp: In function ‘int main()’:
78623032.cpp:13:17: warning: conversion from ‘long long int’ to ‘char’ may change value [-Wconversion]
   13 |     int x = add(a, b);
      |                 ^
78623032.cpp:13:20: warning: conversion from ‘long long int’ to ‘int’ may change value [-Wconversion]
   13 |     int x = add(a, b);
      |                    ^