mastodon.world is one of the many independent Mastodon servers you can use to participate in the fediverse.
Generic Mastodon server for anyone to use.

Server stats:

9.5K
active users

🌗 C++26:標準函式庫中更多 constexpr
➤ C++26 將編譯時期程式設計提升至新高度
sandordargo.com/blog/2025/04/3
本文探討了 C++26 即將推出的標準函式庫中,更多功能將能在編譯時期使用 (constexpr)。文章重點介紹了關於穩定排序、`<cmath>` 和 `<complex>`、trivial unions、容器和adaptors、以及特殊記憶體演算法的提案,以及這些變更如何提升編譯時期程式設計的能力。總體而言,C++26 在 constexpr 的支援上邁出了一大步,未來編譯時期程式設計將更加普及且強大。
+ 哇,這個更新太棒了!constexpr 幫助我避免了許多執行時期的錯誤,現在能用在更多標準函式庫功能上,簡直是夢寐以求的。
+ 雖然有一些細節比較複雜,但整體來看,C++26 的這些改變真的很有意義,讓 C++ 更加強大和高效。
#C++ #程式設計 #constexpr

Sandor Dargo’s Blog · C++26: more constexpr in the standard libraryLast week, we discussed language features that are becoming constexpr in C++26. Today, let’s turn our attention to the standard library features that will soon be usable at compile time. One topic is missing: exceptions. As they need both core language and library changes, I thought they deserved their own post. P2562R1: constexpr stable sorting This paper proposes making std::stable_sort, std::stable_partition, std::inplace_merge, and their ranges counterparts usable in constant expressions. While many algorithms have become constexpr over the years, this family related to stable sorting had remained exceptions — until now. The recent introduction of constexpr containers gives extra motivation for this proposal. If you can construct a container at compile time, it’s only natural to want to sort it there, too. More importantly, a constexpr std::vector can now support efficient, stable sorting algorithms. A key question is whether the algorithm can meet its computational complexity requirements under the constraints of constant evaluation. Fortunately, std::is_constant_evaluated() provides an escape hatch for implementations. For deeper details, check out the proposal itself. P1383R2: More constexpr for <cmath> and <complex> While P0533 made many <cmath> and <cstdlib> functions constexpr-friendly in C++23, it only addressed functions with trivial behavior — those no more complex than the basic arithmetic operators. Floating-point computations can yield different results depending on compiler settings, optimization levels, and hardware platforms. For instance, calculating std::sin(1e100) may produce varying outcomes due to the intricacies of floating-point arithmetic at such scales. The paper discusses these challenges and suggests that some variability in results is acceptable, given the nature of floating-point computations. The proposal accepts the need for a balance between strict determinism and practical flexibility. It suggests that while some functions should produce consistent results across platforms, others may inherently allow for some variability. P3074R7: trivial unions (was std::uninitialized<T>) To implement static, in-place, constexpr-friendly containers like non-allocating vectors, you often need uninitialized storage — typically via unions. However, default behavior for special members of unions has been limiting: if not all alternatives are trivial, the special member is deleted. This presents a problem for constexpr code where a no-op destructor isn’t quite the same as a trivial one. The road to solving this wasn’t short: P3074R7 went through seven revisions and considered five possible solutions—including library-based approaches, new annotations, and even a new union type. Ultimately, the committee decided to just make it work with minimal changes to the user experience. But how? For unions, the default constructor - if there is no default member initializer - is always going to be trivial. If the first alternative is an implicit-lifetime time, it begins its life-time and becomes the active member. The defaulted destructor is deleted if either the union has a user-provided default constructor or there exists a variant alternative that has a default member initializer and that member’s destructor is either deleted or inaccessible. Otherwise, the destructor is trivial. This excerpt from the proposal shows the changes well. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // trivial default constructor (does not start lifetime of s) // trivial destructor // (status quo: deleted default constructor and destructor) union U1 { string s; }; // non-trivial default constructor // deleted destructor // (status quo: deleted destructor) union U2 { string s = "hello"; } // trivial default constructor // starts lifetime of s // trivial destructor // (status quo: deleted default constructor and destructor) union U3 { string s[10]; } // non-trivial default constructor (initializes next) // trivial destructor // (status quo: deleted destructor) union U4 { string s; U4* next = nullptr; }; P3372R2: constexpr containers and adaptors Hana Dusíková authored a massive proposal that boils down to a simple goal: make (almost) all containers and adaptors constexpr. Up until now, only a handful of them were constexpr-friendly (std::vector, std::span, std::mdspan, std::basic_string and std::basic_string_view). From now on, the situation will be flipped. Almost everything will be constexpr-friendly. There is one exception and one constraint: std::hive is not included, because it doesn’t have a stable wording yet if you want to use unordered containers at compile-time, you must provide your own hashing facility, because std::hash cannot be made constexpr-friendly due to its requirements. Its result is guaranteed to be consistent only with the duration of the program. Happy days! P3508R0: Wording for “constexpr for specialized memory algorithms” Such a strange title, isn’t? Wording for something… As it turns out, there was already a paper accepted (P2283R2) making specialized memory algorithms constexpr-friendly. Algorithms that are essential for implementing constexpr container support, yet they were forgotten from C++20. These algorithms are (both in std and in std::ranges namespaces): uninitialized_value_construct uninitialized_value_construct_n uninitialized_copy uninitialized_copy_result uninitialized_copy_n uninitialized_copy_n_result uninitialized_move uninitialized_move_result uninitialized_move_n uninitialized_move_n_result uninitialized_fill uninitialized_fill_n When the paper was made, the necessary implementation change was to use std::construct_at instead of placement new, as std::consturct_at was already constexpr. But in the meantime, P2747R2 was accepted and placement new in the core language also became constexpr. Therefore, the implementation of the above functions doesn’t have to be changed, only their signatures have to be updated to support constexpr. Hence, the wording change. P3369R0: constexpr for uninitialized_default_construct We saw that the constexpr placement new affected P2283R2 and raised the need for a wording change performed in P3508R0. But that’s not the only side-effect it had. From the above-listed algorithm families, one is missing: uninitialized_default_construct. The reason is that uninitialized_default_construct cannot be implemented with std::construct_at as it always performs value initialization, default initialization was impossible. But with constexpr placement new this is not an issue anymore, therefore uninitialized_default_construct can also be turned into constexpr. Conclusion C++26 marks a huge step forward for constexpr support in the standard library. From stable sorting algorithms to containers, from tricky union rules to specialised memory functions, compile-time programming is becoming more and more supported. In the next article, we’ll cover compile-time exceptions! Connect deeper If you liked this article, please hit on the like button, subscribe to my newsletter and let’s connect on Twitter!
Sandor Dargo’s Blog · C++26: more constexpr in the standard libraryLast week, we discussed language features that are becoming constexpr in C++26. Today, let’s turn our attention to the standard library features that will soon be usable at compile time. One topic is missing: exceptions. As they need both core language and library changes, I thought they deserved their own post. P2562R1: constexpr stable sorting This paper proposes making std::stable_sort, std::stable_partition, std::inplace_merge, and their ranges counterparts usable in constant expressions. While many algorithms have become constexpr over the years, this family related to stable sorting had remained exceptions — until now. The recent introduction of constexpr containers gives extra motivation for this proposal. If you can construct a container at compile time, it’s only natural to want to sort it there, too. More importantly, a constexpr std::vector can now support efficient, stable sorting algorithms. A key question is whether the algorithm can meet its computational complexity requirements under the constraints of constant evaluation. Fortunately, std::is_constant_evaluated() provides an escape hatch for implementations. For deeper details, check out the proposal itself. P1383R2: More constexpr for <cmath> and <complex> While P0533 made many <cmath> and <cstdlib> functions constexpr-friendly in C++23, it only addressed functions with trivial behavior — those no more complex than the basic arithmetic operators. Floating-point computations can yield different results depending on compiler settings, optimization levels, and hardware platforms. For instance, calculating std::sin(1e100) may produce varying outcomes due to the intricacies of floating-point arithmetic at such scales. The paper discusses these challenges and suggests that some variability in results is acceptable, given the nature of floating-point computations. The proposal accepts the need for a balance between strict determinism and practical flexibility. It suggests that while some functions should produce consistent results across platforms, others may inherently allow for some variability. P3074R7: trivial unions (was std::uninitialized<T>) To implement static, in-place, constexpr-friendly containers like non-allocating vectors, you often need uninitialized storage — typically via unions. However, default behavior for special members of unions has been limiting: if not all alternatives are trivial, the special member is deleted. This presents a problem for constexpr code where a no-op destructor isn’t quite the same as a trivial one. The road to solving this wasn’t short: P3074R7 went through seven revisions and considered five possible solutions—including library-based approaches, new annotations, and even a new union type. Ultimately, the committee decided to just make it work with minimal changes to the user experience. But how? For unions, the default constructor - if there is no default member initializer - is always going to be trivial. If the first alternative is an implicit-lifetime time, it begins its life-time and becomes the active member. The defaulted destructor is deleted if either the union has a user-provided default constructor or there exists a variant alternative that has a default member initializer and that member’s destructor is either deleted or inaccessible. Otherwise, the destructor is trivial. This excerpt from the proposal shows the changes well. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // trivial default constructor (does not start lifetime of s) // trivial destructor // (status quo: deleted default constructor and destructor) union U1 { string s; }; // non-trivial default constructor // deleted destructor // (status quo: deleted destructor) union U2 { string s = "hello"; } // trivial default constructor // starts lifetime of s // trivial destructor // (status quo: deleted default constructor and destructor) union U3 { string s[10]; } // non-trivial default constructor (initializes next) // trivial destructor // (status quo: deleted destructor) union U4 { string s; U4* next = nullptr; }; P3372R2: constexpr containers and adaptors Hana Dusíková authored a massive proposal that boils down to a simple goal: make (almost) all containers and adaptors constexpr. Up until now, only a handful of them were constexpr-friendly (std::vector, std::span, std::mdspan, std::basic_string and std::basic_string_view). From now on, the situation will be flipped. Almost everything will be constexpr-friendly. There is one exception and one constraint: std::hive is not included, because it doesn’t have a stable wording yet if you want to use unordered containers at compile-time, you must provide your own hashing facility, because std::hash cannot be made constexpr-friendly due to its requirements. Its result is guaranteed to be consistent only with the duration of the program. Happy days! P3508R0: Wording for “constexpr for specialized memory algorithms” Such a strange title, isn’t? Wording for something… As it turns out, there was already a paper accepted (P2283R2) making specialized memory algorithms constexpr-friendly. Algorithms that are essential for implementing constexpr container support, yet they were forgotten from C++20. These algorithms are (both in std and in std::ranges namespaces): uninitialized_value_construct uninitialized_value_construct_n uninitialized_copy uninitialized_copy_result uninitialized_copy_n uninitialized_copy_n_result uninitialized_move uninitialized_move_result uninitialized_move_n uninitialized_move_n_result uninitialized_fill uninitialized_fill_n When the paper was made, the necessary implementation change was to use std::construct_at instead of placement new, as std::consturct_at was already constexpr. But in the meantime, P2747R2 was accepted and placement new in the core language also became constexpr. Therefore, the implementation of the above functions doesn’t have to be changed, only their signatures have to be updated to support constexpr. Hence, the wording change. P3369R0: constexpr for uninitialized_default_construct We saw that the constexpr placement new affected P2283R2 and raised the need for a wording change performed in P3508R0. But that’s not the only side-effect it had. From the above-listed algorithm families, one is missing: uninitialized_default_construct. The reason is that uninitialized_default_construct cannot be implemented with std::construct_at as it always performs value initialization, default initialization was impossible. But with constexpr placement new this is not an issue anymore, therefore uninitialized_default_construct can also be turned into constexpr. Conclusion C++26 marks a huge step forward for constexpr support in the standard library. From stable sorting algorithms to containers, from tricky union rules to specialised memory functions, compile-time programming is becoming more and more supported. In the next article, we’ll cover compile-time exceptions! Connect deeper If you liked this article, please hit on the like button, subscribe to my newsletter and let’s connect on Twitter!
Replied in thread

