通过指向字符数组的指针一般访问数组项?

时间:2017-06-24 17:32:07

标签: c language-lawyer undefined-behavior

如果我正在编写通用算法,我是否允许将未知类型的数组作为指向数组的指针,其中每个元素都是提供的大小而不调用未定义的行为?

例如,以下代码中是否有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*间接使用对象。

1 个答案:

答案 0 :(得分:1)

在C中,typedef不会引入新类型。它只是命名一个结构。名称及其定义可以互换。 (例如,struct也是如此,除了名称之外,没有办法表达结构的定义。)

所以,只要您只谈论某种形式的char * - 正如您所知,这是特殊的,因为任何数据指针都可以转换为它 - 那么您就是这样了依赖于定义的行为。