小编Cur*_*ous的帖子

为什么for_each通过移动返回功能

我正在阅读std::for_each这里的文档http://en.cppreference.com/w/cpp/algorithm/for_each并看到返回值是std::move(f)

为什么标准强制在返回值中移动输入参数?默认情况下不会移动它,因为输入参数是按值传递的吗?


当您编译以下代码时,这会引导我进行几次跟进

Something function(Something something) {
    return something;
} 
Run Code Online (Sandbox Code Playgroud)
  1. return语句是我的系统上具有最高优化级别(-O3)的移动,为什么大多数编译器都不会忽略此返回值?省略了本地值,但函数参数不是..

  2. 在这种情况下C++ 17是否强制执行?我阅读了该提案(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html)但我并不完全了解哪些案例符合强制性省略的条件.

Apple LLVM version 8.0.0 (clang-800.0.42.1)在我的Mac和g++ 5.4Ubuntu 16.04 上试过这个.

c++ move copy-elision c++11 c++17

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

clang thread_local初始化中的错误

以下代码应该只创建thread_local一次in-class ,但最终会在每次访问时初始化它

#include <iostream>
#include <thread>

using std::cout;
using std::endl;

template <typename T>
class Something {
public:
    struct TLBookkeeping {
        TLBookkeeping() {
            std::cout << "TLBookkeeping() " << std::this_thread::get_id() << std::endl;
        }
    };

    static void foo();
    static thread_local TLBookkeeping bookkeeping_;
};

template <typename T>
thread_local typename Something<T>::TLBookkeeping Something<T>::bookkeeping_;

template <typename T>
void Something<T>::foo() {
    std::cout << &bookkeeping_ << std::endl;
    std::cout << &bookkeeping_ << std::endl;
}

namespace {
struct Struct {};
}

int main() {    
    Something<Struct>::foo();
}
Run Code Online (Sandbox Code Playgroud)