@george C++ in college. If you're needing a first language, I suggest Java because many of the High School AP CompSci courses are Java. Why? I do not know. My advise is don't fuck around with Kotlin. Start with a solid systems language like #Rust or #C so you get a good understanding of concepts. Python and the scripting languages are FANTASTIC, but have a good systems language in your toolbox.

The next major improvement for #swad (for upcoming version 0.6) will be reloading the #configuration file. That's a surprisingly complex thing to implement, reaching from "how to integrate custom signal handling in the generic event loop at all", over "how to find configuration differences and react on these doing the minimally intrusive thing", to "how to deal with having to close listening sockets in order to open different ones". 🤔

Here's a finished piece of the puzzle related to that sockets topic:

github.com/Zirias/swad/commit/

I already reached a state where I can switch the #TLS #certificate without any service interruption, which was MY main motivation for wanting that feature at all 😎

Путь программиста: в ловушке SRP

Рано или поздно каждый программист должен задуматься о вопросах архитектуры приложения. Архитектура это про выделение ответственностей, определение компонентов их реализующих и связей между ними. Начинается все с ответственностей, а грани тонки. Очень часто будет сложно определить где начинается одна роль и заканчивается другая, сформулировать признаки по которым мы разделяем. Человеку требуются ориентиры, точки опоры и чем проще тем лучше.

