簡體   English   中英

if 語句中的 sizeof() 運算符

[英]sizeof() operator in if-statement

#include <stdio.h>
int main(void)
{
    if (sizeof(int) > -1)
        printf("True");
    else
        printf("False");
}

它打印False 為什么 sizeof() 不在if返回值?

  1. sizeof不是一個函數,它是一個運算符。 括號不是運營商名稱的一部分。
  2. 它失敗是因為生成的值具有無符號類型size_t ,這會導致“通常的算術轉換”,其中-1被轉換為無符號,在這種情況下它是一個非常大的數字。

基本上你是在比較4 > 0xffffffffu ,或者至少接近這個值。 有關詳細信息, 請參閱此問題

無符號和有符號整數提升(更准確地說,是“通常的算術轉換”)。 sizeof產生一個size_t類型的值,當與一個無符號值( size_t是)相比時,-1 被提升為該類型,並溢出並變得巨大。

無符號整數溢出具有明確定義的行為,並被視為模2 ^ width ,其中width是特定無符號整數類型中的位數。 因此,例如,如果您有一個 32 位寬的size_tint ,則您的比較將等同於

if (4 > 4294967295u)

這顯然是錯誤的。

  • if 語句中 > 運算符的操作數是sizeof(int)-1
  • sizeof(int)size_t類型,它保證是一個無符號整數。 實際上,在任何系統上, size_t很可能至少與unsigned int一樣大。
  • -1int類型,它等價於signed int
  • 沒有整數提升發生,因為兩個操作數都是足夠大的整數類型。
  • 然后根據正式稱為通常算術轉換的 C 規則平衡兩個操作數。

這些狀態(C11 6.3.1.8):

...

否則,如果有符號整數類型操作數的類型可以表示無符號整數類型操作數類型的所有值,則將無符號整數類型操作數轉換為有符號整數類型操作數的類型。

否則,兩個操作數都被轉換為與帶符號整數類型的操作數的類型對應的無符號整數類型。

  • 上面的后者將會發生,因為(有符號的) int不能適合size_t所有值。
  • 因此-1被轉換為無符號整數。 實際上, size_t很可能相當於 unsigned int 或 unsigned long。 在這樣的變量中存儲 -1 時發生的任何事情都是實現定義的行為。
  • 在二進制補碼計算機(世界上所有計算機的 99.9%)上,-1 將被解釋為0xFFFFFFFF (FF 的數量取決於給定系統上 int 的大小)。
  • 4 > 0xFFFFFFFF評估為假。

Sizeof 是一個運算符,它產生一個 unsigned long int。 因此,當您將 unsigned long int 與 -1 進行比較時,它存儲為0xffffffff (int 的大小為 4 個字節)。

-1 默認是有符號整數。 但是,在有符號整型和無符號整型之間進行比較時,編譯器將有符號整型隱式轉換為無符號整型。 這導致無符號 -1 大約等於 4.6giga 值。

因此,輸出為false

只需測試一下,自己看看

#include <stdio.h>
main() {
    unsigned int a=4;
    int b = -1;
    //this is what you're doing
    printf("%u vs %u\n", a, (unsigned int)b);
    //this is what you want to do instead
    printf("%d vs %d\n", (int)a, b);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM