42
static_assert(sizeof(unsigned) == 4, ":(");
static_assert(sizeof(double) == 8 ,":(");
unsigned u{42};
double x{u};

g ++ 4.7.1は、このコードについて文句を言います。

warning: narrowing conversion of 'u' from 'unsigned int' to 'double' inside { }

なぜこれがナローイングコンバージョンなのですか?すべてがunsigned完全に表現できるわけではありませんdoubleか?

4

3 に答える 3

45

なぜこれがナローイングコンバージョンなのですか?

定義には(私の強調で)含まれているため:

C ++ 11 8.5.4 / 7ナローイング変換は、整数型[...]から浮動小数点型への暗黙の変換[...]です。ただし、ソースが定数式であり、その後の実際の値は変換はターゲットタイプに適合し、元のタイプに変換して戻すと元の値を生成します。

uは定数式ではないため、ソースタイプのすべての可能な値がターゲットタイプで表現可能であるかどうかに関係なく、変換が狭くなります。

すべてがunsigned完全に表現できるわけではありませんdoubleか?

それが定義された実装です。32ビットunsignedおよびdouble52ビットの仮数の一般的なケースでは、それが当てはまります。ただし、一部の実装では表現が大きくなっunsignedたり小さくなったりdoubleするため、その仮定に依存するコードは移植性がありません。

于 2012-07-17T11:02:12.570 に答える
4

xを非定数式で初期化するために発生する警告

Ilyas-iMac:TestC++11 sandye51$ cat main.cpp                   
int main()
{
    static_assert(sizeof(unsigned) == 4, ":(");
    static_assert(sizeof(double) == 8 ,":(");
    constexpr unsigned u{42};
    double x{u};

    return 0;
}Ilyas-iMac:TestC++11 sandye51$ gcc -o main main.cpp -std=c++11
Ilyas-iMac:TestC++11 sandye51$ 

ご覧のとおり、上記のコードは警告やエラーなしで機能します

于 2012-07-17T11:01:37.467 に答える
1

(試してみましょう:)doubleは、正確に52ビットの有効な(2進数)桁(ieee標準による)をunsigned int持っていますが、他のシステムでは64ビットが適切な場合があります。したがって、unsigned intシステムの実際の幅は、このチェックには価値がない可能性があります。

于 2012-07-17T11:01:41.933 に答える