%x printf 说明符的 long 类型参数是否正常?

is an argument of type long OK for %x printf specifier?

我在 Win32 docs 上找到了这个:

// Check the smart card context handle.
// hContext was set previously by SCardEstablishContext.

LONG    lReturn;
lReturn = SCardIsValidContext(hContext);
if ( SCARD_S_SUCCESS != lReturn )
{
   // Function failed; check return value.
   if ( ERROR_INVALID_HANDLE == lReturn )
       printf("Handle is invalid\n");
   else
   {
       // Some unexpected error occurred; report and bail out.
       printf("Failed SCardIsValidContext - %x\n", lReturn);
       exit(1);  // Or other appropriate error action.
   }
}
else
{
   // Handle is valid; proceed as needed.
   // ...
}

printf("Failed SCardIsValidContext - %x\n", lReturn); 行正在将类型为 LONG 的参数(long 的类型定义)传递给 printf,其中 printf 需要 unsigned int根据 cppreference.com。这是定义明确的行为吗?如果是这样,它是否与显式 static_castunsigned int 相同?

printf("%x", (LONG)101); 在 Windows 中有效且定义明确 其中 LONGdefined 为 '一个 32 位有符号整数”,与 int 相同,大小与 unsigned int 相同。

使用 C++ 类型的可移植等价物是 printf("%lx", (unsigned long)101l);

is an argument of type long OK for %x printf specifier?

不,在 C++ 中是不行的。 %x 适用于 unsigned int,不适用于 long。

Is this well defined behavior?

不,这是未定义的行为。引自 C 标准草案(定义格式说明符的地方):

x,X The unsigned int argument is converted to ... unsigned hexadecimal notation ...

If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.


如果系统记录如此,在 windows 中可能是“OK”,但依赖这种保证将无法移植到其他系统。我怀疑这个例子并不是为了证明这种滥用格式说明符的有效性,而是偶然的。