2017-11-01 4 views
7

負の数にビットシフトします。リテラルで負の値をシフトすると[-Wshift-negative-value]警告が表示されるのはなぜですか?

int main(void) { 
    int count = 2; 
    printf("%d\n", ~0<<count); 
    printf("%d\n", ~0<<2); // warning:shifting a negative signed value is undefined [-Wshift-negative-value] 
    return 0; 
} 

整数リテラルは、変数が使用されるときシフトしないで使用した場合、警告がコード上にコンパイル上に来ているなぜ疑いがあります。

+2

彼はなぜ '〜0 << 2'という警告が出るのかと尋ねていますが、'〜0 << count'はしません。 –

+1

@ChristianGibbonsええ、それを得ました。少し遅すぎた –

+2

おそらく 'count'は' 0 'になる可能性があります –

答えて

2

C89で負の値の左シフトを処理するには、それらのプラットフォームで最も論理的ではない方法で、1の補数と符号の大きさの実装が必要でした。たとえば、1の補数のプラットフォームでは、C89は、-1として-1を設定しています。< <この標準の作成者は、コンパイラライターが、負の数の左シフトをどのような方法でも処理できるようにすることで、この問題を修正することに決めました。 2の補数の実装を含むすべての実装に柔軟性を持たせることは、2の補完の実装がC89の動作から逸脱することを意図していることを意味するものではありません。はるかに高い可能性があり、コンパイラライターが命令の有無にかかわらずそれを理解できるように、2の補数のプラットフォームでの賢明な振る舞いが十分に明白になることを意図し、期待しました。

xy両方が定数である場合x<<yを簡略化することができるので、コンパイラは、多くの場合、他の定数によって左シフト、負の定数についてスコーク、そのような単純化は、シフトを含むコードであるか否かをコンパイル時にシフトを行うことが必要となります実行した。対照的に、someConstant << nonConstantを指定すると、通常単純化は不可能であるため、コンパイラは実行時にシフトを行うコードを単純に生成します。

関連する問題