Forwarded from Lancern's Treasure Chest
对于上面的 C++ 代码,下面哪一个说法是正确的?
Anonymous Quiz
29%
程序无法通过编译
32%
程序的行为是良定义的
18%
当 condition 为 true 时程序具有未定义行为
21%
无论 condition 的值如何,程序总具有未定义行为
草,原来就叫 std::move
建议加入 std::copy 的 cppreference 底下的 see also
template<typename T>
decltype(auto) avg(T x, T y)
noexcept(noexcept((x + y) / 2))
requires requires { (x + y) / 2; }
{
return (x + y) / 2;
}
Forwarded from Lancern's Treasure Chest
2024 年 4 月 Tokyo 会议后一些频道主认为有意思的 C++ 标准提案
P1061R8: Structured Bindings can introduce a Pack
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p1061r8.html
允许结构化绑定引入 pack :
P2034R3: Partially Mutable Lambda Captures
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2034r3.pdf
允许分别将每个 lambda 捕获声明为 mutable 了:
P2135R1: P2055R1: A Relaxed Guide to memory_order_relaxed
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2135r1.pdf
一篇科普性质文章,介绍 C++11 relaxed 内存序的原子操作的 out-of-thin-air 现象以及 read-from-untaken-branch 现象,以及如何在已有程序中识别潜在的相关问题
P2141R2: Aggregates are named tuples
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2141r2.html
让
P2747R2: constexpr placement new
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2747r2.html
让 placement-new 成为 core constant expression
P2748R5: Disallow Binding a Returned Glvalue to a Temporary
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2748r5.html
当函数返回一个引用时,不再允许这个引用绑定到临时对象上,杜绝一类 use-after-free 缺陷:
P2988R4: std::optional<T&>
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2988r4.pdf
给
逐步氧化起来了
P3166R0: Static Exception Specifications
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3166r0.html
又要搞大新闻,重新引入了之前被废弃的
一个亮点是允许使用
与老式
按照这样的设计编译器理论上可以把所有带有
P3176R0: The Oxford variadic comma
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3176r0.html
不再允许不带前导逗号的 ellipsis parameter :
P1061R8: Structured Bindings can introduce a Pack
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p1061r8.html
允许结构化绑定引入 pack :
std::tuple<X, Y, Z> f();
auto [...xs] = f(); // OK
auto [x, ...rest] = f(); // OK
auto [x,y,z, ...rest] = f(); // OK
auto [x, ...rest, z] = f(); // OK
P2034R3: Partially Mutable Lambda Captures
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2034r3.pdf
允许分别将每个 lambda 捕获声明为 mutable 了:
auto a = [mutable x, y]() {
x = 1; // OK
y = 2; // Error
};P2135R1: P2055R1: A Relaxed Guide to memory_order_relaxed
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2135r1.pdf
一篇科普性质文章,介绍 C++11 relaxed 内存序的原子操作的 out-of-thin-air 现象以及 read-from-untaken-branch 现象,以及如何在已有程序中识别潜在的相关问题
P2141R2: Aggregates are named tuples
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2141r2.html
让
std::get, std::tuple_element 以及 std::tuple_size 等实现 tuple protocol 的 STL 函数和 type traits 原生支持 aggregate 类型:struct Foo { int x; double y; std::string z; };
Foo x{1, 2.0, "3"};
std::get<1>(x); // Evaluate to 2.0
static_assert(std::is_same_v<
std::string,
typename std::tuple_element<2, Foo>::type
>); // OK
static_assert(std::tuple_size<Foo> == 3); // OKP2747R2: constexpr placement new
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2747r2.html
让 placement-new 成为 core constant expression
P2748R5: Disallow Binding a Returned Glvalue to a Temporary
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2748r5.html
当函数返回一个引用时,不再允许这个引用绑定到临时对象上,杜绝一类 use-after-free 缺陷:
const int &foo() {
return 42; // Ill-formed
}P2988R4: std::optional<T&>
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2988r4.pdf
给
std::optional 引入 std::optional<T&> 特化,可以实现用 std::optional 上的 monadic 操作替换一堆空指针判断逐步氧化起来了
P3166R0: Static Exception Specifications
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3166r0.html
又要搞大新闻,重新引入了之前被废弃的
throw 声明符,可以用于声明一个函数所能够抛出的所有可能的异常类型:void throws_nothing() throw(); // Effectively `noexcept`
void throws_a_b() throw(A, B); // throws_a_b can throw A or B
void throws_any() throw(...); // throws_any may throw any exception
一个亮点是允许使用
throw(auto) 自动推导函数可能抛出的异常类型集合:void foo() throw(auto) { /* ... */ }与老式
throw 声明符的本质区别在于编译器会强制检查异常集合的正确性。如果函数带有 throw 声明符但却可能抛出没有通过 throw 声明符声明的异常,那么程序 ill-formed:void foo() throw(A) {
throws_a_b(); // Ill-formed: B is not listed above
try {
throws_a_b(); // Ill-formed: B is not caught
}
catch (A) {}
try {
throws_a_b(); // OK since B will be caught
}
catch (A) {}
catch (B) {}
}按照这样的设计编译器理论上可以把所有带有
throw 声明符的函数的异常路径算得明明白白,可以开始优化 try-catch 路径了(例如把 throw-catch 直接优化为 goto)。P3176R0: The Oxford variadic comma
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3176r0.html
不再允许不带前导逗号的 ellipsis parameter :
void foo(int ...); // Ill-formed
今日 debug:程序莫名其妙偶发死锁,一路查下来发现之前写了个在 signal handler 里面调用 omp_set_num_threads,其中可能调用了 malloc,然而被信号打断的现场恰好也正在调用 malloc 中,导致 signal handler 死在了 futex_wait 里
Forwarded from 每日消费电子观察 (horo)
Rust 基金会宣布 C++ 和 Rust 互操作性方面进展:正提升项目功能、解决短期技术挑战
============
互操作性是什么东西,们语言神不都直接 riir 的吗
https://www.ithome.com/0/811/212.htm
============
互操作性是什么东西,们语言神不都直接 riir 的吗
https://www.ithome.com/0/811/212.htm
Ithome
Rust 基金会宣布 C++ 和 Rust 互操作性方面进展:正提升项目功能、解决短期技术挑战 - IT之家
谷歌于今年 2 月宣布向 Rust 基金会捐款 100 万美元(IT之家备注:当时约 721 万元人民币),这笔资金将用于改善 C++ 与 Rust 互操作性。Rust 基金会现已在 GitHub 发布报告宣布他们在 C++ 和 Rust 互操作性方面取得的进展,报告指出 Rust 基金会当前的目标是不断提升 Rust 本身的功能、解决短期技术挑战,从而为实现长期的互操作性奠定基础。
Forwarded from saffah 的日常废话【一周年快乐!】 (saffahyjp | 二饼 | 2p | 扩散语言模型 | ɥɐɟɟɐs)
今日 C++ 笑话:在报错信息里看到了 SomeClass::someFunc::(anonymous class)::operator()::(anonymous class)::operator()::(anonymous class)::operator()::(anonymous class)::operator()::(anonymous class)::operator()::(anonymous class)::operator()::(anonymous class)::operator()::(anonymous class)::operator()
Lancern's Treasure Chest
P3312: Overload Set Types 目前,如下的代码片段无法编译: std::vector<float> v = {1, 2, 3, 4}; std::ranges::transform(v, v.begin(), std::sin); 这是因为 std::sin 具有多个重载: float sin(float); double sin(double); long double sin(long double); template <typename T> double sin(T);…
对这个问题,我曾经有个 workaround 是
但是这有个问题,比如还是用 sin 举例,那么 requires { FN(sin)(1, 2) } 会得到一个 true,但实际上 sin 不能支持多个参数调用
隔壁群主 @lancern 给出了一个更强的 workaround 能解决这个问题,让我们一起领略现代 C++ 的美感!
#define FN(f...) [&]<typename... Args>(Args&&... args)->decltype(auto){return (f)(std::forward<Args>(args)...);}但是这有个问题,比如还是用 sin 举例,那么 requires { FN(sin)(1, 2) } 会得到一个 true,但实际上 sin 不能支持多个参数调用
隔壁群主 @lancern 给出了一个更强的 workaround 能解决这个问题,让我们一起领略现代 C++ 的美感!
TIL:lambda 的 noexcept 必须放在 trailing return type 的前面,与参数有关的 requires 必须放在 trailing return type 的后面
所以正确顺序是
[&]
<typename... Ts>
requires something<Ts...>
[[noreturn]]
(Ts&&... ts)
mutable
noexcept(true)
[[another_attr]]
-> decltype(auto)
requires requires { someThing(ts...); }
pre(somePre(ts...))
{
ohFinallyTheBody();
}
Forwarded from valueless channel
#今天踩了啥坑 #cpp #cpp20
先试试你能一眼看出代码中的错误吗
尽管走到判断 i 的奇偶处,一定隐含了 i 不会小于等于 1,但在 if constexpr 的上下文中,有无 else 关键字对编译器来说是有区别的 —— if constexpr 上下文以外的代码对于编译器总是可见的(不受编译时常量条件编译),所以上面的代码会导致实例化出 i 下溢出到负数长度的 buffer 数组。
https://godbolt.org/z/nPz9WzxrK
template<size_t i>
consteval void count_to_one() {
if constexpr (i <= 1) {
return;
}
char buffer[i];
if constexpr (i % 2 == 0) {
// ... do something if `i` is even
return count_to_one<i - 1>();
} else {
// ... do something if `i` is odd
return count_to_one<i - 1>();
}
}
int main() {
count_to_one<10>();
}
先试试你能一眼看出代码中的错误吗
TIL
如果 x 是以 const auto&& 定义的,那么 return x 会尝试进行拷贝构造;如果 x 是以 auto&& 定义的,则 return x 会走 forced ellision
如果 x 是以 const auto&& 定义的,那么 return x 会尝试进行拷贝构造;如果 x 是以 auto&& 定义的,则 return x 会走 forced ellision