2016-09-21 10 views
1

の左シフト・カウント> =幅を削除する:この同じコードがいない間このコードは警告を生成ないのはなぜタイプの警告

niko: snippets $ cat leftshift.c 
#include <stdint.h> 
#include <stdio.h> 

int main(void) { 

    uint32_t var1; 
    uint32_t var2; 

    var1=55; 
    var2=var1 << (sizeof(uint32_t)-8); 

    printf("%d\n",var2); 
} 
niko: snippets $ gcc -g -Wl,--warn-common -ffunction-sections -fshort-enums -fdata-sections -Wall -Wextra -Wunreachable-code -Wmissing-prototypes -Wmissing-declarations -Wunused -Winline -Wstrict-prototypes -Wimplicit-function-declaration -Wformat -D_GNU_SOURCE -fshort-enums -std=c99 -c leftshift.c 
leftshift.c: In function ‘main’: 
leftshift.c:10:12: warning: left shift count >= width of type [-Wshift-count-overflow] 
    var2=var1 << (sizeof(uint32_t)-8); 
      ^
niko: snippets $ 

を:

niko: snippets $ cat leftshift.c 
#include <stdint.h> 
#include <stdio.h> 

int main(void) { 

    uint32_t var1; 
    uint32_t var2; 

    var1=55; 
    var2=var1 << (32-8); 

    printf("%d\n",var2); 
} 
niko: snippets $ gcc -g -Wl,--warn-common -ffunction-sections -fshort-enums -fdata-sections -Wall -Wextra -Wunreachable-code -Wmissing-prototypes -Wmissing-declarations -Wunused -Winline -Wstrict-prototypes -Wimplicit-function-declaration -Wformat -D_GNU_SOURCE -fshort-enums -std=c99 -c leftshift.c 
niko: snippets $ 

はGCCに何か問題はありますか? uint32_tのサイズは32ビットなので、そうではありませんか?

答えて

2

Sizeofはバイト単位のサイズを返します。あなたはこれを試してみてください:

printf("%d\n", sizeof(uint32_t)); 

あなたはおそらく、あなたはビット単位でサイズをしたい場合、あなたは8掛けることができ32、それは4だということではない見つける:sizeof(uint32_t) * 8

+0

愚かな私。ありがとう! – Nulik

+1

'%d'は' size_t'が返す 'size_t'の型指定子が間違っていることに注意してください。代わりに '%zu'を使用するか、引数を型指定子に一致する型にキャストします。 – user694733

+2

'sizeof(uint32_t)* CHAR_BIT'は移植性が高く、自己文書化しています。 OTOH 'CHAR_BIT == 8'は非常に一般的です。 – chux

1

sizeof(uint32_t)お使いのシステムでは4です、したがって、最初のコードは、負の数である(4-8)として右のオペランドを取得します。したがって、警告です。

2番目のコードでは正の数なので、警告は表示されません。

+0

'sizeof(uint32_t)'は 'size_t'型ですので、sizeof(uint32_t)-8'は非常に大きな符号なしの数値になります。そのため、 "左シフトカウント** = **タイプの幅" – chux

+0

ビット演算子の右側は加算式です(c11の6.5.7)。負の場合もありますが、負の場合は結果が未定義です。整数昇格はsizeof(uint32_t)で行われ、signed intになり、結果はintに符号付きされます。シフト式の結果は未定義です。 –

+0

'sizeof(size_t) = sizeof(int)'の場合、結果は大きな符号なし整数です。いずれにしても、結果は右ビットシフトオペランド(0 ... 31)の許容範囲外であり、動作は不定です。 – user694733

関連する問題