【问题标题】:int test (unsigned int i = -1); why does the compiler not generate a warning?整数测试(无符号整数 i = -1);为什么编译器不生成警告?
【发布时间】:2016-07-26 17:27:48
【问题描述】:

Unsigned int 默认不能为负数。编译器生成警告。 没关系。 但我不清楚为什么当我在具有负默认值的函数中执行相同操作时它不会生成警告。

unsigned int test(unsigned int i = -1) { return i;} // no warnings! Why?

int main()
{
   unsigned int i = -1;        // warning warning C4245 (ok!)
   unsigned int j = test();    // no warnings!  Why?     
}

【问题讨论】:

    标签: c++ visual-c++


    【解决方案1】:

    我同意您的编译器应该警告您默认参数是否定的。但是编译器并不完美。 (并且该标准允许将负整数值转换为无符号类型。)

    至于调用 test() 的警告,可怜的编译器如何知道 test()总是 返回-1?函数的定义甚至可能在不同的编译单元中! (当然不是你的情况,但编译器在发出警告时不应该横向考虑。)

    如果testconstexpr 限定,那么情况就不同了,编译器应该能够发出警告。

    【讨论】:

    • 我用 G++ 5.1 测试过,constexpr 在这种情况下似乎没有产生任何警告。
    • 哼。我认为它应该。像 -1.1 这样实际上是 UB 的东西呢?
    • @Bathsheba 你是说unsigned int i = -1.1 是未定义的行为?
    • 当然在 C 中。从今天开始,这里有一个关于这个的问题:stackoverflow.com/questions/36443556/…
    【解决方案2】:

    这种转化是allowed without a cast,只要你准备好承受后果:

    unsigned 整数类型的对象可以转换为对应的signed 类型。但是,如果无符号对象的值超出有符号类型可表示的范围,这种转换可能会导致数据误解。

    不过,当您进行从已签名到未签名再返回的转换时,the data will be preserved

    【讨论】:

    • 确实是允许的(有趣的是,虽然 -1.0 也允许,但浮点值低于 UB),但我对(好)问题的解读是为什么编译器不 警告你。
    • 当 OP 将有符号的-1 设置为i 时,编译器知道数据将超出unsigned 可表示的范围,因此会发出警告。关于为什么 C++ 标准在可能发生错误解释时不需要警告,我唯一的猜测是它保证了相同的位表示,并且无操作的潜在危害是有限的。
    猜你喜欢
    • 2011-01-22
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多