小编Ben*_*Ben的帖子

为什么 GCC 不能为两个 int32s 的结构生成最佳 operator==?

一位同事向我展示了我认为没有必要的代码,但果然,确实如此。我希望大多数编译器会将所有这三种相等性测试的尝试视为等效的:

#include <cstdint>
#include <cstring>

struct Point {
    std::int32_t x, y;
};

[[nodiscard]]
bool naiveEqual(const Point &a, const Point &b) {
    return a.x == b.x && a.y == b.y;
}

[[nodiscard]]
bool optimizedEqual(const Point &a, const Point &b) {
    // Why can't the compiler produce the same assembly in naiveEqual as it does here?
    std::uint64_t ai, bi;
    static_assert(sizeof(Point) == sizeof(ai));
    std::memcpy(&ai, &a, sizeof(Point));
    std::memcpy(&bi, &b, sizeof(Point));
    return ai == bi;
}

[[nodiscard]]
bool optimizedEqual2(const Point &a, const Point &b) { …
Run Code Online (Sandbox Code Playgroud)

c++ gcc x86-64 micro-optimization compiler-optimization

86
推荐指数
3
解决办法
4658
查看次数

不同的 Lambda 可以衰减到同一个函数指针吗?

两个不同的 lambda(没有捕获,并且具有相同的参数和主体)可以衰减到相同的函数指针吗?

我有这个代码:

#include <cassert>
#include <type_traits>

int main() {
    auto f0 = [](auto x) { return x; };
    auto f1 = [](auto x) { return x; };
    
    static_assert(not std::is_same_v<decltype(f0), decltype(f1)>);

    // MSVC Release-mode combines the functions so the pointers are the same (even though the types should be different.
    assert(static_cast<int(*)(int)>(f0) != static_cast<int(*)(int)>(f1));
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/P3vc45654

我相信static_assert一定会通过。这样就assert保证能通过吗?(我看到 MSVC 在发布模式下assert在我的计算机上失败。)

c++ lambda language-lawyer c++11

27
推荐指数
1
解决办法
1656
查看次数

可以将一个static_cast <float>从double赋值给double进行优化吗?

我偶然发现了一个我认为不必要的功能,并且通常让我害怕:

float coerceToFloat(double x) {
    volatile float y = static_cast<float>(x);
    return y;
}
Run Code Online (Sandbox Code Playgroud)

然后使用如下:

// double x
double y = coerceToFloat(x);
Run Code Online (Sandbox Code Playgroud)

这与这样做有什么不同吗?:

double y = static_cast<float>(x);
Run Code Online (Sandbox Code Playgroud)

目的似乎是将双倍降低到单精度.它闻起来像极端偏执狂写的东西.

c++ floating-point casting

22
推荐指数
4
解决办法
1550
查看次数

CMAKE_CXX_STANDARD 与 target_compile_features?

我很想将我们的项目升级到 C++20。我的CMakeLists.txt文件通常说

set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD_REQUIRED ON)
Run Code Online (Sandbox Code Playgroud)

但我感觉这不是正确的做法。什么是正确的方法?是这个吗?:

target_compile_features(Foo PUBLIC cxx_std_20)
Run Code Online (Sandbox Code Playgroud)

我的目标的名称在哪里Foo(每个目标都相同?)如果我这样做,我是否会删除所有set (CMAKE_CXX_STANDARD*)地方的所有行?

同样,如果我有

target_compile_features(Foo PUBLIC cxx_std_20)
target_compile_features(Bar PUBLIC cxx_std_17)
target_link_libraries(Bar PUBLIC Foo)
Run Code Online (Sandbox Code Playgroud)

这是否意味着当它去构建时,Bar它会注意到它需要包含头文件,并且Foo需要Foocxx_std_20包含cxx_std_20cxx_std_17因此Bar将使用 C++20 构建?

c++ cmake c++20

14
推荐指数
1
解决办法
7672
查看次数

显式调用析构函数然后使用放置新来重建它是否定义了行为?

这非常类似于这与Placement-new 和显式析构函数调用的正确用法,但范围更严格:

如果我有一个类型 ,Sstd::is_nothrow_default_constructible_v<S>std::is_nothrow_destructible_v<S>not std::has_virtual_destructor_v<S>not std::is_polymorphic_v<S>它是调用此函数的定义行为吗?:

template <typename T>
void reconstruct(T& x) noexcept {
    // C++20: requires instead of static_assert:
    static_assert(std::is_nothrow_default_constructible_v<T>);
    static_assert(std::is_nothrow_destructible_v<T>);
    static_assert(!std::has_virtual_destructor_v<T>);
    static_assert(!std::is_polymorphic_v<T>);
    x.~T();
    ::new (&x) T{};
}
Run Code Online (Sandbox Code Playgroud)

如果存在现有的指针或引用怎么办,如

int main() {
    S s;
    s.x = 42;
    const S& sref = s;
    reconstruct(s);
    return sref.x; // Is this UB because the original S sref references no longer exists?
}
Run Code Online (Sandbox Code Playgroud)

我问这个的原因是std::once_flag没有重置机制。我知道为什么它通常不能,而且很容易误用,但是,在某些情况下我想进行线程不安全的重置,并且我认为这种重建模式会给我我想要的,只要这种重建是定义的行为。 https://godbolt.org/z/de5znWdYT

c++ lifetime language-lawyer

13
推荐指数
1
解决办法
316
查看次数

调整 C++20 范围管道的 clang-format

C++20(以及带有 的 23 std::ranges::to<T>())惯用地使用operator|来创建如下所示的转换管道:

    return numbers 
        | std::views::filter([](int n) { return n % 2 == 0; })
        | std::views::transform([](int n) { return n * 2; })
        | std::ranges::to<std::vector>();
Run Code Online (Sandbox Code Playgroud)

根据我的项目的当前情况.clang-format,看起来像

    return numbers | std::views::filter([](int n) { return n % 2 == 0; }) |
           std::views::transform([](int n) { return n * 2; }) | std::ranges::to<std::vector>();
Run Code Online (Sandbox Code Playgroud)

我觉得很难读。如果我设置BreakBeforeBinaryOperators: All我得到

    return numbers | std::views::filter([](int n) { return n % 2 == 0; })
           | std::views::transform([](int n) { return …
Run Code Online (Sandbox Code Playgroud)

c++ clang-format c++20 std-ranges

12
推荐指数
1
解决办法
900
查看次数

当模板参数全部被推导时,它们的顺序是否重要?

我发现 Clang、GCC 和 MSVC 之间存在差异,其中 GCC 和 Clang 执行了我所期望的操作:

#include <Eigen/Core>

template <typename Indices, typename T, int Rows> //< Bad
//template <typename Indices, int Rows, typename T> //< OK
//template <typename T, int Rows, typename Indices> //< OK
//template <typename T, typename Indices, int Rows> //< Bad
//template <int Rows, typename Indices, typename T> //< Bad
//template <int Rows, typename T, typename Indices> //< Bad
void f(
    const Eigen::Matrix<T, Rows, 1>&,
    const Indices&
) {}


int main() {
    f(Eigen::Matrix<double, 6, …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer template-argument-deduction

12
推荐指数
1
解决办法
201
查看次数

别名"git git"只是"git"?

我不时地打字输入" git"然后想出别的东西,然后键入例如" git checkout master".当然,这让我失望了

$ git git checkout master
git: 'git' is not a git command. See 'git --help'.

Did you mean this?
    init
$
Run Code Online (Sandbox Code Playgroud)

有没有办法创建一个名为gitno-op 的git别名?我已经尝试了明显的" git = ''"和" git = """以及" git = " "",但毫不奇怪,它们都会产生类似的反应Expansion of alias 'git' failed; '' is not a git command.

git

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

如果我在Python中引用了一个绑定方法,那么单独保持对象存活吗?

我今天写了这样的东西(与mpl_connect文档不同:

class Foo(object):
    def __init__(self): print 'init Foo', self
    def __del__(self): print 'del Foo', self
    def callback(self, event=None): print 'Foo.callback', self, event


from pylab import *
fig = figure()
plot(randn(10))
cid = fig.canvas.mpl_connect('button_press_event', Foo().callback)
show()
Run Code Online (Sandbox Code Playgroud)

这看起来很合理,但它不起作用 - 就好像matplotlib失去了我给它的功能.如果不通过它Foo().callback我通过它lambda e: Foo().callback(e),它的工作原理.同样,如果我说x = Foo(),然后通过它x.callback,它的工作原理.

我的假设是,创建的未命名的Foo实例会在行Foo()之后立即销毁mpl_connect- 具有Foo.callback引用的matplotlib 不会保持Foo活动状态.那是对的吗?

在我遇到的非玩具代码中,解决方案x = Foo()没有用,大概是因为在那种情况下show()其他地方x已经超出了范围.

更一般地说,Foo().callback是一个<bound method Foo.callback of <__main__.Foo object at …

python matplotlib

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

当std :: atomic <T> :: is_always_lock_free为false时std :: atomic <T>是否安全?

在没有操作系统的嵌入式(ARM)环境中,如果我使用中断,那么是否存在使用死锁的可能性std::atomic<T>?如果是这样,怎么样?

通常,任何时刻,控制都可以被中断以处理中断.特别是,如果一个人天真地拥有一个互斥体并想用它来对变量做一个"安全",那么可以锁定它,写入和解锁,然后锁定,读取和解锁.但是如果读取是在一个中断中,你可以锁定,中断,锁定=>死锁.

特别是,我有一个std::atomic<int>为这is_always_lock_freefalse.我应该担心僵局吗?当我查看生成的程序集时,编写42如下:

bl __sync_synchronize
mov r3, #42
str r3, [sp, #4]
bl __sync_synchronize
Run Code Online (Sandbox Code Playgroud)

它似乎没有锁定.用于读取值的asm是类似的.对于发烧友的操作是否(可能)锁定了exchange

c++ embedded atomic interrupt

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