[MS] Comparing exception behavior of magic statics, std::call_once , and std::async - devamazonaws.blogspot.com
We've been comparing magic statics, std::, and std::, but one thing we haven't considered is their behavior in the event of an exception.
For magic statics, if an exception occurs during initialization of the static, then the static is considered not to have been initialized. The exception propagates, and the next time the function is called, the language will try to initialize the static again.
For call_, if an exception occurs during execution of the lambda, then the call is considered not to have occurred. The exception propagates, so the next time you call call_ with the same once_, it will try to call it.
But std:: is different. If an exception occurs during execution of the invocable, then the exception is saved, and when you ask the future or shared future for the result, the exception is rethrown. It does not try to execute the invocable again.
Let's summarize this in a table.
| Before | After success | After exception | |
|---|---|---|---|
| Magic static | Uninitialized | Initialized | Uninitialized |
| std:: |
Uninitialized | Initialized | Uninitialized |
| std:: |
Uninitialized | Initialized | Failed |
Or we can do it in a state diagram.
| magic static fail call_once fail ⮏ |
async fail | |
| Uninitialized | → | Failed |
| ↓ success | ||
| Initialized |
Going back to the choice between std:: and std::, you have to think about what you want to happen if an exception occurs while trying to initialize the variable. If you want to try again, then use std::. If you want to remember the failure and keep rethrowing it, then use std::.
If you are indifferent, then I would suggest std::, because it is much lighter weight.
Post Updated on September 18, 2026 at 03:00PM
Thanks for reading
from devamazonaws.blogspot.com
Comments
Post a Comment