红联Linux门户
Linux帮助

std::size_t在Linux下是8字节,在Windows下是4字节

发布时间:2016-11-07 10:58:19来源:linux网站作者:zes11478
我在Windows下写了一个程序,然后放到Linux上编译时,出现了很奇怪的提示,遂将问题代码抽离出来,发现原因在于:std::size_t在Linux下是8字节,在Windows下是4字节。当参数为引用时容易出错。
 
抽离后的代码如下所示:
#include <iostream>  
#include <string>  
#include <cstdint>//cstdint standard header, uint32_t, int32_t,  
#include <cassert>//cassert standard header,  
#include <memory>//std::shared_ptr,  
typedef std::shared_ptr<std::string> StdStringPtr;  
class TestBuffer  
{  
public:  
TestBuffer();  
public:  
void Feed(const char* data, uint32_t len);  
StdStringPtr NextMessage();  
private:  
static StdStringPtr ParseMessage(const char* buff, uint32_t& posBeg, uint32_t posEnd);  
private:  
std::string m_buf;  
std::size_t m_posBeg;//std::size_t在Linux下是8字节,在Windows下是4字节.  
std::size_t m_posEnd;  
};  
TestBuffer::TestBuffer() :m_posBeg(0), m_posEnd(0){}  
void TestBuffer::Feed(const char* data, uint32_t len)  
{  
m_buf.append(data, len);  
m_posEnd += len;  
}  
StdStringPtr TestBuffer::NextMessage()  
{  
StdStringPtr msg = TestBuffer::ParseMessage(m_buf.c_str(), m_posBeg, m_posEnd);  
assert(m_posBeg <= m_posEnd);  
return msg;  
}  
StdStringPtr TestBuffer::ParseMessage(const char* buff, uint32_t& posBeg, uint32_t posEnd)  
{  
StdStringPtr msg = nullptr;  
const uint32_t msgLen = 5;  
//随便写一个实现:5个字符作为一个消息.  
if (msgLen <= posEnd - posBeg)  
{  
msg = std::make_shared<std::string>(buff + posBeg, msgLen);  
posBeg += msgLen;  
}  
return msg;  
}  
int main()  
{  
std::printf("sizeof(uint32_t)   =%d\n", sizeof(uint32_t));  
std::printf("sizeof(uint64_t)   =%d\n", sizeof(uint64_t));  
std::printf("sizeof(std::size_t)=%d\n", sizeof(std::size_t));  
std::string str = "abcde12345ABCDE67890";  
TestBuffer myBuf;  
myBuf.Feed(str.c_str(), str.length());  
StdStringPtr msg;  
while ((msg = myBuf.NextMessage()).get() != nullptr)  
std::cout << (*msg) << std::endl;  
std::cout << "WILL EXIT..." << std::endl;  
return 0;  
}
 
在Linux下编译时报错:
[root@localhost ~]# g++ -std=c++11 test.cpp  
test.cpp: In member function ‘StdStringPtr TestBuffer::NextMessage()’:  
test.cpp:33:82: error: no matching function for call to ‘TestBuffer::ParseMessage(const char*, std::size_t&, std::size_t&)’  
StdStringPtr msg = TestBuffer::ParseMessage(m_buf.c_str(), m_posBeg, m_posEnd);
^
test.cpp:33:82: note: candidate is:  
test.cpp:16:25: note: static StdStringPtr TestBuffer::ParseMessage(const char*, uint32_t&, uint32_t)  
static StdStringPtr ParseMessage(const char* buff, uint32_t& posBeg, uint32_t posEnd);
^
test.cpp:16:25: note:   no known conversion for argument 2 from ‘std::size_t {aka long unsigned int}’ to ‘uint32_t& {aka unsigned int&}’  
[root@localhost ~]#
 
刚看到错误提示时,发现函数声明变成‘TestBuffer::ParseMessage(const char*, std::size_t&, std::size_t&)’了,但是我的函数明明是'TestBuffer::ParseMessage(const char* buff, uint32_t& posBeg, uint32_t posEnd)'呀,当时让人感觉太奇怪了。
 
总结:以后变量的定义、类的数据成员的定义、 函数的定义、等接口性质的地方,一律#include <cstdint>,然后用int32_t、uint32_t、int64_t、uint64_t、等不会有歧义的类型。对于std::size_t类型,已经在std里面了,我原以为它不会有歧义了,没想到随着平台的不同,它还是有改变。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/25789.html