警告:整数常量对于" long"来说太大了类型

时间:2014-04-04 02:45:46

标签: c gcc gcc-warning

我有以下代码。

  uint32_t reg_val = 0;
  uint64_t val = 0;
  reg_val = 0;
  reg_val = ((val & 0xffffff000000) >> 24);
  dev_write(rw,reg_val);

编译器发出一条警告

warning: integer constant is too large for "long" type

我只将24位分配给reg_val,它被定义为大小为32位的无符号整数。

为什么编译器会生成此警告?

2 个答案:

答案 0 :(得分:8)

常量0xffffff000000对于32位长而言太大,在您的情况下范围为0x7fffffff

将其写为0xFFFFFF000000ULLunsigned long long) 或者通过写作来避免这个问题

reg_val = (val >> 24) & 0xFFFFFF;

答案 1 :(得分:1)

稍微扩展greggo的答案。

如何定义整数文字取决于我们所使用的语言版本。

在C99中,整数文字自动具有可以包含其值的类型(除非不存在此类型)。因此,假设32位long,则此常量已经具有类型unsigned long long,因此不应发生警告。

我没有C89文本的副本,但C89没有long long。如果规则相似,那么将会以实现定义的方式将常量转换为32位unsigned long(可能会截断更高的位)。

由于OP收到了警告,但也能够使用ull后缀来解决它,这表明他正在使用编译器扩展。从理论上讲,如果编译器以类似C89的模式提供long long,那么它应该也更新其整数文字规则,这样一个不适合long的文字就有了键入long long(可能是未签名的)。

但是,我听说编译器存在不执行此操作;除非你把后缀放在自己身上,否则它们会截断文字,而不是给它一个适合的类型。

tl; dr - 后缀不应该是必需的;但是使用它永远不会伤害它,它可以解决严重实现的编译器扩展。