微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – gcc的-Wconversion与使用比int短的复合赋值(=等)不兼容吗?

gcc一个有用的标志-Wconversion,当从较宽类型到较窄类型的隐式转换时,会产生警告,可能会丢失信息.不幸的是,它有以下…没有帮助的行为.

考虑这个程序:

int main(void) {
  short x = 1;
  x = x+x;
  return 0;
}

使用-Wconversion编译生成

nonsense.c: In function 'main':
nonsense.c:3:8: warning: conversion to 'short int' from 'int' may alter its value [-Wconversion]

这是公平的在大多数平台上,如果发生这种情况,那么这可能会导致x == 0x8000. (你得到这个警告的实际机制:操作数受“通用算术转换”的限制,将它们扩展为int;因此结果也是int类型;然后分配给x是一个隐式转换更宽更窄的类型.)但是,假设你期望并打算这种行为. (您正在模拟16位处理器或16位移位寄存器;或者您知道此代码中x的可能值的范围,它将永远不会溢出.)您可以通过放入一个明确的方式来告诉编译器投:

int main(void) {
  short x = 1;
  x = (short)(x+x);
  return 0;
}

然后不会抱怨.

到现在为止还挺好.但是,如果引起麻烦的作业是复合赋值 – =,* =,<< =等等 - 那么就我看到没有办法摆脱这个警告,因为没有'你可以插入显式转换的代码中的任何一点. 这意味着,例如,你不能拥有全部
> -Wconversion在你的项目的顶级编译器标志,以捕获所有真正的错误,它的意图.
>复合赋值运算符代码中的任何一个实例应用于比int短的整数类型.
>无警告的构建.

这似乎很伤心.

所以,问题是:有没有办法解决这个问题?我可以看到以下几种方法

>使用#pragma GCC诊断…可以禁止使用已知会引发它的代码中的警告,尽管没有错误. (下载:丑,编译器特定)
>将复合赋值展开为更长的单个作业并插入显式转换. (下行:超丑)
>关闭 – 转换. (下降:此警告在别处有用.)
>提出警告. (不利于使用-Werror;在任何情况下,优良做法是使您的代码编译完全没有任何警告,因为“无警告”和“某些警告”之间的区别比“某些警告“和”更多的警告“).

所有这些似乎都不能令​​人满意,我想知道是否有一些聪明的人,我失踪了.

(注:当然我会接受一个“不,就是这样”的答案,如果这其实是真相.)

所以,看起来好像答案是真的是预期的行为,没有办法阻止它比上面列出的更好. (Mark B观察到您可以编写一个与=但是使用显式转换相同的函数.ecatmur建议使用operator =函数定义一个新类型来进行显式转换.)

我接受马克B的答案标题中的问题的实际答案只是“是”:-).

解决方法

我假设在这种情况下的警告逻辑是它的功能与复合运算符实现的操作相同.复合运算符语法应该做一个非常明显的复合操作,在这种情况下,您想要明确地说明你正在做什么.当您想要明确表示意图存在时,更明确地说明代码总是胜利:您只写一次,但更长的拼写版本将使未来维护者完全清楚您的意图.

我会建议你把这个操作放在一起,然后拼写出来.您的维护者真的不会介意,我怀疑他们会认为它是丑陋的.

或者,创建一个scalar_mult(short& amp; short)函数来隐藏转换.然后你显示明确的意图,并避免在每个表达式中的演员.

最后,您可以完全避免使用较短的类型,避免发生警告.

原文地址:https://www.jb51.cc/c/113207.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