标签: clang++

“this”参数上每个地址空间限定符的方法重载

在使用 clang++ 的 C++ 中,是否可以根据隐式 \xe2\x80\x98this\xe2\x80\x99 参数上的地址空间限定符重载方法?如果是这样,语法是什么?

\n\n

该来源建议我可以将地址空间限定符放在参数列表之后、大括号之前(类似于在 \'this\' 上使用 const 限定符)。我尝试了以下方法,但失败了;clang 认为我正在尝试设置方法的地址空间,而不是“this”:

\n\n
 // Does not work.\n struct SomeClass\n {\n   // method for \'this\' in default address space\n   void doit();\n   // method for \'this\' in address space 300.\n   void doit() __attribute__((address_space(300)); // clang rejects this syntax\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n

我发现的最接近的是 clang 让我根据其显式形式参数的地址空间(而不是 \'this\' )重载方法。例如,下面的代码将打印 \xe2\x80\x9c1\\n2\\n\xe2\x80\x9d。

\n\n
// Similar, but does not solve my problem:\n#include <cstdio>\n\nstruct SomeClass\n{\n  void doit(void *v)     { printf("1\\n"); }\n  void doit(void …
Run Code Online (Sandbox Code Playgroud)

c++ embedded address-space language-extension clang++

5
推荐指数
0
解决办法
125
查看次数

如何关闭 Clang++ 中的_所有_优化?

我正在尝试调试一些 C++11 代码,而 LLDB 没有帮助。代码大致如下:

void f(my_type dt) {
   try {
      g(h(dt));
   }
   catch ( /* reasonable exception type here */ ) {
   }
}
Run Code Online (Sandbox Code Playgroud)

当我在该行上放置断点时g(h(dt)),LLDB 坚持认为 的值dt不可用。它肯定不能被忽略,因为它用于实现h某些数据库查询的输入。

我使用 CMake,它使用以下标志进行编译:

CXX_FLAGS = -g -O0 -fPIC -std=c++11 -stdlib=libc++ -Wall
Run Code Online (Sandbox Code Playgroud)

我确认(使用make VERBOSE=true)这些标志确实用于构建项目。据我所知,应包含完整的调试信息并关闭所有优化。事实显然并非如此。我还可以添加哪些其他标志来强制 Clang 保持所有参数和变量在整个调用堆栈中可用?

不幸的是,使用小文件和函数的小测试用例不会重现此问题:大多数时候,变量会按我的预期保留。

我正在运行 Yosemite 的 Mac 上工作。

$ clang++ --version
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
Run Code Online (Sandbox Code Playgroud)

debugging optimization lldb c++11 clang++

5
推荐指数
1
解决办法
1万
查看次数

GCC 和 Clang 在与 __builtin_constant_p 相关的 static_assert 方面有所不同

我碰巧发现GCC和Clang在以下代码的编译上有所不同:

struct Foo
{
    int mem = 42;
};

int main()
{
    constexpr Foo foo;
    static_assert(__builtin_constant_p(foo));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用g++ -std=c++17和编译clang++ -std=c++17

特别是,

  • 加++ g++-9 (Homebrew GCC 9.3.0_1) 9.3.0编译,而
  • clang++Apple clang version 11.0.3 (clang-1103.0.32.62)无法编译,抱怨说
error: static_assert failed due to requirement '__builtin_constant_p(foo)'
    static_assert(__builtin_constant_p(foo));
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我没有发现任何关于__builtin_constant_p.

为了 __builtin_constant_p

海湾合作委员会

您可以使用内置函数 __builtin_constant_p 来确定某个值在编译时是否已知为常量...

叮当

Clang 支持许多与 GCC 语法相同的内置库函数,包括 __builtin_nan、__builtin_constant_p、__builtin_choose_expr、__builtin_types_compatible_p、__builtin_assume_aligned、__sync_fetch_and_add 等。

问题:虽然我知道__builtin_constant_p是一个编译器扩展,但哪个应该是正确的?

c++ g++ static-assert constexpr clang++

5
推荐指数
1
解决办法
210
查看次数

使用 Clang 10 使用显式模板实例化 ~queue 的未定义引用

以下代码未链接 Clang 10,但在 GCC 和 Clang 9 上成功:

#include <queue>

template <typename T>
class A
{
public:
    void f();

private:
    std::queue<int> q;
};

template <typename T>
void A<T>::f()
{
    q = {};
}

template class A<int>;

int main()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我从编译器得到的是:

在线示例

/opt/compiler-explorer/gcc-9.3.0/lib/gcc/x86_64-linux-gnu/9.3.0/../../../../x86_64-linux-gnu/bin/ld: /tmp/example-f70f65.o: in function `A<int>::f()':

/home/ce/<source>:16: undefined reference to `std::queue<int, std::deque<int, std::allocator<int> > >::~queue()'

clang-10: error: linker command failed with exit code 1 (use -v to see invocation)

Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)

如果我替换std::queuestd::vector, …

c++ templates c++11 clang++

5
推荐指数
1
解决办法
132
查看次数

Clang 对递归 constexpr 函数的好奇错过了优化

今天我想测试一下,Clang 如何转换两个函数的递归幂,并注意到即使使用已知指数,即使使用 constexpr 也不会优化递归。

#include <array>
constexpr unsigned int pow2_recursive(unsigned int exp) {
    if(exp == 0) return 1;
    return 2 * pow2_recursive(exp-1);
}

unsigned int pow2_5() {
    return pow2_recursive(5);
}
Run Code Online (Sandbox Code Playgroud)

pow2_5 被编译为对 pow2_recursive 的调用。

pow2_5():                             # @pow2_5()
        mov     edi, 5
        jmp     pow2_recursive(unsigned int)     # TAILCALL
Run Code Online (Sandbox Code Playgroud)

但是,当我在需要在编译时知道结果的上下文中使用结果时,它将在编译时正确计算结果。

unsigned int pow2_5_arr() {
    std::array<int, pow2_recursive(5)> a;
    return a.size();
}
Run Code Online (Sandbox Code Playgroud)

被编译为

pow2_5_arr():                        # @pow2_5_arr()
        mov     eax, 32
        ret
Run Code Online (Sandbox Code Playgroud)

以下是 Godbolt 中完整示例的链接:https ://godbolt.org/z/fcKef1

那么,我在这里错过了什么吗?有什么可以在运行时改变结果的原因吗,pow2_5 不能像 pow2_5_arr 一样优化?

c++ clang compiler-optimization constexpr clang++

5
推荐指数
0
解决办法
65
查看次数

clang++ 12 是否支持 C++20 std::construct_at?

我正在使用最近批准的 C++20 标准功能std::construct_at()并试图更熟悉它们......

我已经根据CppReference.com示例构建了一个示例:

#include <memory>

struct S {
    int a;
    int b;
};

int main() {
    std::allocator<S> alloc;
    S * s = alloc.allocate(1);
    std::construct_at(s, 42, 43); // GCC 10.2 OK Clang 12 NOT
    std::destroy_at(s);
    alloc.deallocate(s, 1);
    s = nullptr;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码使用最新的稳定 GCC 构建得很好: gcc-10.2 test.cpp -std=c++2a -lstdc++

但是我无法使用 Clang 12(主干)或 10(稳定)编译它。 clang-12 test.cpp -std=c++20 -stdlib=libc++ 有错误:

test.cpp:11:5: error: no matching function for call to 'construct_at'
    std::construct_at(s, 42, 43); // GCC 10.2 OK Clang …
Run Code Online (Sandbox Code Playgroud)

c++ clang++ c++20

5
推荐指数
1
解决办法
413
查看次数

为什么 clang 在每次使用时都取消引用参数?

我一直在对工作中的一些代码进行性能优化,并偶然发现了一些奇怪的行为,我将其归结为下面的简单 C++ 代码片段:

#include <stdint.h>

void Foo(uint8_t*& out)
{
    out[0] = 1;
    out[1] = 2;
    out[2] = 3;
    out[3] = 4;
}
Run Code Online (Sandbox Code Playgroud)

然后,我铛(在Windows上)用下面的编译:clang -S -O3 -masm=intel test.cpp。这导致以下程序集:

        mov     rax, qword ptr [rcx]
        mov     byte ptr [rax], 1
        mov     rax, qword ptr [rcx]
        mov     byte ptr [rax + 1], 2
        mov     rax, qword ptr [rcx]
        mov     byte ptr [rax + 2], 3
        mov     rax, qword ptr [rcx]
        mov     byte ptr [rax + 3], 4
        ret
Run Code Online (Sandbox Code Playgroud)

为什么 clang 生成的代码反复将out …

c++ windows clang++

5
推荐指数
1
解决办法
94
查看次数

什么是 clang 编译的模块 pcm 文件?

我正在查看 clang 模块的驱动程序测试用例:https : //github.com/llvm-mirror/clang/blob/master/test/Driver/modules.cpp

它包括生成 .pcm.o 文件的步骤。我想知道它们是干什么用的。

给定一个 c++20 模块

// a-m.cc
module;
#include <iostream>
export module a;
export void do_a() { std::cout << "A\n"; }
Run Code Online (Sandbox Code Playgroud)

您可以使用编译它

clang++ -std=c++20 -x c++-module --precompile a-m.cc -o a.pcm
Run Code Online (Sandbox Code Playgroud)

它生成预编译的模块文件a.pcm

但是也有将 .pcm 文件编译为 .o 文件的步骤。

从驱动程序测试

clang++ -std=c++20 a.pcm -S -o a.pcm.o
Run Code Online (Sandbox Code Playgroud)

如何使用 .pcm.o 文件?

如果我写一个主程序

// main.cc
import a;

int main() {
    do_a();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译

clang++ -std=c++20 -c main.cc -fmodule-file=a=a.pcm
Run Code Online (Sandbox Code Playgroud)

然后尝试与 .pcm.o 链接,我得到

clang++ main.o …
Run Code Online (Sandbox Code Playgroud)

c++ clang++ c++20 c++-modules

5
推荐指数
1
解决办法
207
查看次数

Clang:二进制表达式('const auto' 和'int')的无效操作数,具有依赖于模板上下文的 constexpr 模板变量

Clang error : invalid operands to binary expression ('const auto' and 'int')
Run Code Online (Sandbox Code Playgroud)

语境 :

  • 叮当 12.0.0

简单的问题:

  • 这个错误在这种情况下意味着什么?(例如,这里的消息是否相关?)
  • 为什么这个错误只在用 Clang 编译时发生,而不是 GCC 和 Msvc-cl ?

这是一个最小的复制案例(可在 Godbolt 上获得

template <typename ... Ts>
struct foo
{
    constexpr inline static auto value = 42;
};

template <typename ... Ts>
struct bar
{
    template <typename U>
    constexpr static inline auto foo_value = foo<Ts...>::value; // Error here
    // nb : replacing `auto` with `int` remove the error
};

static_assert(bar<int>::foo_value<int> == …
Run Code Online (Sandbox Code Playgroud)

c++ clang clang++ c++17 c++20

5
推荐指数
0
解决办法
73
查看次数

类模板的名称是否在限定的外部析构函数定义的范围内?

clang-11使用-pedantic以下代码段编译时,最新版本的 clang (since ) 会发出警告:

namespace foo {
    template <int A>
    struct Bar {
        ~Bar();
    };
} // namespace foo 

template <int A>
foo::Bar<A>::~Bar(){}
Run Code Online (Sandbox Code Playgroud)

生成的警告(和错误-Werror)是:

<source>:10:12: error: ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~' [-Werror,-Wdtor-name]
foo::Bar<A>::~Bar(){}
~~~~~~~~~~~^~
           ::Bar
Run Code Online (Sandbox Code Playgroud)

Live Example

clang是我见过的第一个发出此诊断的编译器,据我所知,上面写的内容是完全有效的 C++。似乎抑制这种情况的两种不同方法是在同一名称空间内定义 显式限定析构函数名称——例如:

<source>:10:12: error: ISO C++ requires the name after '::~' to be found in the same scope …
Run Code Online (Sandbox Code Playgroud)

c++ templates clang clang++

5
推荐指数
1
解决办法
57
查看次数