如果我正在编写通用算法,我是否允许将未知类型的数组作为指向数组的指针,其中每个元素都是提供的大小而不调用未定义的行为?
例如,以下代码中是否有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);
}
}
我知道我可以这样做:
char *elts = array;
char *end = elts + eltCount * eltSize;
for (; elts != end; elts += eltSize) {
action(elts);
}
但是第一部分代码对我来说似乎更惯用,因为编译器为我做了指针运算。上面的函数使用gcc和clang编译时没有警告(相关的编译标志是-std=c99 -O3 -fstrict-aliasing -pedantic-errors -Wextra -Wall
)。我也想知道严格的别名,但据我所知,似乎我没有在这里打破它,因为允许通过char*
间接使用对象。
答案 0 :(得分:1)
在C中,typedef不会引入新类型。它只是命名一个结构。名称及其定义可以互换。 (例如,struct
也是如此,除了名称之外,没有办法表达结构的定义。)
所以,只要您只谈论某种形式的char *
- 正如您所知,这是特殊的,因为任何数据指针都可以转换为它 - 那么您就是这样了依赖于定义的行为。