我想知道,根据C规范,如果给定的数据类型与预期的格式说明符不匹配,C中的预期行为是什么。例如:
printf("%lu\n", 2);
答案 0 :(得分:5)
如果可能,将根据正常的促销规则(加上两个例外)推广该类型。如果无法进行促销,则每个7.16.1.1(强调我的)C11中的行为未定义:
va_arg宏扩展为具有指定类型的表达式 以及调用中下一个参数的值。参数ap应该 已经由va_start或va_copy宏初始化(没有 为同一个ap)干预va_end宏的调用。每 调用va_arg宏修改ap以使其值为 依次返回连续的参数。参数类型应为 指定的类型名称,以指向对象的指针类型 具有指定类型的只需通过后缀* *即可获得 输入。如果没有实际的下一个参数,或者类型不是 与实际的下一个参数的类型兼容(如提升的那样) 根据默认参数促销),行为是 未定义,但以下情况除外:
一种类型是有符号整数类型,另一种类型是相应的无符号整数类型,并且该值可表示为 两种类型;
一种类型是指向void的指针,另一种是指向字符类型的指针。
答案 1 :(得分:1)
未定义的行为。 @Weather Vane
2
是一个十进制整数常量,其值为2,类型为int
。
当2
传递给...
的{{1}}部分时,它会经历默认参数促销,在这种情况下printf(const char * format, ...);
会保持int
{1}}。 int
收到printf()
作为2
。
int
期望与"%ld"
匹配。由于long
和long
是不同的类型:
如果任何参数不是相应转换规范的正确类型,则行为未定义。 C11dr§7.21.6.19
即使int
和long
的大小和范围相同,结果仍然是UB - 尽管这一点存在争议。在许多平台上,UB是可以接受的。无论如何,应避免使用此代码。
启用良好的编译器会警告不匹配。
备选方案:
int