2015-04-22 101 views
1

考虑下面的代码示例:格式说明

#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标准?

+1

C99是否要求符合规范的编译器根据无效的printf()调用(或任何其他可变参数调用)发出警告? – user3125367

回答

1

警告是由编译器生成的,它能够确定您向调用传递了不正确的参数,并且不在第二次。

该标准定义了传递不正确的参数和/或使用不正确的标志会导致未定义的行为。

标准不要求此警告,它只是程序员的附加帮助。

1

我的问题是:这样的行为是否符合C99标准?

这两个示例调用未定义的行为,但没有违反约束或语法规则,因此不需要诊断。

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命令中,那么编译器看起来非常聪明,如果字符串是间接传递的,它看起来不是。

+2

呃......这个问题如何回答?是不是像OP已经知道这一点? –

+0

你是对的,我已经添加了一个说明 –

0

在这个例子中

snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3); 

你直接字面传递字符串,而在这其中

snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3); 

你传递一个变量。

我假设你的编译器(不管是哪一个)为了所讨论的警告的目的而将文字与变量区分开来。

0

我在C99标准的附件I(常见警告)中找到了以下声明,以澄清情况。

1在很多情况下,执行过程可能会产生警告,其中没有一个是作为本国际标准的一部分指定的 。以下是一些更常见的情况。