将负整数与size_t一起使用是否安全
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;
}
每当我需要处理有符号类型时,我总是使用:
typedef std::make_signed<std::size_t>::type ssize_t; // Since C++11
。作为 std::size_t 的签名替代品。
我很欣赏这个问题已经有几年了,但我希望这对其他人有所帮助。感谢喜怒无常的骆驼::并发队列。
我不能说代码有多安全,但我认为这是一种非常糟糕的风格。更好的方法是使用支持正向或反向迭代的迭代器。
例如:
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";
}
}
将负整数与size_t一起使用是否安全?
不,这很危险。溢出。
size_t a = -1;
std::cout << a << "n";
输出:
4294967295 // depends on the system, largest value possible here
相关文章:
- GoogleMock是否仍然打算与任何测试框架一起使用?
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- 是否可以将 Clang-Tidy 与 QNX 一起使用?
- 是否可以将 std::basic_ifstream 和 std::basic_ofstream 与自定义缓冲区一起使用?
- 您是否必须随项目一起交付原型文件?
- 将 std::transform 与 std::back_inserter 一起使用是否有效?
- 是否已经有一个 constexpr std::bit_cast 与 g++ 一起使用
- 是否可以将存储在dword中的十六进制与getasynckeystate一起使用
- 是否可以将CRTP与本身已模板化的派生类一起使用
- 是否可以检索与柯南包管理器一起打包的库的源代码,以便在其中进行调试?
- 我是否需要将 ref 与 make_pair 一起使用才能返回引用?
- 将分配的内存与基本数据类型一起使用时,是否需要新放置? std::complex?
- 是否可以将引用类型别名与指针运算符一起使用来声明对指针的引用?
- iOS SDK 是否可以与动态库一起交付
- 是否可以在C++中将两个函数一起添加
- 是否可以与Gurobi一起使用C 中的元组
- 类模板参数扣除是否可与STD :: MAP一起使用
- 是否可以将SDL2与智能指针一起使用
- 是否可以重载模板函数以与 std::vector 的元素一起使用
- c++:将数组连接在一起-是否可能使用指针而不复制