gcc奇怪的转换警告(从'int'转换为'A <b> :: count_type {aka short unsigned int}'可能会改变其值)

时间:2015-12-13 14:55:39

标签: c++ c++11 gcc

我使用模板跟随C ++ 11代码:

struct Base{
    using count_type = unsigned short;
};

template<class T>
struct A : public Base{
    using count_type = A::count_type;
    // not works even if I comment this

    count_type add(T x){
        count_type sum = 5;
        sum += x.value(); 
        //sum += (count_type) x.value(); // not works even if I cast this, e.g.


        return sum;
    }
};

struct B{
    using count_type = A<B>::count_type;

    count_type value(){
        return 5; // not works even if I do:
        //return (count_type) 5;
        //return 5U;
    }
};

int main(int argc, char *argv[]){
    B b;

    A<B> a;

    a.add(b);
}

当我尝试使用-Wconversion进行编译时,出现了奇怪的错误消息:

$ g++ -std=c++11  -Wconversion x.cc
x.cc: In instantiation of ‘A<T>::count_type A<T>::add(T) [with T = B; A<T>::count_type = short unsigned int]’:
x.cc:29:9:   required from here
x.cc:11:7: warning: conversion to ‘A<B>::count_type {aka short unsigned int}’ from ‘int’ may alter its value [-Wconversion]
   sum += x.value();
       ^

为什么会这样?在任何地方都没有int

如果有人编辑我的问题,我将不胜感激。

注意:clang不会发出此类警告。

2 个答案:

答案 0 :(得分:1)

sum += x.value();表示(大致)sum = sum + x.value();此处的RHS sum + x.value()会添加两个unsigned short值并生成int。将int分配回unsigned short可以改变其值。

在我看来,警告不是特别有用,我建议将其关闭,但如果你想因某些原因保持启用,请在那里写一个演员:

sum = (count_type) (sum + x.value());

sum = static_cast<count_type>(sum + x.value());

答案 1 :(得分:1)

根据隐式促销,任何算术表达式(如sum = sum + x.value())都会经历称为通常的算术转换的模式,标准的第5节中的相关部分:

  

...

     

- 否则,将对两个操作数执行整数促销(4.5)。 59然后,以下规则应适用于晋升的操作数:

整体促销指定:

  

bool,char16_t,char32_t或wchar_t 之外的整数类型的prvalue,其整数转换等级(4.13)小于int的等级,可以转换为int类型的prvalue < / strong>如果int可以表示源类型的所有值;否则,源prvalue可以转换为unsigned int类型的prvalue。

因此操作数转换为int,然后转换为unsigned short。这是因为转换排名指定了

  

有符号整数类型的等级应大于任何有符号整数类型的等级。

  

任何无符号整数类型的等级应等于相应的有符号整数类型的等级。