小编Hol*_*Cat的帖子

使用MinGW-w64的Clang 8:如何使用地址和UB消毒器?

Clang 8发行说明中有以下内容:

  • 允许在MinGW上使用Address Sanitizer和Undefined Behavior Sanitizer。

但是,我无法弄清楚如何正确使用它们。

我将Clang 8.0.0与MSYS2 MinGW GCC结合使用。确切的细节在问题的底部。

我正在尝试编译以下最少的代码:

1.cpp

#include <iostream>

int main()
{
    // Testing ubsan
    int x = 0x7fffffff;
    x++;
    std::cout << x << std::endl;

    // Testing asan
    int *y = new int;
    delete y;
    std::cout << *y << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

以下是结果-fsanitize=address

# /z/Lander/LLVM/bin/clang++ -target x86_64-w64-windows-gnu -fsanitize=address 1.cpp
Z:\Lander\msys2\mingw64\bin\ld.exe: cannot find Z:\Lander\LLVM\lib\clang\8.0.0\lib\windows\libclang_rt.asan_dynamic-x86_64.dll.a: No such file or directory
Z:\Lander\msys2\mingw64\bin\ld.exe: cannot find Z:\Lander\LLVM\lib\clang\8.0.0\lib\windows\libclang_rt.asan_dynamic_runtime_thunk-x86_64.a: No such file or directory
Z:\Lander\msys2\mingw64\bin\ld.exe: cannot find Z:\Lander\LLVM\lib\clang\8.0.0\lib\windows\libclang_rt.asan_dynamic_runtime_thunk-x86_64.a: No …
Run Code Online (Sandbox Code Playgroud)

c++ clang mingw-w64 address-sanitizer ubsan

9
推荐指数
2
解决办法
495
查看次数

C++20 中模板对非类型文字参数的部分特化:clang 和 gcc 不同意

在 c++20 中玩弄文字、非类型模板参数,我发现 g++ 和 clang++ 不同意以下代码。

#include <algorithm>

template<size_t N>
struct StringLiteral {
    constexpr StringLiteral(const char (&str)[N]) {
        std::copy_n(str, N, value);
    }
    char value[N];
};

template <typename T, StringLiteral Name>
struct named{};

template <typename T>
struct is_named: std::false_type{};

template <typename T, size_t N, StringLiteral<N> Name>
struct is_named<named<T, Name>>: std::true_type{};

// This will fail with g++
static_assert(is_named<named<int, "ciao">>::value == true);
Run Code Online (Sandbox Code Playgroud)

在 Godbolt 上实时查看:https ://godbolt.org/z/f3afjd

首先也是最重要的,我什至不确定我是否以正确的方式做这件事:它是与泛型StringLiteral<N>类型匹配的方式,还是不是?如果不是,正确的方法是什么?

而且,为什么编译器不同意呢?谁有错误?


编辑:发现删除size_t N部分特化中的参数使两个编译器都同意,结果是预期的。像这样:

template <typename T, StringLiteral …
Run Code Online (Sandbox Code Playgroud)

c++ g++ language-lawyer clang++ c++20

9
推荐指数
1
解决办法
764
查看次数

Clang声称`成员引用基类型'X'不是结构或联合`,但X是带有推导参数的结构模板

考虑以下代码:

template <typename T> struct X
{
    X(T) {}
    void foo() {}
};

template <typename T> struct Y
{
    int object = 0;

    void bar()
    {
        X(object).foo();
    }
};
Run Code Online (Sandbox Code Playgroud)

Live on gcc.godbold.org

GCC 8.2编译它,而Clang 7吐出以下错误:

<source>:13:18: error: member reference base type 'X' is not a structure or union
        X(object).foo();
        ~~~~~~~~~^~~~
Run Code Online (Sandbox Code Playgroud)

对我来说这看起来像个错误.

条件非常具体:如果任一结构不是模板,或者object不是成员变量,或者不涉及CTAD(类模板参数推导),那么Clang也会编译代码.

这里发生了什么?它确实是一个Clang bug吗?

更重要的是,如何在没有摆脱CTAD的情况下以最小的变化编译代码?


唯一使用的标志是-std=c++17.

clang++ --version

clang version 7.0.0 (tags/RELEASE_700/final 342594)
Target: x86_64-unknown-linux-gnu
Thread model: posix
Run Code Online (Sandbox Code Playgroud)

c++ clang compiler-bug template-argument-deduction c++17

8
推荐指数
1
解决办法
457
查看次数

C ++ 17 / C ++ 2a中的编译时哈希类型

考虑以下代码:

#include <iostream>
#include <type_traits>

template <class T>
constexpr std::size_t type_hash(T) noexcept 
{
    // Compute a hash for the type
    // DO SOMETHING SMART HERE
}

int main(int argc, char* argv[])
{
    auto x = []{};
    auto y = []{};
    auto z = x;
    std::cout << std::is_same_v<decltype(x), decltype(y)> << std::endl; // 0
    std::cout << std::is_same_v<decltype(x), decltype(z)> << std::endl; // 1
    constexpr std::size_t xhash = type_hash(x);
    constexpr std::size_t yhash = type_hash(y);
    constexpr std::size_t zhash = type_hash(z);
    std::cout << (xhash == yhash) …
Run Code Online (Sandbox Code Playgroud)

c++ hash template-meta-programming c++17 c++20

8
推荐指数
2
解决办法
417
查看次数

如何防止用户指定功能模板参数,迫使其推导?

假设我有一个模板函数:

template <typename A, typename B>
A fancy_cast(B)
{
    return {};
}
Run Code Online (Sandbox Code Playgroud)

预期的用法类似于fancy_cast<int>(1.f)

但是,没有什么可以阻止用户手动指定第二个模板参数:fancy_cast<int, int>(1.f),这会引起问题。

如何防止typename B被指定并强制推断?

我想出了这个:

// Using this wrapper prevents the code from being
// ill-formed NDR due to [temp.res]/8.3
template <auto V> inline constexpr auto constant_value = V;

template <
    typename A,
    typename ...Dummy,
    typename B,
    typename = std::enable_if_t<constant_value<sizeof...(Dummy)> == 0>
>
A fancy_cast(B)
{
    return {};
}
Run Code Online (Sandbox Code Playgroud)

它似乎可以工作,但是非常麻烦。有没有更好的办法?

c++

8
推荐指数
1
解决办法
114
查看次数

Clangd - 当没有 `compile_commands.json` 时如何设置要使用的默认标志?

这可能是不可能的,但我还是想问。我使用 Clangd 作为 VSCode 的自动完成引擎。它工作得很好,但有一个问题。

Clang 的官方 Windows 二进制文件依赖于 MSVC 标准库头。如果未安装 MSVC,Clang 和 Clangd 会抱怨缺少标头。

有一个标志使 Clang 使用 MinGW 的 libstdc++ ( --target=x86_64-w64-windows-gnu),我必须将其包含在compile_commands.json.

这个解决方案有效,但即使没有compile_commands.json.

有没有办法让 Clangd 假设--target=x86_64-w64-windows-gnu没有compile_commands.json

c++ clang clangd

8
推荐指数
1
解决办法
9203
查看次数

在嵌套需求中,为什么使用 `requires bool_constant&lt;X&gt;::value;` 而不是 `requires X;`?

我正在阅读这个 cppreference 页面,并在其中找到了以下代码:

template <class G>
concept uniform_random_bit_generator =
  // ...
  requires {
    // ...
    requires std::bool_constant<(G::min() < G::max())>::value;
  };
Run Code Online (Sandbox Code Playgroud)

我很好奇为什么std::bool_constant在这里使用。是不是可以requires G::min() < G::max();直接使用,像这样:

template <class G>
concept uniform_random_bit_generator =
  // ...
  requires {
    // ...
    requires G::min() < G::max();
  };
Run Code Online (Sandbox Code Playgroud)

c++ c++20

8
推荐指数
1
解决办法
143
查看次数

如何设计一个需要在其析构函数中加入一个线程的基类,该线程对同一个类实例进行操作?

我刚刚得到了一个有趣的比赛条件。考虑以下类:

#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>

class A
{
    std::thread th;
    std::atomic_bool stop = false;

  public:
    A() = default;
    A(const A &) = delete;
    A &operator=(const A &) = delete;

    ~A()
    {
        stop.store(true);
        th.join();
    }

    virtual void Step() = 0;

    void Start()
    {
        th = std::thread([this]
        {
            while (true)
            {
                if (stop.load())
                    return;

                // Just to help reproduce the race condition.
                std::this_thread::sleep_for(std::chrono::milliseconds(50));

                Step();
            }
        });
    }
};

struct B : A
{
    void Step() override
    {
        std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism multithreading race-condition stdthread

8
推荐指数
0
解决办法
109
查看次数

当 SFINAE 条件的满足取决于所声明的函数时,该条件是否保证为假?

考虑这段代码:

#include <type_traits>

struct A {};

struct B
{
    template <typename T, std::enable_if_t<!std::is_constructible_v<B, T &&>, std::nullptr_t> = nullptr>
    B(T &&) {}
};

int main()
{
    B b(A{});
}
Run Code Online (Sandbox Code Playgroud)

Clang、GCC 和 MSVC 都接受它

这段代码是否有效,或者编译器应该拒绝它?

有趣的是,如果我使用requires而不是enable_if_t,GCC 和 Clang 开始拒绝它,而 MSVC 仍然接受。该错误归结为satisfaction of constraint depends on itself

但同样的事情不应该导致第一个代码中的错误吗?或者这是未定义的?

#include <type_traits>

struct A {};

struct B
{
    template <typename T>
    requires(!std::is_constructible_v<B, T &&>)
    B(T &&) {}
};

int main()
{
    B b(A{});
}
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

8
推荐指数
1
解决办法
186
查看次数

为什么需要`std :: function :: operator =(F &&)`来创建一个临时的`std :: function`?

显然std::function::operator=(F &&f)需要的行为完全一样std::function(std::forward<F>(f)).swap(*this);.

除非我遗漏了某些东西,否则这个定义会导致一些多余的移动:

#include <functional>
#include <iostream>

struct A
{
    A() {std::cout << "A()\n";}
    A(const A &) {std::cout << "A(const A &)\n";}
    A(A &&) {std::cout << "A(A &&)\n";}
    A &operator=(const A &) {std::cout << "A &operator=(const A &)\n"; return *this;}
    A &operator=(A &&) {std::cout << "A &operator=(A &&)\n"; return *this;}
    ~A() {std::cout << "~A()\n";}
    void operator()() const {}
};

int main()
{
    std::function<void()> f;
    f = A{};
}
Run Code Online (Sandbox Code Playgroud)

打印:

A()        // Created by `A{}` …
Run Code Online (Sandbox Code Playgroud)

c++ std-function

7
推荐指数
1
解决办法
159
查看次数