与 stdarg 相关的 clang 错误?

标签 c clang

这似乎是 clang 中与空终止变量参数列表相关的错误。

预期的行为是 va_arg() 将在第一次迭代时返回 0,因为别名后面的参数是 0。

完整代码如下。在 main() 中,删除“void *map = 0;”或者调用 foo() 使错误消失。

#include <stdio.h>
#include <stdarg.h>

/*
clang --version:
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
*/

void *foo(char *a, char *b, char *c, ...) {
        return 0;
}

void *bar(char *a, char *b, char *c, char *d, char *e, char *f, char *alias, ...) {
        char *arg;
        va_list ap;
        va_start(ap, alias);
        printf("alias = %s\n", alias);
        while((arg = va_arg(ap, char *))) {
                printf("arg = %p\n", arg);
                printf("BUG!\n");
                return 0;
        }
        va_end(ap);
        printf("NO BUG\n");
        return 0;
}

int main() {
        void *map = 0; // removing this statement hides bug
        foo(0, 0, 0, 0);// removing this statement hides bug
        bar("a", "b", "c", "d", "e", "f", "b", 0);
}

输出是:

alias = b
arg = 0x100000000
BUG!

最佳答案

0 不是 char*;它是一个 int。所以用 va_arg(ap, char*) 读取它是未定义的行为。

当您指的是 char * 类型的空指针时,请提供参数 (char*)0。 (或者 (char*)NULL,如果您愿意的话。)作为 M.M.在评论中指出,常见的 NULL 是不正确的,因为 NULL 可能是 #defined as 0.

(因为0是一个int,编译器不关心高四字节,参数的低四字节确实是0 . 但那是一个实现细节;我只是以解释的方式提到它。)

关于与 stdarg 相关的 clang 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52286365/

相关文章:

c - Windows WFP驱动程序: Getting BSOD when processing packets in ClassifyFn callback

c++ - 使用 SSE/AVX 内在函数的快速点积

编译器错误消息定制

c - 中值滤波器实现测试

c - 函数只返回字符串的字母

c 静态 float 错误: ‘????’ redeclared as different kind of symbol

xcode - "bad codegen, pointer diff in boost"32 位构建错误

c++ - 在 10.15 之前的 mac 版本上,llvm 9 是否支持 std::filesystem?

c++ - Clang AST 将对 make_unique 的调用与特定类匹配

c - 通过三点A、B、C的坐标定义一个盒子