以下代码可在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;;
}

罪魁祸首是这条线:
return abs_sum(current_sum+std::abs(*it),++it,it_end);

在clang中,*it++it之前进行求值,在g++中是相反的,导致迭代器在被取消引用之前先增大。事实证明,函数参数的求值顺序是实现定义的。

我的问题是:如何捕获此类错误?理想情况下,当我不小心依赖于实现的特定细节时,我希望有一个错误或至少一个警告。

clang和gcc都不会发出任何警告,即使使用-Wall也是如此。

最佳答案



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

...但是一些工具可以帮助您:

  • 您的编译器:启用所有警告(g++/clang++ -Wall -Wextra -pedantic是一个好的开始);
  • cppcheck;
  • clang-analizer;

  • 他们没有提供任何保证。这就是为什么C++很难做到的原因。您(编码员)最了解并且不编写UB。祝你好运。

    关于c++ - 如何在函数参数初始化中捕获未定义的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53778063/

    10-11 19:10