(https://wandbox.org/permlink/fgqCDHV0axKDRt89) …

c++ multithreading clang thread-local c++17

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

次优高速缓存行预取的成本

使用__builtin_prefetch(..., 1)内部函数(准备写入时的预取)完成后期预取的成本是多少?也就是说,在需求加载或写入需要它之前没有到达L1缓存的预取?

例如

void foo(std::uint8_t* line) {
    __builtin_prefetch(line + std::hardware_constructive_interference_size, 1);
    auto next_line = calculate_address_of_next_line(line);
    auto result = transform(line);
    write(next_line, result)
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果成本transform低于预取,那么这个代码最终会比没有预取的效率低吗?关于缓存预取的维基百科文章讨论了for循环的最佳步幅,但未提及该场景中次优预取的影响(例如,如果k太低会发生什么?).

这是否足够流水线以至于次优预取无关紧要?出于这个问题的目的,我只考虑Intel x86(Broadwell时代的处理器).

c++ performance x86 assembly prefetch

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

英特尔硬件上的商店缓冲区大小?什么是商店缓冲区?

英特尔优化手册似乎对存储缓冲区的数量存在于处理器的许多地方,但谈判没有谈存储缓冲区的大小.这是公共信息还是商店缓冲区的大小保留为微架构细节?

我正在研究的处理器主要是Broadwell和Skylake,但其他人的信息也不错.

另外,存储缓冲区究竟做了什么?

performance x86 assembly intel cpu-architecture

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

poll()系统调用以及之后接收或发送数据的行为

让我们考虑下面的代码

pollfd file_descriptors[1];
file_descriptors[0].fd = sock_fd;
file_descriptors[0].events = POLLIN;

int return_value = poll(file_descriptors, 1, 0);

if (return_value == -1) { cerr << strerror(errno); }
else if (return_value == 0) { cerr << "No data available to be read"; }
else { 
    if (file_descriptors[0].revents & POLLIN) {
        recv(sock_fd, buff, 1024, 0); 
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我对上面的代码有两个问题.

  1. 如果对poll()的调用既不返回也-1没有在数组中的第一个条目的位图中0设置POLLIN标志,那么调用是否会阻塞?如果不是,那么数据是否会即时读取?reventsfile_descriptorsrecv()
  2. 假设呼叫poll()的方式与上面提到的相同.要读入多少数据?它只是和普通电话一样recv()吗?即1024在上述情况下小于或等于任意(对程序员)的数量.然后,如果我想poll()再次阅读之前,我是否只是从第一次调用开始重复,poll()直到完全读取所有数据(即在客户端服务器方案中,这将对应于正在完成的请求)?

谢谢!

c++ sockets networking tcp c++11

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

引用可能被破坏的静态对象

假设我有以下代码

Something.hpp

#pragma once

class Something {
public:
    static Something& get();
private: 
    Something();
};
Run Code Online (Sandbox Code Playgroud)

Something.cpp

#include "Something.hpp"
#include <iostream>
using namespace std;

Something& Something::get() {
    static Something something;
    return something;
}
Something::Something() {
    cout << "Something()" << endl;
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include <iostream>
using namespace std;

struct SomethingElse {
    ~SomethingElse() {
        Something::get();
        cout << "~SomethingElse" << endl; 
    }
};

void func() {
    static SomethingElse something_else;
    // do something with something_else
}

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

Something是否可以创建多个对象实例?标准是否说明了序列化静态对象的破坏?

注意 …

c++ static-variables c++11

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

谁负责共同的未来和承诺状态

谁拥有期货和承诺的共享国家?特别是谁负责构建和删除这些类中的共享状态?或者共享状态应该被引用计数?通过在cppreference上阅读这些文档,我无法得到答案.

我想到它的方式最简单的方法就是让std::promise类负责创建共享状态,然后将其交给在未来被销毁时std::futurestd::promisefor中取出的那个.但是这种方法可能导致悬挂的承诺对象.所以我不确定这两者之间应该分享这个州的真实情况.

例如,下面的代码是否会产生未定义的行为(因为未来被销毁时可能会破坏共享状态)?

auto prom = std::promise<void>{};
{
    auto fut = prom.get_future();
}
prom.set_value();
Run Code Online (Sandbox Code Playgroud)

此外,std::promise::~promise关于cppreference 的文档说"如果共享状态已准备好,则释放它",这让我认为共享状态不是引用计数.

c++ future promise c++11 c++14

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

为什么const rvalue限定std :: optional :: value()返回一个const右值引用?

std::optional::value() 有两个以上的重载

constexpr T& value() &;
constexpr const T & value() const &; 
constexpr T&& value() &&;
constexpr const T&& value() const &&;
Run Code Online (Sandbox Code Playgroud)

返回const右值引用有什么意义?

我能想到的唯一原因是使编译器能够帮助捕获未完成的行为(真的很奇怪),如下所示

auto r = std::cref(const_cast<const std::optional<int>&&>(
    std::optional<int>{}).value());
Run Code Online (Sandbox Code Playgroud)

如果std::optional::value()已返回a,const T&则上述代码将编译,并在r reference_wrapper以后使用时导致未定义的行为.

以上返回的是否有任何其他角落案例const T&&

c++ rvalue-reference c++17 stdoptional

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

std :: atomic与另一个角色的联合

我最近阅读了一些在同一个联合中具有原子和字符的代码.像这样的东西

union U {
    std::atomic<char> atomic;
    char character;
};
Run Code Online (Sandbox Code Playgroud)

我不完全确定这里的规则,但代码注释说,因为一个字符可以别名,所以如果我们保证不改变字节的最后几位,我们就可以安全地对原子变量进行操作.并且该字符仅使用最后几个字节.

这是允许的吗?我们可以在一个字符上覆盖原子整数并使它们都处于活动状态吗?如果是这样,当一个线程试图从原子整数加载值并且另一个线程对该字符进行写入(仅最后几个字节)时会发生什么情况,那么char写入是原子写入吗?那里发生了什么?是否必须为尝试加载原子整数的线程刷新缓存?

(这段代码对我来说也很臭,我并不主张使用它.只是想了解上述方案的哪些部分可以定义,在什么情况下)


根据要求,代码正在做这样的事情

// thread using the atomic
while (!atomic.compare_exchange_weak(old_value, old_value | mask, ...) { ... }

// thread using the character
character |= 0b1; // set the 1st bit or something
Run Code Online (Sandbox Code Playgroud)

c++ multithreading strict-aliasing language-lawyer stdatomic

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

模板模板类谓词不在部分特化中工作

我有很多EnableIf特性,基本上检查输入类型是否满足接口.我试图创建一个通用Resolve特征,可用于将这些特征转换为布尔特征.

像这样的东西 - https://wandbox.org/permlink/ydEMyErOoaOa60Jx

template <
  template <typename...> class Predicate,
  typename T,
  typename = std::void_t<>>
struct Resolve : std::false_type {};
template <template <typename...> class Predicate, typename T>
struct Resolve<Predicate, T, Predicate<T>> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)

现在,如果你有这样的EnableIf特质

template <typename T>
using EnableIfHasFoo = std::void_t<decltype(std::declval<T>().foo())>;
Run Code Online (Sandbox Code Playgroud)

您可以非常快速地创建它的布尔版本

template <typename T>
struct HasFoo : Resolve<EnableIfHasFoo, T> {};
Run Code Online (Sandbox Code Playgroud)

或类似的变量模板.

但由于某种原因,部分专业化没有按预期工作.Resolve不能按预期工作.请参阅此处的输出 - https://wandbox.org/permlink/ydEMyErOoaOa60Jx.同样的事情实现"手动"工作 - https://wandbox.org/permlink/fmcFT3kLSqyiBprm

我自己手动定义类型.是否存在我缺少的部分特化和模板模板参数的详细信息?

c++ templates sfinae enable-if c++17

7
推荐指数
2
解决办法
211
查看次数