【发布时间】:2015-11-12 15:30:56
【问题描述】:
当我尝试编译此代码时收到一条警告消息
sscanf(value, "%h" PRIu16 "B", &packet_size)
使用 Clang 600.0.57 (OS X)。
warning: format specifies type 'unsigned char *' but the argument has type 'uint16_t *'
(aka 'unsigned short *') [-Wformat]
if (sscanf(value, "%h" PRIu16 "B", &packet_size) == 1) {
~~~~ ^~~~~~~~~~~~
但是如果我删除修饰符“h”,那么我会在 GCC 4.8.3 (Scientific Linux 7) 中收到以下错误。
warning: format ‘%u’ expects argument of type ‘unsigned int*’, but argument 3 has type ‘uint16_t* {aka short unsigned int*}’ [-Wformat=]
if (sscanf(value, "%" PRIu16 "B", &packet_size) == 1) {
^
什么是 sscanf 中 uint16_t* 的正确且可移植的修饰符?
=== 在下面添加了更多不言自明的示例 ===
test.c
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS 1
#endif
#include <inttypes.h>
#include <stdio.h>
int main() {
char* str = "16 bits";
uint16_t u16;
sscanf(str, "%h" PRIu16 " bits", &u16); // Clang warning
sscanf(str, "%" PRIu16 " bits", &u16); // GCC warning
sscanf(str, "%" SCNu16 " bits", &u16); // OK for both compilers
printf("%" PRIu16 " bits\n", u16);
return 0;
}
Clang 警告
$ clang test.c -Wall -Wextra
test.c:10:36: warning: format specifies type 'unsigned char *' but the argument
has type 'uint16_t *' (aka 'unsigned short *') [-Wformat]
sscanf(str, "%h" PRIu16 " bits", &u16); // Clang warning
~~~~ ^~~~
1 warning generated.
GCC 警告
$ gcc -Wall -Wextra test.c
test.c: In function ‘main’:
test.c:11:3: warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 3 has type ‘uint16_t *’ [-Wformat=]
sscanf(str, "%" PRIu16 " bits", &u16); // GCC warning
^
【问题讨论】:
-
SCNsN代表scanf()。使用:sscanf(value, "%"SCNu16"B", &packet_size),记得#include <inttypes.h> -
cplusplus.com/reference/cstdio/scanf 说你想要
sscanf(sourcestring,"%hu",&uint16Value)。我不知道PRIu16正在扩展到什么,但也许它正在扩展到告诉sscanf寻找unsigned char*的东西? (或者编译器在发出包含宏的警告时表现不佳?) -
@RussSchultz cplusplus.com 没有这样的说法。你不能假设
typedef unsigned short int uint16_t。将<stdint.h>与printf和scanf函数一起使用的可移植方式是使用<inttypes.h>中提供的常量。