【发布时间】:2017-04-03 01:04:09
【问题描述】:
这段代码有什么问题?
#include <stdio.h>
#include <stdarg.h>
void myprintf(const char * format, ...) __printflike(1, 2);
int main(int argc, const char * argv[]) {
printf("%s\n");
myprintf("%s\n");
return 0;
}
void myprintf(const char * format, ...) {
if (format) {
va_list arguments;
va_start(arguments, format);
vprintf(format, arguments);
va_end(arguments);
}
}
通过使用__printflike,我收到了一个很好的警告,例如printf。但与至少打印垃圾的printf 不同,我在调用vprintf 时得到 EXC_BAD_ACCESS,如下所示:
有什么方法可以让我完成这项工作吗? 谢谢!
更新: 我知道通过使用错误数量的参数调用函数,我会得到未定义的行为,但我希望 myprintf 的行为就像 printf 一样(不会崩溃) .那可能吗?有什么方法可以在调用vprintf 之前检查参数以避免异常?
更新 2: 我想我现在明白了,感谢所有 cmets 和答案。对于这个非常简单的示例,我认为最好使用宏,它快速失败并在调用点崩溃:
【问题讨论】:
-
"printf,至少打印垃圾"。这不是保证的行为。当您故意将具有未定义行为的错误放入代码中时,您不能期望它“至少打印垃圾”。 UB 表示行为不可预测。它可以立即崩溃,它可以稍后崩溃,它可以打印垃圾,它不能打印任何东西,......
-
@kaylum 我更新了我的问题,因为我想知道我的函数是否可以以未定义的方式表现得像
printf。从您的角度来看......如果调用者传递错误的参数,记录该行为是未定义的就足够了吗?谢谢! -
程序崩溃比继续运行要好得多。你需要你的程序崩溃。这是错误的。如果它崩溃了,它不会再造成任何伤害。如果它继续下去,谁知道它会造成什么损害。你正在寻找一个毫无意义和不受欢迎的目标——而且是一个无法实现的目标,因为你不能强迫未定义的行为以任何特定的方式表现。另见Fail Fast。
标签: c macos printf variadic-functions