【发布时间】:2016-06-11 01:37:07
【问题描述】:
我正在修复我继承的遗留项目中的编译器警告。新编译器是 gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)。
他们有很多类似下面的代码:
#include <cstdio>
#include <cstring>
struct foobar
{
char field1[10];
char field2[5];
};
int main()
{
struct foobar foo;
memset(&foo, ' ', sizeof(foo));
strncpy(foo.field1, "1234567890", sizeof(foo.field1));
// Produces warning
printf("[%.*s]", sizeof(foo.field1), foo.field1);
return 0;
}
这会产生警告消息:
1_test.c: In function ‘int main()’:
1_test.c:16:49: warning: field precision specifier ‘.*’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("[%.*s]", sizeof(foo.field1), foo.field1);
这对我来说似乎是错误的,因为 '.*' 应该期望 size_t 但显然它不会......
除了必须执行以下操作之外,还有什么方法可以全局解决此问题:
// Fixes
printf("[%.10s]", foo.field1);
// Fixes
printf("[%.*s]", static_cast<int>(sizeof(foo.field1)), foo.field1);
【问题讨论】:
-
我正要说“使用
static_cast”,但你是对的,这是一个丑陋的解决方案。 -
@Slava 它不是 C++,但它是它的一部分
-
@KABoissonneault 上面哪部分代码使它成为 C++ 而不是 C?
-
@Slava 'C' 什么时候得到
和 ? MessageBox不是 C++,但这并不意味着 Windows 用户在使用 Microsoft 的库时不能问 C++ 问题。最后,printf 本身在 C++ 标准中被多次使用,这是否使 C++ 标准不是 C++? -
printf()中的功能早于size_t作为类型的存在;这就是为什么它使用int而不是size_t。 (标准 I/O 库是 70 年代后期的一个特性——例如,在第 7 版 UNIX 中。在设计标准 I/O 库时,size_t类型不是 C 或 C 支持库的一部分,所以该类型无法使用。)