C++ 的警告或错误原语的隐式转换
我对一些 C++ 代码进行了大量重构,并发现了许多我不知道的隐式转换引起的错误。
示例
struct A *a();
bool b() {
return a();
}
void c() {
int64_t const d(b());
}
问题
- 在
b
中,a
的返回类型被自动转换为bool
。 - 在
c
中,从b
返回的值会默默地提升为int64_t
。
问题
如何接收有关基本类型之间隐式转换的警告或错误?
注意
- 使用
-Wconversion
似乎只能进行与上面示例无关的几个任意转换。 BOOST_STRONG_TYPEDEF
不是一个选项(我的类型需要是 POD,因为它们用于磁盘结构)。- C 也很有趣,但是这个问题与 C++ 代码库有关。
I've done some heavy refactoring of some C++ code, and discovered numerous bugs arising from implicit conversions that I'm not aware of.
Example
struct A *a();
bool b() {
return a();
}
void c() {
int64_t const d(b());
}
Issues
- In
b
, the return type ofa
is silently cast tobool
. - In
c
, the value returned fromb
is silently promoted toint64_t
.
Question
How can I receive warnings or errors for the implicit conversion between primitive types?
Note
- The use of
-Wconversion
seems to only pick up several arbitrary conversions unrelated to the example above. BOOST_STRONG_TYPEDEF
is not an option (my types need to be PODs, as they're used in disk structures).- C is also of interest, however this problem pertains to a C++ code base.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在C++编程语言,第3版,附录C.6,即“隐式类型转换”中, Bjarne Stroustrup 将转化分为促销和转化:第一个转化“保留价值”(即案例 2),第二个转化则不然(案例 1)。
关于转换,他说“基本类型可以通过多种令人眼花缭乱的方式相互转换。在我看来,太多的转换是被允许的。”和“编译器可以警告许多有问题的转换。幸运的是,许多编译器确实这样做了。”
另一方面,促销是安全的,编译器似乎不应该向它们发出警告。
编译器警告通常不是强制性的。通常在 C++ 草案和最终 ANSI 文档 中,报告“实现者应该发出警告”,其中建议:如果需要,您可以自行检查以获取更多信息。
编辑:添加了 C++11 注释:
在 C++ 编程语言,第 4 版 中,附录第三版已再次报告并扩展为第 10.5 节“隐式类型转换”。
由于前面的考虑因素相同,C++11 更精确地定义了“缩小转换”并添加了 {} 初始化符号 (6.3.5),使用该符号截断会导致编译错误。
In the C++ programming language, 3rd edition, appendix C.6, namely "Implicit Type Conversion", Bjarne Stroustrup classifies conversions as promotions and conversions: the first ones "preserve values" (that's your case 2), the second ones doesn't (case 1).
About conversions, he says that "The fundamental types can be converted into each other in a bewildering number of ways. In my opinion, too many conversions are allowed." and "A compiler can warn about many questionable conversions. Fortunately, many compilers actually do."
promotions on the other side are safe, and it seems like a compiler is not supposed to give a warning for them.
Compiler warnings are usually not mandatory. Usually in the C++ drafts and final ANSI documents it is reported that "implementers should issue a warning" where suggested: you can check it yourself for further information if needed.
EDITED: added C++11 note:
In The C++ programming language, 4th edition, the appendix of the 3rd edition has been reported and extended as section 10.5, "Implicit Type Conversion" again.
Being the previous considerations the same, C++11 more precisely define "narrowing conversions" and adds up the {}-initializer notation (6.3.5), with which truncations lead to a compilation error.
如果您正在使用 gcc,您是否尝试过 -Wall -Wextra 基本上检查此页面
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
如果不是 GCC,请发布编译器详细信息。
If you are using gcc have you tried -Wall -Wextra basically check this page
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
If it is not GCC please post the compiler details.
Microsoft Visual C++ 会就从
A*
到bool
的缩小转换发出警告。请参阅编译器警告 C4800
另一方面,升级并不是“危险”转换,因为不可能丢失数据。
编辑:演示
Microsoft Visual C++ would give a warning about the narrowing conversion from
A*
tobool
.See Compiler Warning C4800
Promotion on the other hand is not a "dangerous" conversion, because it's impossible to lose data.
EDIT: Demonstration
据我了解,您无法控制之间的隐式转换
原始类型:它是由标准和任何兼容的强制规定的
编译器只会默默地执行它。
您确定像 BOOST_STRONG_TYPEDEF 这样的方法在您的系统中不起作用吗?
问题?没有虚拟成员函数且只有一个原语的类
数据成员基本上只不过是 POD 数据类型。你可以
只需遵循相同的方法,并且只允许转换为基础
原始类型;例子:
As far as I understand, you cannot control implicit conversion between
primitive types: it's mandated by the standard and any compliant
compiler will just perform it silently.
Are you sure an approach like BOOST_STRONG_TYPEDEF won't work in your
problem? A class with no virtual member functions and just one primitive
data member is basically nothing more than a POD data type. You can
just follow the same approach and only allow conversion to the base
primitive type; example:
您可以使用一种可用的静态分析工具、clint 或 C++ 等价物等程序,或者一种商用工具。其中许多工具可以找出有问题的隐式转换。
You can use one of the available static analysis tools, programs like clint or C++ equivalents, or one of the commercially available tools. Many of these tools can pick out problematic implicit conversions.
编写一个自定义 clang 插件来诊断您的问题。我们在 LibreOffice 代码中做了很多这样的事情。如果您想要灵感,请浏览我们的源代码 http://cgit.freedesktop.org/ libreoffice/core/tree/compilerplugins/clang
Write a custom clang plugin to diagnose your problems. We do a lot of this in the LibreOffice code. Come browse our source if you want inspiration at http://cgit.freedesktop.org/libreoffice/core/tree/compilerplugins/clang