diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 6ef1947..6711967 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -9383,15 +9383,39 @@ See also: It is hard to be certain that concurrency isn't used now or sometime in the future. Code gets re-used. Libraries using threads my be used from some other part of the program. +Note that this applies most urgently to library code and least urgently to stand-alone applications. ##### Example - ??? + double cached_computation(double x) + { + static double cached_x = 0.0; + static double cached_result = COMPUTATION_OF_ZERO; + double result; + + if (cached_x = x) + return cached_result; + result = computation(x); + cached_x = x; + cached_result = result; + return result; + } + +Although `cached_computation` works perfectly in a single-threaded environment, in a multi-threaded environment the two `static` variables result in data races and thus undefined behavior. + +There are several ways that this example could be made safe for a multi-threaded environment: +* Delegate concurrency concerns upwards to the caller. +* Mark the `static` variables as `thread_local` (which might make caching less effective). +* Implement concurrency control, for example, protecting the two `static` variables with a `static` lock (which might reduce performance). +* Have the caller provide the memory to be used for the cache, thereby delegating both memory allocation and concurrency concerns upwards to the caller. +* Refuse to build and/or run in a multi-threaded environment. +* Provide two implementations, one which is used in single-threaded environments and another which is used in multi-threaded environments. **Exception**: There are examples where code will never be run in a multi-threaded environment. However, there are also many examples where code that was "known" to never run in a multi-threaded program was run as part of a multi-threaded program. Often years later. Typically, such programs lead to a painful effort to remove data races. +Therefore, code that is never intended to run in a multi-threaded environment should be clearly labeled as such. ### CP.2: Avoid data races