c - 与stdarg相关的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*)0
当您的意思是类型为空的指针时,请提供参数char *
。(或者(char*)NULL
,如果您愿意。)正如 MM 在评论中指出的那样,常见的NULL
不正确,因为NULL
可能#define
d 为0
。
(既然0
是 an int
,编译器就不关心高四字节了。参数的低四字节确实是0。但这是一个实现细节;我只是作为解释的方式提到它。)
推荐阅读
- mysql - 当我使用 union all 和 group by 时获取所有最后一个 id
- mongodb - 如何获取 MongoDB 集合中特定字段的数组元素总数?
- php - 每次部署后 Amazon EC2 Linux PHP 都会变慢
- c# - C# Mono 程序在自动执行时在树莓派上崩溃
- jquery - 使用 jquery 从节点添加链接
- r - 彭博基金定价设定币种
- python - 箱线图组如何在 matplotlib 中具有不同的颜色和相应的图例?
- php - Symfony 3.4:如何在 UnitTest 中获取 serviceContainer
- python - pypi依赖中的“额外”是什么?
- javascript - React 应用程序打开带有错误 URL 的新选项卡,https 而不是 https: