Nil*_*nck 8 c integer-overflow size-t
我喜欢为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语言的解决方案!
Mic*_*urr 12
关于size_t是签名还是未签名和GCC(来自旧的GCC手册 - 我不确定它是否仍在那里):
在
size_t2.4版之前,GCC 的类型和版本存在潜在问题 .ANSI C要求size_t始终为无符号类型.为了与现有的系统的头文件兼容性,GCC限定size_t在stddef.h为任何类型系统的sys/types.h定义的那样.定义大多数Unix系统size_t中sys/types.h,定义它是一个符号的类型.库中的某些代码依赖于size_t无符号类型,如果签名则无法正常工作.期望
size_t无符号的GNU C库代码 是正确的.size_t作为签名类型的定义不正确.我们计划在版本2.4中,GCC将始终定义size_t为无符号类型,并且'fixincludes'脚本将按摩系统,sys/types.h以免与此冲突.与此同时,我们通过告诉GCC明确地
size_t在编译GNU C库时使用无符号类型来解决这个问题.'configure'将自动检测GCC使用哪种类型,size_t以便在必要时安排覆盖它.
如果你想要的签名版本size_t使用ptrdiff_t或在某些系统上存在的一个typedef ssize_t.
size_t 应该是未签名的。
它通常定义为 unsigned long。
我从未见过它有其他定义。ssize_t是它的签名对应物。
编辑:GCC 在某些情况下将其定义为已签名。在 ASNI C 模式或 std-99 下编译应该强制它是无符号的。
size_t根据 C++ C 标准,是无符号整数类型。任何已size_t签名的实现都严重不符合,并且可能还有其他可移植性问题。它保证在溢出时回绕,这意味着您可以编写类似if (a + b < a)查找溢出的测试。
size_t对于涉及记忆的任何事情来说都是一种很好的类型。你做得对。