【问题标题】:Why does this code give a warning? [duplicate]为什么这段代码会发出警告? [复制]
【发布时间】:2014-10-19 05:23:20
【问题描述】:
#include <stdlib.h>
#include <stdio.h>

#define SIZE_TYPE
#define MEM_SIZE_BYTES  4096
#define MEM_SIZE_WORDS  MEM_SIZE_BYTES/sizeof(int)

int main() {

    printf("bytes are %d\n", MEM_SIZE_BYTES);
    printf("words are %d\n", MEM_SIZE_WORDS);

}

编译给出警告...为什么?

testintsize.c:11:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat]

我在这里找到了 SIZE_TYPE 宏:https://gcc.gnu.org/onlinedocs/gccint/Type-Layout.html 和这个有关系吗?

这样做并没有导致警告消失:

#define SIZE_TYPE int 

【问题讨论】:

  • sizeof 运算符返回一个 size_t 类型的值,它必须是无符号的并且足够大以适应平台上所有可能的大小,并且在您的特定平台上是 unsigned long int你需要"%lu" 格式。参见例如this printf reference page
  • SIZE_TYPE 宏有什么作用?
  • 编译器可能会检查 size_t 的定义。定义它可能会导致奇怪的事情发生。
  • 与您的问题无关:请用括号括住任何比单个数字或标识符更复杂的表达式的宏。

标签: c


【解决方案1】:

您有几种不同的方法来解决此警告:

选项 #1:

#define MEM_SIZE_WORDS MEM_SIZE_BYTES/sizeof(int)      // change this
#define MEM_SIZE_WORDS MEM_SIZE_BYTES/(int)sizeof(int) // to this

选项 #2:

#define MEM_SIZE_WORDS MEM_SIZE_BYTES/sizeof(int)        // change this
#define MEM_SIZE_WORDS (int)(MEM_SIZE_BYTES/sizeof(int)) // to this

选项 #3:

printf("words are %d\n", MEM_SIZE_WORDS);  // change this
printf("words are %lu\n", MEM_SIZE_WORDS); // to this

【讨论】:

  • -1,这不是问题的答案,另外给出了错误的解决方案。
  • @JensGustedt:阅读问题,你这个挑剔的人。 OP 了解问题,并且(曾经)只是在寻找解决方案。
  • C 标准预见的真正解决方案是使用%zu 作为格式说明符。
【解决方案2】:

在这种情况下,sizeof 返回一个 long unsigned int。绕过警告的一种方法:

#include <stdlib.h>
#include <stdio.h>

#define SIZE_TYPE
#define MEM_SIZE_BYTES  4096
int intSize = sizeof(int);
#define MEM_SIZE_WORDS  MEM_SIZE_BYTES/intSize

int main() {

    printf("bytes are %d\n", MEM_SIZE_BYTES);
    printf("words are %d\n", MEM_SIZE_WORDS);

}

intSize 是 全局 变量。在某些情况下,它不会被视为最佳实践。使用 强制转换为 int 会更好(请参阅 barak 的评论和回答)。

【讨论】:

  • 这将在您每次使用 MEM_SIZE_WORDS 时产生运行时计算。
  • #define SIZE_TYPE 宏在这里做什么?
  • 嗨@barak,自从我写上我的最后一个C 代码以来已经很久了。不是说 MEM_SIZE_BYTES/intSize 会在预处理器编译之前计算一次吗?此时,MEM_SIZE_WORDS 将被简单地替换为结果值。也就是说,运行时无需重新计算。
  • intSize是一个变量,预处理器不处理C中的变量。在c++中,如果你声明为const,那么编译器 可能会将其替换为该变量的值,然后最终将整个表达式替换为一个常量值。
  • @barak,感谢您的复习。那么,预处理器完成后代码会是什么样子呢? MEM_SIZE_WORDS 会被替换为 4096/intSize 吗?
【解决方案3】:

sizeof 运算符返回类型 size_t,它是一个无符号整数类型。按C的隐式类型转换规则MEM_SIZE_BYTES/sizeof(int)也有相同的类型,size_t

要打印该类型的值,请使用%zu 作为printf 格式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多