请考虑以下代码示例:
#define STRING_LITERAL "%u, %u"
const char string_const[ ] = "%u, %u";
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);
我的编译器然后发出警告:格式字符串在此参数
之前结束现在,如果我将指令更改为:
snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3);
然后编译器没有发出警告。
我的问题是:这样的行为是否符合C99标准?
答案 0 :(得分:1)
我的问题是:这种行为是否符合C99标准?
这两个示例都调用未定义的行为,但没有违反约束或语法规则,因此不需要诊断。
答案 1 :(得分:1)
警告是由编译器生成的,该编译器能够确定您向调用传递了不正确的参数,而在第二次调用中没有。
标准定义传递不正确的参数和/或使用不正确的标志会导致未定义的行为。
标准不要求警告,它只是程序员的额外帮助。
答案 2 :(得分:0)
你有太多的论点,应该是:
#define STRING_LITERAL "%u, %u"
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2);
或:
#define STRING_LITERAL "%u, %u, %u"
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);
缺少警告的原因是它是未定义的行为,并且仅在编译器足够智能以认为出现问题时才会发出警告。如果字符串直接在snprintf命令中,那么编译器似乎足够聪明,如果字符串是间接传递的,那么它似乎不是。
答案 3 :(得分:0)
在这个例子中
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);
你直接传递一个字符串文字,而在这一个
snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3);
你传递了一个变量。
我假设您的编译器(无论是什么)将文字与变量区别对待,以用于相关警告。
答案 4 :(得分:0)
我在C99标准的附件I(常见警告)中找到了以下陈述,澄清了这种情况。
1实现可能会在许多情况下生成警告,但都不是 作为本国际标准的一部分。以下是一些较常见的情况。