如何在函数参数初始化中捕获未定义的行为

LKl*_*vin 6 c++ undefined-behavior unspecified-behavior

以下代码在clang ++中有效,但在g ++中崩溃了

#include<vector>
#include<iostream>

template<class Iterator>
double abs_sum(double current_sum, Iterator it, Iterator it_end){
    if (it == it_end)
        return current_sum;
    return abs_sum(current_sum+std::abs(*it),++it,it_end);
}


int main(int argc, char** argv){
    std::vector<double> values {1.0, 2.0,-5};

    std::cout << abs_sum(0.0,values.begin(),values.end()) << std::endl;;
}
Run Code Online (Sandbox Code Playgroud)

罪魁祸首证明是这条线:

return abs_sum(current_sum+std::abs(*it),++it,it_end);
Run Code Online (Sandbox Code Playgroud)

在clang中,*it在之前进行评估++it,在g ++中它是相反的,导致迭代器在被解除引用之前被增加.事实证明,评估函数参数的顺序是实现定义的.

我的问题是:我如何捕获此类错误?理想情况下,当我意外地依赖于具体实施细节时,我想要出错或至少发出警告.

即使用-Wall,clang和gcc都不会发出任何警告.

YSC*_*YSC 4

我的问题是:如何捕获此类错误?

你不知道。未定义的行为是未定义的。你抓不到它...

...但有些工具可以帮助您:

  • 你的编译器:启用所有警告(g++/clang++-Wall -Wextra -pedantic是一个好的开始);
  • cpp检查;
  • 铿锵分析器;

但他们不提供任何保证。这就是为什么C++很难。你(你,编码员)最了解,不要写 UB。祝你好运。