Jos*_*man 2 c pointers c99 intptr
我可以假设以下不变量吗?
void foo(char *buf, size_t len) {
// "buf" points to either an array or memory allocated with malloc().
assert((uintptr_t)(buf + len) < UINTPTR_MAX);
}
Run Code Online (Sandbox Code Playgroud)
在我正在编写的解析器中,我想使用指针标记某些偏移:例如,我可能有char *end_of_submessage,end_of_submessage相对于我当前的缓冲区.但是如果子消息没有在当前缓冲区内结束,我想使用一个大于当前缓冲区中任何偏移量的值.所以我会这样做:
void parse(char *buf, size_t len, uintptr_t end_of_submessage) {
// Some parsing that might increment "buf"
// ...
// If end_of_submessage == UINTPTR_MAX, processing will not be
// triggered even if we have processed our entire current buffer.
if ((uintptr_t)buf >= end_of_submessage)
process_submsg_end();
}
Run Code Online (Sandbox Code Playgroud)
但是如果malloc()返回内存ptr + len == UINTPTR_MAX,或者数组具有相同的属性,那么这个方案就会被挫败.假设这种情况永远不会发生是否安全?根据标准是否安全?如果没有,在实践中是否安全?
C标准提供的唯一保证如下:
ISO/IEC 9899:1999(E)§7.18.1.4/ 1
以下类型指定一个带符号的整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针:
Run Code Online (Sandbox Code Playgroud)intptr_t以下类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针:
Run Code Online (Sandbox Code Playgroud)uintptr_t这些类型是可选的.
不保证这些转换整数的精确内容.特别是,给定一个char指针p,(uintptr_t)(p + 1) == ((uintptr_t)p) + 1不保证是真的.
如果要标记偏移,则应使用ptrdiff_t另一个指针的偏移量,或者只需使用指针标记结束.例如:
void parse(char *buf, size_t len, char *end_of_submessage)
{
// ...
if (buf >= end_of_submessage)
process_submsg_end();
}
Run Code Online (Sandbox Code Playgroud)
如果end_of_submessage可能位于不同的缓冲区中,您可以使用以下内容:
char *buf_start = buf;
// ...
if (buf_start <= end_of_submessage && buf >= end_of_submessage)
process_submsg_end();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
185 次 |
| 最近记录: |