9 c undefined-behavior language-lawyer
如果我正在编写通用算法,我是否允许将未知类型的数组作为指向数组的指针,其中每个元素的大小都是在不调用未定义行为的情况下提供的?
例如,以下代码中是否有UB?
typedef void (*action_t)(const void *item);
void do(void *array, size_t eltCount, size_t eltSize, action_t action)
{
// Convenient typedef.
typedef char element[eltSize];
element *elts = array;
element *end = elts + eltCount;
for (; elts != end; elts++) {
action(elts);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以这样做:
char *elts = array;
char *end = elts + eltCount * eltSize;
for (; elts != end; elts += eltSize) {
action(elts);
}
Run Code Online (Sandbox Code Playgroud)
但是第一部分代码对我来说似乎更惯用,因为编译器为我做了指针运算.上面的函数使用gcc和clang编译时没有警告(相关的编译标志是-std=c99 -O3 -fstrict-aliasing -pedantic-errors -Wextra -Wall).我也想知道严格的混叠,但据我所知,似乎我没有在这里打破它,因为允许间接通过对象使用char*.
在 C 中,typedef 不会引入新类型。它只是命名一个构造。该名称及其定义是可以互换的。(对于 来说,情况并非如此struct,除了名称之外,没有其他方法可以表达结构的定义。)
因此,只要您只是谈论某种形式char *(如您所知,这是特殊的,因为任何数据指针都可以转换为它),那么您就依赖于定义的行为。