首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clang无法检测到未定义的行为。

Clang无法检测到未定义的行为。
EN

Stack Overflow用户
提问于 2017-10-08 12:59:03
回答 2查看 507关注 0票数 0

如何在下面的示例中检测到未定义的行为?

代码语言:javascript
复制
#include <iostream>
#include <stream>
int main() {
    std::cout << "Undefined: " << std::string().front() << std::endl;
    return 0;
}

clang++ -fsanitize=address,undefined -g -Wall -Wextra main.cc编译。

编译时或运行时的预期输出将是一个错误。根据front(),对空字符串调用cplusplus.com是未定义的行为。实际输出是Undefined:

问题

  1. 我可以在编译或运行时产生错误吗?如果没有,为什么编译器不能检测到这一点?
  2. 如果没有,是否有任何工具可以检测到这一点?例如,静态分析。

使用的版本:

代码语言:javascript
复制
$ clang++ --version
Apple LLVM version 9.0.0 (clang-900.0.37)
Target: x86_64-apple-darwin17.0.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

$ /usr/local/Cellar/gcc/7.2.0/bin/g++-7 --version
g++-7 (Homebrew GCC 7.2.0) 7.2.0
[Copyright Notice]

相关的相关问题:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-08 13:17:08

把Baum mit Augen的链接变成一个答案。

在与GCC一起编译时添加标志-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC。对于Clang来说,同样的情况并不适用。

这允许在std::basic_string内部进行运行时检查。

结果(为清晰起见增加的行间隔):

代码语言:javascript
复制
$ /usr/local/Cellar/gcc/7.2.0/bin/g++-7 main.cc -g  -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
$ ./a.out
Undefined:
/usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/basic_string.h:1077:
 std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::reference 
 std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::front() 
     [with _CharT = char; _Traits = std::char_traits<char>;
      _Alloc = std::allocator<char>;
      std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::reference = char&]: 
         Assertion '!empty()' failed.
[1]    24143 abort      ./a.out
票数 1
EN

Stack Overflow用户

发布于 2017-10-08 13:41:22

在标准容器中,编译时警告并不总是可能的,但是实现一个空闲函数将允许额外的检查,这些检查也可以通过编译器标志来选择关闭。

代码语言:javascript
复制
#define NDEBUG

#include <iostream>
#include <string>
#include <cassert>
#include <stdexcept>


struct assert_on_failure
{
    template<class ErrorMessage>
    void check(bool condition, ErrorMessage&& msg) const
    {
        if (!condition)
            assert(!msg);
    }
};

struct throw_on_failure
{
    template<class ErrorMessage>
    void check(bool condition, ErrorMessage&& msg) const
    {
        if (!condition)
            throw std::runtime_error(msg);
    }
};

#ifdef NDEBUG
constexpr auto default_failure_policy = throw_on_failure{};
#else
constexpr auto default_failure_policy = assert_on_failure{};
#endif



template
<
    class Container,
    class FailurePolicy = std::add_lvalue_reference_t<decltype(default_failure_policy)>
>
decltype(auto) get_front(Container&& cont, 
                         FailurePolicy&& policy = default_failure_policy)
{
    policy.check(cont.size() > 0, "container is empty");
    return cont.front();
}

int main() {
    std::cout << "Undefined: " << get_front(std::string()) << std::endl;
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46631366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档