今天我第一次制作了64bit的项目版本.基本上它编译,链接并运行正常,除了抱怨新的64位size_t类型和简单int类型之间不兼容的警告.这主要发生在我的代码中这样的情况:
void func(std::vector<Something> &vec)
{
int n = vec.size();
for (int i=0; i < n; i++)
{
....vec[i]....
}
}
Run Code Online (Sandbox Code Playgroud)
这很容易修复,我读了一篇文章说应该使用size_t或ptrdif_t作为循环索引.但是在这种情况下我能做些什么呢?
void outsideLibraryFunc(int n);
void func(std::vector<Something> &vec)
{
int n = vec.size();
outsideLibraryFunc(n);
}
Run Code Online (Sandbox Code Playgroud)
我无法更改外部库的函数声明,它需要一个int类型的参数,我需要传递向量元素的数量.除了禁用编译器警告外,我还能做些什么?
我刚看到一些像这样的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;
}
Run Code Online (Sandbox Code Playgroud) 我喜欢为VS.NET和GCC免费提供代码警告,我喜欢让我的代码准备好64位.
今天我写了一个小模块来处理内存缓冲区,并通过文件样式的接口提供对数据的访问(例如,你可以读取字节,写字节,搜索等).
作为当前读取位置和大小的数据类型,我使用size_t,因为这似乎是最自然的选择.我绕过警告,它也应该在64位工作.
以防万一:我的结构看起来像这样:
typedef struct
{
unsigned char * m_Data;
size_t m_CurrentReadPosition;
size_t m_DataSize;
} MyMemoryFile;
Run Code Online (Sandbox Code Playgroud)
签名size_t似乎没有在实践中定义.Google代码搜索证明了这一点.
现在我处于两难境地:我想检查增加size_t的溢出因为我必须处理用户提供的数据,第三方库将使用我的代码.但是,对于溢出检查,我必须知道符号.它在实施中产生了巨大的差异.
那么 - 我应该如何在平台和编译器独立的方式编写这样的代码?
我可以检查size_t运行或编译时的签名吗?这将解决我的问题.或者也许size_t首先不是最好的主意.
有任何想法吗?
编辑:我正在寻找C语言的解决方案!
我一直在尝试创建一个for循环,它将根据网络数据包的长度进行迭代.在API中,event.packet-> dataLength存在变量(size_t).我想迭代从0到event.packet-> dataLength - 7每次迭代时我增加10但我有一个麻烦的世界.
我寻找解决方案,但一直找不到任何有用的东西.我尝试将size_t转换为unsigned int并使用它进行算术但不幸的是它没有用.基本上我只想要这样:
for (int i = 0; i < event.packet->dataLength - 7; i+=10) { }
Run Code Online (Sandbox Code Playgroud)
虽然每次我做这样的事情或尝试我的转换时,我<#part都是一个巨大的数字.他们在API的教程中给出了printf语句,该API使用"%u"来打印实际数字,但是当我将它转换为unsigned int时,它仍然是不正确的.我不知道从哪里开始.任何帮助将不胜感激 :)
我使用Oracle API访问数据库,此API具有readBuffer(char * buffer, unsigned int size);我无法进行任何更改的功能.
我有一个使用这个API的类,我的函数的签名当前需要a std::string和一个unsigned int大小,问题是,当我传递std::string.size()给我的函数的size参数时,我收到编译器的警告,转换size_t为unsigned intcan导致数据丢失.
我想知道是否有一种有效的方法将其转换size_t为一个unsigned int所以我可以将它传递给我的API而不是从编译器得到警告?
我理解为size_t的目的和谷歌搜索此转换变成了很多结果说:"改变采取的size_t ARG功能",但我CAN NOT改变我的API的签名在这种情况下.
有什么建议?
起初人们可能会想std::numeric_limits<size_t>::max(),但如果有一个巨大的物体,它还能提供一个一个接一个的指针吗?我猜不会.这是否意味着最大的价值sizeof(T)可以产生std::numeric_limits<size_t>::max()-1?我是对的,还是我错过了什么?
在这个问题中我看到以下内容:
for (vector<int>::size_type ix = 0; ix ! = ivec.size(); ++ix) {
ivec[ix] = 0;
}
Run Code Online (Sandbox Code Playgroud)
我明白为什么int不在这里使用,但为什么不使用size_t?
在什么情况下我应该用vector<int>::size_type而不是size_t?
我们在嵌入式平台上使用C89.我试图打印出来size_t,但它不起作用:
#include <stdio.h>
int main(void) {
size_t n = 123;
printf("%zu\n",n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
而不是123,我得到了zu.
其他说明符正常工作.
如果size_t存在不应该 zu也可用printf?
这是我应该联系我的图书馆供应商的事情,还是允许排除它的图书馆实施?
在我的平台上(以及我认为的大多数平台上)std::size_t并且std::ptrdiff_t 具有相同的大小和相同的对齐方式。有没有哪个平台不是真的?简而言之:标准是否要求?
标准 C++ 中是否有 size_t 的有符号变体?意味着与 size_t 完全相同的位大小,但有符号。
我当然可以这样做:
#include <type_traits>
using signed_size_t = std::make_signed_t<std::size_t>;
Run Code Online (Sandbox Code Playgroud)
但也许标准库中已经有类似的定义,而不是发明额外的类型名称?
我知道有 ssize_t 和 ptrdiff_t,都有签名。但根据他们的描述,它们似乎都可以具有与 size_t 不同的位大小。但我需要与 size_t 完全相同的位大小,但已签名。