简体   繁体   English

C格式说明符与数据类型不匹配

[英]C format specifier mismatch with data type

I would like to know, as per C specification, what is the expected behavior in C if the given data type does not match the format specifier expected. 我想知道,按照C规范,如果给定的数据类型与预期的格式说明符不匹配,则C的预期行为是什么。 For eg: 例如:

    printf("%lu\n", 2);

The type will be promoted per the normal promotion rules (plus two exceptions) if possible. 如果可能,将按照常规升级规则(加上两个例外)升级该类型。 If the promotion is not possible, the behavior is undefined in C11 per 7.16.1.1 (emphasis mine): 如果无法升级,则在C11中根据7.16.1.1 (强调我的行为)未定义行为:

The va_arg macro expands to an expression that has the specified type and the value of the next argument in the call. va_arg宏扩展为具有指定类型和调用中下一个参数值的表达式。 The parameter ap shall have been initialized by the va_start or va_copy macro (without an intervening invocation of the va_end macro for the same ap). 参数ap应该已经由va_start或va_copy宏初始化(对于同一ap无需介入va_end宏)。 Each invocation of the va_arg macro modifies ap so that the values of successive arguments are returned in turn. 每次调用va_arg宏都会修改ap,以便依次返回连续参数的值。 The parameter type shall be a type name specified such that the type of a pointer to an object that has the specified type can be obtained simply by postfixing a * to type. 参数类型必须是指定的类型名称,以便可以通过后缀*来简单地获得具有指定类型的对象的指针的类型。 If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases : 如果没有实际的下一个自变量, 或者类型与实际的下一个自变量的类型不兼容(根据默认自变量提升),则该行为是不确定的,以下情况除外

  • one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types; 一种类型是有符号整数类型,另一种类型是相应的无符号整数类型,并且值在两种类型中均可表示;

  • one type is pointer to void and the other is a pointer to a character type. 一种类型是指向void的指针,另一种类型是指向字符类型的指针。

It is undefined behavior . 这是未定义的行为 @Weather Vane @风向标

2 is an decimal integer constant with a value of 2 and type of int . 2是一个十进制整数常量 ,值为2,类型为int

When 2 is passed to ... part of printf(const char * format, ...); 2传递给... printf(const char * format, ...); it undergoes default argument promotions , which in this case is int stays an int . 它接受默认的参数提升 ,在这种情况下, int保持为int printf() receives the 2 as an int . printf()接收2作为int

"%ld" expects to match a long . "%ld"期望匹配long As long and int are different types: longint是不同的类型:

If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined. 如果任何参数都不是相应转换规范的正确类型,则行为未定义。 C11dr §7.21.6.1 9 C11dr§7.21.6.19

Even if the size and range of long and int are the same, the result is still UB - although there is debate on this point. 即使longint的大小和范围相同,结果仍然是UB-尽管对此有争议。 On many platforms, the UB is acceptable. 在许多平台上,UB是可以接受的。 In any case, this code should be avoided. 无论如何,都应避免使用此代码。

A well enabled compiler will warn of the mis-match. 启用良好的编译器将警告不匹配。

Alternatives: 备择方案:

printf("%d\n", 2);
printf("%lu\n", 2ul);
printf("%lu\n", 2UL);
printf("%lu\n", 1ul * 2);
printf("%lu\n", (undersigned long) 2);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM