C++ C++;使截断在运行时打印错误的自动方法
我刚刚加入了一个拥有数千行代码的团队,如:C++ C++;使截断在运行时打印错误的自动方法,c++,truncation,C++,Truncation,我刚刚加入了一个拥有数千行代码的团队,如: int x = 0; x=something(); short y=x; doSomethingImportantWith(y); 编译器给出了很好的警告:将XX位类型值转换为“short”会导致截断。有人告诉我,没有真正发生截断的情况,但我对此表示严重怀疑 是否有一种很好的方法可以在每个案例中插入支票,其效果如下: if (x>short.max) printNastyError(__FILE,__LINE); 每次作业前?手动执
int x = 0;
x=something();
short y=x;
doSomethingImportantWith(y);
编译器给出了很好的警告:将XX位类型值转换为“short”会导致截断。有人告诉我,没有真正发生截断的情况,但我对此表示严重怀疑
是否有一种很好的方法可以在每个案例中插入支票,其效果如下:
if (x>short.max) printNastyError(__FILE,__LINE);
每次作业前?手动执行此操作将花费比我希望使用的更多的时间和精力,并且编写一个脚本来读取警告并将这些内容添加到正确的文件以及所需的include似乎有些过分——特别是因为我希望有人已经这样做了(或类似的事情)
我不关心性能(实际上)或其他任何问题,只关心这些问题何时发生,这样我就可以只解决真正重要的问题,或者让管理层相信这是一个问题 您可能可以为gcc编写一个插件来检测这些截断,并发出对函数的调用,以检查转换是否安全。您可以在或中编写这些插件。如果您喜欢使用clang,它还支持编写
我认为最简单的方法是让插件将不安全强制转换从
int
转换为short
,调用函数\u convert\u int\u to\u float\u fail\u if\u data\u loss(value)
。我将把它作为一个练习留给读者如何编写这样一个插件。你可以尝试用以下难看的技巧编译和运行它:
#include <limits>
#include <cstdlib>
template<class T>
struct IntWrapper
{
T value;
template<class U>
IntWrapper(U u) {
if(u > std::numeric_limits<T>::max())
std::abort();
if(U(-1) < 0 && u < std::numeric_limits<T>::min()) // for signed U only
std::abort();
value = u;
}
operator T&() { return value; }
operator T const&() const { return value; }
};
#define short IntWrapper<short>
int main() {
int i = 1, j = 0x10000;
short ii = i;
short jj = j; // this aborts
}
#包括
#包括
模板
结构IntWrapper
{
T值;
模板
IntWrapper(U){
如果(u>std::numeric_limits::max())
std::abort();
如果(U(-1)<0&&U
显然,它可能会破坏作为模板参数传递的
short
,在其他情况下可能会破坏,因此在破坏构建的地方取消定义它。您可能需要添加运算符重载,以便通常的算法与包装器一起工作。为什么不将警告作为错误进行编译?@DanF然后没有人可以处理自己的问题--我希望调试构建可以做到这一点,而不必强迫我现在修复它们--这样我就可以找到大问题。任何对值的检查都必须进行在运行时发生。@DanF是的,我希望编译器(或其他工具)为我添加运行时检查。我不认为这是一个技术上的难题,而且可能非常有用,但对我来说,把所有的运行时检查都放在自己身上是不现实的(我们有数以百万行的代码,到处都是这样)。@Dale为什么不对它运行一个CUnit测试,然后向他们展示代码到底有多糟糕?