如果您知道字符会在到达有效区域末尾之前找到,那么调用长度过长的 memchr 是否合法?

Is it legal to call memchr with a too-long length, if you know the character will be found before reaching the end of the valid region?

C11 和 C++11 中是否定义了以下行为1?

bool has4() {  
    char buf[10] = {0, 1, 2, 4};
    return memchr(buf, 4, 20);
}

此处我们将过长的长度传递给memchr。该数组有 10 个元素,但我们传递了 20 个。但是,我们正在搜索的元素总是在末尾之前找到。我很清楚这是否合法。

如果允许这样做,则会限制实现的灵活性,因为实现不能依赖大小作为可访问内存区域大小的有效指示,因此必须小心读取超出找到的元素。一个例子是一个实现,它想要从传入的指针开始执行 16 字节的 SIMD 加载,然后并行检查所有 16 字节。如果用户传递的长度为 16,则只有在要求整个长度都可访问时,这才是安全的。

否则(如果上面的代码是合法的)实现必须避免在目标元素之后的元素上发生潜在的错误,例如通过对齐负载(可能代价高昂)或检查指针是否靠近 .


1 这是我猜想同时标记 C 和 C++ 是有效的那些罕见问题之一:据我所知,C++ 标准只是直接遵从此处的 C 标准,通过参考,就行为而言,但如果情况并非如此,我想知道。

在 C11 和 C++17 中(强调我的

void *memchr(const void *s, int c, size_t n);

The memchr function locates the first occurrence of c (converted to an unsigned char) in the initial n characters (each interpreted as unsigned char) of the object pointed to by s. The implementation shall behave as if it reads the characters sequentially and stops as soon as a matching character is found.

只要 memchr 在您越界之前找到它要查找的内容,就可以了。


C++11和C++14都是用的C99,没有这样的写法。 (他们指的是ISO/IEC9899:1999)

C99写法:

void *memchr(const void *s, int c, size_t n);

The memchr function locates the first occurrence of c (converted to an unsigned char) in the initial n characters (each interpreted as unsigned char) of the object pointed to by s.

通过不定义如果传递的大小过大会发生什么,在 C99

中行为是 未定义