[英]Is it safe to use negative integers with size_t?
我剛看到一些像這樣的C ++代碼。 它使用一個條件來決定是通過std::vector
前進還是后退。 編譯器沒有抱怨,但我認為size_t
是無符號的。 這有危險嗎?
vector<int> v { 1,2,3,4,5 };
bool rev = true;
size_t start, end, di;
if (rev) {
start = v.size()-1;
end = -1;
di = -1;
}
else {
start = 0;
end = v.size();
di = 1;
}
for (auto i=start; i!=end; i+=di) {
cout << v[i] << endl;
}
通過這種方式很好地定義了使用無符號整數(並且size_t
是無符號的),並且有回繞:標准保證了這種行為,而不是有符號整數,標准不保證這種行為。
然而,這是不必要的聰明。
作為一般規則,為了避免由於隱式包裝促銷到無符號的問題,使用無符號整數用於位級別的東西,使用有符號整數來表示數字。 你需要一個對應於size_t
有符號整數,你可以找到ptrdiff_t
。 定義帶有簽名結果的n_items
函數,例如
using Size = ptrdiff_t;
template< class Container >
auto n_items( Container const& c )
-> Size
{ return end( c ) - begin( c ); }
你已經准備好了,不再是編譯器的愚蠢行為。
而不是太聰明的給定代碼
vector<int> v { 1,2,3,4,5 };
bool rev = true;
size_t start, end, di;
if (rev) {
start = v.size()-1;
end = -1;
di = -1;
}
else {
start = 0;
end = v.size();
di = 1;
}
for (auto i=start; i!=end; i+=di) {
cout << v[i] << endl;
做例如
const vector<int> v { 1,2,3,4,5 };
const bool reverse = true; // whatever
for( int i = 0; i < n_items( v ); ++i )
{
const int j = (reverse? n_items( v ) - i - 1 : i);
cout << v[j] << endl;
}
我不能說代碼有多安全 ,但我認為這是一種非常糟糕的風格。 更好的方法是使用支持正向或反向迭代的迭代器。
例如:
std::vector<int> v = { 1, 2, 3, 4, 5 };
bool rev = true;
if (rev)
{
for (auto itr = v.rbegin(); itr != v.rend(); ++itr)
{
std::cout << *itr << "\n";
}
}
else
{
for (auto itr = v.begin(); itr != v.end(); ++itr)
{
std::cout << *itr << "\n";
}
}
每當我需要處理簽名類型時,我總是使用:
typedef std::make_signed<std::size_t>::type ssize_t; // Since C++11
...作為std :: size_t的簽名替代。
我很欣賞這個問題已經有幾年了,但我希望能幫到別人。 感謝moodycamel :: ConcurrentQueue 。
使用size_t的負整數是否安全?
不,這很危險。 溢出。
size_t a = -1;
std::cout << a << "\n";
輸出:
4294967295 // depends on the system, largest value possible here
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.