2013-01-07 78 views
20

C中的哪個類型應該用來表示兩個對象的大小之間的差異?什麼類型減去2 size_t的?

由於size_t是無符號,像

size_t diff = sizeof (small_struct) - sizeof (big_struct); 

顯然不會是正確的,在我看來,沒有真正簽署等同。

ptrdiff_t聽起來有點誘人的,但

  1. 就像它的名字說,這是減去指針。
  2. 我讀過例如像DOS這樣的分段平臺的最大對象大小爲64k,可以用16位表示。然而,遠指針由一個16位段值和一個16位偏移值組成。那麼在這樣一個32位的平臺上,這難道不會讓ptrdiff_t? 如果是這樣,兩個大小不同的對象之間的差異只需要16位,但使用ptrdiff_t會給你一個32位寬的變量,使它不是最優的。

那麼,什麼是合適的,便攜式的工作與這樣的價值?

Edit: 我知道ssize_t供,但它是

  1. 的標準C.
  2. 其實並不希望用於此用途不是一部分,而是用於返回無論是尺寸還是(負)誤差值。
+0

'ssize_t'簽訂'size_t' –

+1

@AFAIK'ssize_t'是POSIX,而不是ISO C. –

+2

@RomanR。 'ssize_t'不是C標準,'size_t'的值不能保證適合POSIX中的'ssize_t'。 – ouah

回答

8

沒有一個標準的數據類型可以保證100%的安全。作爲證據,假設size_t真的只是uint64_t,這完全有可能。然後,沒有標準的C數據類型保證有一個與uint64_t匹配的正範圍,並且也處理負值。

因此,你的問題的直率答案是「沒有數據類型」(假定嚴格遵守標準C,你似乎期望)。

但是,您不清楚您的用例,並且可能您可能能夠利用模運算來處理「負值」值。例如,the following code導致d24因爲模運算,這樣,如同size_t簽署的代碼行事:

#include <stdio.h> 
#include <stdint.h> 

int main() 
{ 
    size_t d1 = sizeof(int32_t) - sizeof(int64_t); 
    size_t d2 = sizeof(int64_t) + d1; // Add difference (even if d1 is "negative"*) 

    printf("d1: %zu\n", d1); 
    printf("d2: %zu\n", d2); 

    return 0; 
    // * By "negative" I mean that d1 would be negative if size_t were signed 
} 

模運算可能是不夠的,你在你的情況,但對其他人來說可能。

18

當我真的很擔心這樣的溢出問題(尤其是在模運算工作時,這裏的「負」值換地方以外~0)我只是把它分成兩種情況:

if (a > b) { 
    size_t diff = a - b; 
} else { 
    size_t diff = b - a; 
    // code here subtracts diff rather than adds it, etc. 
} 
2

有是沒有符號的C整數類型,它可以保存來自size_t值的所有值。

+2

在你的實現?還是標準專門禁止? :) – pmg

+0

我的意思是在所有的實現。當然,所有'size_t'值都可以符合有符號整數類型。 – ouah

-2

你可以這樣做:

size_t diff = std::abs(static_cast <int> (sizeof (small_struct) - sizeof (big_struct)));