habr.com/ru/articles/906242/

#архитектура_приложений #c#net #solid

ХабрПуть программиста: в ловушке SRPРано или поздно каждый программист должен задуматься о вопросах архитектуры приложения. Архитектура это про выделение ответственностей, определение компонентов их реализующих и связей между ними....

I was looking for an alternative to classic shell scripts, so I timed a Hello World program in different languages for fun. I thought you might want to know:

1 ms - #Bash
1 ms - #Perl
12 ms - #Python
33 ms - #Go (shebang calling `go run`)
38 ms - #C (shebang compiling to temporary file)
61 ms - #Rust (shebang compiling to temporary file)

Needless to say that this is a highly unfair and silly comparison. It's still interesting, though.

I'm trying to add "genric" #signal handling to #poser. Ultimate goal is to provide a way for #swad to handle #SIGHUP, although signal handling must be done in poser's main event loop (signals are only ever unblocked while waiting for file descriptor events).

Okay, I could just add explicit handling for SIGHUP. But a generic solution would be nicer. Just for example, a consumer might be interested in #SIGINFO which doesn't even exist on all platforms ... 🤔

Now, #POSIX specs basically just say signal constants are "integer values". Not too helpful here. Is it safe to assume an upper bound for signal numbers on "real world" OS implementations, e.g. 64 like on #Linux? Should I check #NSIG and, if not defined, just define it to 64? 🙈

Regarding my #async / #await "imitation" for #C, I already mentioned it requires the (unfortunately deprecated) #POSIX user context switching (#getcontext, #swapcontext, ...). I check availability in the build. The fallback is an implementation that blocks a worker #thread while awaiting an async task.

Now, one of the systems that doesn't provide the required user context switching is unfortunately #OpenBSD. Does anyone know of a suitable workaround? The requirement is pretty clear: Ability to "put aside" the context of a thread (registers, PC, dedicated #stack, ...) to resume execution later. Implementations following POSIX also save/restore the signal mask, which is a feature I would *not* need.

Any ideas?

404Not Found