从C++ 11标准(15.1.p4):
除非在3.7.4.1中指出,否则异常对象的内存以未指定的方式分配
如果分配失败怎么办 - 它会抛出std::bad_alloc吗?打电话std::terminate?未指定?
std::make_unique()(和类似的功能)有一点问题:
#include <cstdio>
#include <memory>
using namespace std;
struct S
{
S() { printf("ctor\n"); }
~S() { printf("dtor\n"); }
S(S const&) { printf("cctor\n"); }
S(S&&) { printf("mctor\n"); }
};
S foo() { return S(); }
int main()
{
{
printf("--------------- case 1 ---------------\n");
unique_ptr<S> s1 = make_unique<S>( foo() );
}
{
printf("--------------- case 2 ---------------\n");
unique_ptr<S> s2 { new S( foo() ) };
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
--------------- case 1 ---------------
ctor
mctor
dtor
dtor
--------------- case 2 …Run Code Online (Sandbox Code Playgroud) 在研究了HTTP/1.1标准之后,特别是第31页和相关的我得出结论,任何8位八位字节都可以出现在HTTP头值中.即任何带有[0,255]范围代码的字符.
然而我试过的HTTP服务器拒绝接受代码> 127(或大多数US-ASCII不可打印的字符)的任何东西.
这里是标准中使用的语法摘录:
message-header = field-name ":" [ field-value ]
field-name = token
field-value = *( field-content | LWS )
field-content = <the OCTETs making up the field-value and consisting of
either *TEXT or combinations of token, separators, and
quoted-string>
CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>
SP = <US-ASCII SP, space (32)>
HT = <US-ASCII HT, horizontal-tab (9)>
CRLF = CR LF
LWS = [CRLF] 1*( SP | HT ) …Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
struct S
{
S() = default;
S(S const&) = delete;
// S(S&&) = delete; // <--- uncomment for a mind-blowing effect:
// MSVC starts compiling EVERY case O_O
};
S foo() { return {}; }
struct X : S
{
// X() : S(foo()) {} // <----- all compilers fail here
};
struct Y
{
S s;
Y() : s(foo()) {} // <----- only MSVC fails here
};
struct Z
{
S s = {}; // ... …Run Code Online (Sandbox Code Playgroud) 我正在检查为我的一些代码生成的 asm,我的眼睛发现了一些有趣的东西:
#include <mutex>
std::mutex m;
void foo()
{
m.lock();
}
Run Code Online (Sandbox Code Playgroud)
生成的汇编代码 (x86-64 gcc 9.2, -std=c++11 -O2):
foo():
mov eax, OFFSET FLAT:_ZL28__gthrw___pthread_key_createPjPFvPvE
test rax, rax
je .L10 // (1) we can simply bypass lock() call?
sub rsp, 8
mov edi, OFFSET FLAT:m
call __gthrw_pthread_mutex_lock(pthread_mutex_t*)
test eax, eax
jne .L14 // (2) waste of space that will never be executed
add rsp, 8
ret
.L10:
ret
.L14:
mov edi, eax
call std::__throw_system_error(int)
m:
.zero 40
Run Code Online (Sandbox Code Playgroud)
问题:
(与这个问题相关)。
我正在尝试unique_ptr通过 lambda组合std::integral_constant(在 C++20 中获取大多数 std 函数的地址是非法的,我正在找出一种将它们包装在 lambda 中的便捷方法)。我注意到std::integral_constant我无法解释的奇怪行为(godbolt):
#include <type_traits>
template<auto L, class T = decltype(L)>
using constant = std::integral_constant<T, L>;
void dummy(void*);
int main()
{
using C1 = constant<&dummy>;
using C2 = constant<[](void* p){ dummy(p); }>;
C1()()(nullptr); // #1 works as expected
C2()()(nullptr); // #2 works as expected
C1()(nullptr); // #3 unexpectedly works
C2()(nullptr); // #4 fails as expected
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么第 3 行可以编译吗?这就是std::unique_ptr秘密使用的内容(当你用作std::integral_constant …
下面是一个 C++17 代码片段,其中一个线程等待另一个线程到达某一阶段:
std::condition_variable cv;
std::atomic<bool> ready_flag{false};
std::mutex m;
// thread 1
... // start a thread, then wait for it to reach certain stage
auto lock = std::unique_lock(m);
cv.wait(lock, [&]{ return ready_flag.load(std::memory_order_acquire); });
// thread 2
... // modify state, etc
ready_flag.store(true, std::memory_order_release);
std::lock_guard{m}; // NOTE: this is lock immediately followed by unlock
cv.notify_all();
Run Code Online (Sandbox Code Playgroud)
据我了解,这是使用原子标志和条件变量来实现目标的有效方法。例如不需要使用std::memory_order_seq_cst。
是否可以进一步放宽此代码?例如:
std::memory_order_relaxed在ready_flag.load()std::atomic_thread_fence()而不是std::lock_guard{m};您应该使用std::make_shared以确保带有计数器的块存储在数据旁边.不幸的是,内部std::make_shared<T>使用零初始化T(即用于T()初始化数据块).有没有办法欺骗它使用默认初始化?我知道我可以使用std::shared_ptr<T>( new T, [](auto p){delete p;}),但我最终会得到两个分配(数据和计数器块不会彼此相邻).
这是否会导致不平衡树(以及随后的搜索性能不佳)std::map/set:
std::set<int> s;
for(int i = 0; i< 1000; ++i)
s.insert(s.end(), i);
Run Code Online (Sandbox Code Playgroud)
?
或者换句话说:"暗示插入"会根据需要重新平衡底层树吗?
Afaik,C++标准不保证这一点,但我想知道在这种情况下最流行的实现是如何表现的.
Rust 有相当于 C++ 的吗std::chrono::steady_clock?(强调稳定)
该时钟的时间点不会随着物理时间的向前移动而减少,并且该时钟的滴答之间的时间是恒定的。
std::time::Instant显然不适合:
...瞬间不能保证稳定。换句话说,底层时钟的每个滴答声的长度可能不同(例如,某些秒可能比其他秒长)。某个瞬间可能会向前跳跃或经历时间膨胀(减慢或加速)......
x<N>.rs在我的库中,我有几个示例 - (通常)每个示例都由目录中的单个文件表示examples。
一个示例使用一个.proto文件——该文件需要在(所述示例的)构建期间进行编译,并且它生成的输出由示例本身使用。
我在我的中尝试过这个Cargo.toml:
[[example]]
name = "x1"
path = "examples/x1/main.rs"
build = "examples/x1/build.rs"
Run Code Online (Sandbox Code Playgroud)
但是build当我跑步时键被忽略cargo build --example x1
是否可以有特定于示例的build.rs文件?
如果不是——处理这种情况的正确方法是什么?
编辑:我最终.proto在板条箱中处理该文件build.rs(即使不需要构建该板条箱)并在示例中使用工件,如下所示:
pub mod my_proto {
include!(concat!(env!("OUT_DIR"), "/my_proto.rs"));
}
Run Code Online (Sandbox Code Playgroud) 基本上:
auto p1 = std::steady_clock::now().time_since_epoch().count();
... // do smth for unspecified period of time
auto p2 = std::steady_clock::now().time_since_epoch().count();
assert(p2 >= p1); // is this guaranteed?
Run Code Online (Sandbox Code Playgroud)
?
如果是 - 这是如何保证的?通过确保没有 C++ 程序运行时间超过std::steady_clock::duration::max() - std::steady_clock::duration::zero()?
在我看来,标准允许std::exception_ptr不使用引用计数(即std::exception_ptrcctor 可以制作它指向的异常对象的副本)。这意味着以下代码可能永远不会调用,handle_eptr()并且异常可能会main()因相关后果而逃逸:
#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>
void handle_eptr(std::exception_ptr eptr) // passing by value is ok <---- ARE YOU SURE?
{
try {
if (eptr) {
std::rethrow_exception(eptr);
}
} catch(const std::exception& e) {
std::cout << "Caught exception \"" << e.what() << "\"\n";
}
}
int main()
{
std::exception_ptr eptr;
try {
std::string().at(1); // this generates an std::out_of_range
} catch(...) {
eptr = std::current_exception(); // capture
}
handle_eptr(eptr); …Run Code Online (Sandbox Code Playgroud) c++ ×10
c++11 ×5
c++17 ×5
c++14 ×2
rust ×2
c++-chrono ×1
gcc ×1
http ×1
http-headers ×1
rust-cargo ×1