如果您知道在到达有效区域的末尾之前找到该字符,那么调用长度过长的memchr是否合法?
在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,则只有在需要访问整个长度时才会安全。
否则(如果上面的代码是合法的),实现必须避免对目标元素之外的元素进行潜在的error handling,例如通过对齐加载(可能很昂贵)或检查指针是否接近保护边界的末尾 。
1这是一个罕见的问题,我猜C和C ++的标记是有效的:据我所知,C ++标准只是在行为方面直接推迟到C标准,但是如果不是这样的话我想知道。
在C11和C ++ 17( 强调我的 )
void *memchr(const void *s, int c, size_t n);
memchr
函数在s
指向的对象的初始n
字符(每个解释为unsigned char
)中定位第一次出现的c
(转换为unsigned char
)。 实现的行为就像它按顺序读取字符一样,并在找到匹配的字符后立即停止。
只要memchr
在您走出界限之前找到了它正在寻找的东西,你就可以了。
C ++ 11和C ++ 14都使用C99,它没有这样的措辞。 (他们参考ISO / IEC 9899:1999)
C99措辞:
void *memchr(const void *s, int c, size_t n);
memchr
函数在s
指向的对象的初始n
字符(每个解释为unsigned char
)中定位第一次出现的c
(转换为unsigned char
)。
通过不定义如果传递太大的大小会发生什么,行为在C99中是未定义的