Johan511 Blog

volatile specifier

Understanding volatile

Often, during discussions with peers, I notice a common misunderstanding of what the volatile specifier in C++ does, and I hope to clarify it with the following blog post.

References:

Reading an object designated by a volatile glvalue (7.2.1), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment. Evaluation of an expression (or a subexpression) in general includes both value computations (including determining the identity of an object for glvalue evaluation and fetching a value previously assigned to an object for prvalue evaluation) and initiation of side effects. When a call to a library I/O function returns or an access through a volatile glvalue is evaluated the side effect is considered complete, even though some external actions implied by the call (such as the I/O itself) or by the volatile access may not have completed yet.

The following excerpt details that all accesses (reads and writes) to a volatile qualified variable are considered as side-effects, hence qualifying a variable as volatile only disables compiler optimizations on reads/write instructions to it. It absolutely doesn’t provide any guarantees on memory ordering of these read and write instructions. The read/write instructions generated would be identical to that of an non volatile qualified variable. At the assembly level there is no notion of which address (or variable) was marked as volatile.

Since volatile read/writes do not have any acquire/release memory ordering. Hence, while reading (without any explicit acquire memory ordering) from an volatile qualified variable, it should be expected that the write (without any explicit release memory ordering) from a different unit of execution might be delayed indefinitely.

NOTE:

  1. These reads/writes need not be from main memory and can be from the local cache.
  2. Casting down a volatile defined variable to a non-volatile variable is UB.

When to use volatile?

Traditionally compilers were built without concurrent programs in mind and often perform optimizations assuming there is no other unit of execution affecting the control flow being analyzed.

Hence, volatile is used when a variable is shared between multiple concurrent units of execution and you don’t need any sort of acquire-release memory ordering.

read more

Inline-Specifier

Understanding Inline

Often, during discussions with peers, I notice a common misunderstanding of what the inline specifier in C++ does, and I hope to clarify it with the following blog post

This post is motivated by a session at my university where the speaker incorrectly claimed that the purpose of the inline specifier is to instruct the compiler to inline a function call.

This blog post is going to delve into how the inline specifier affects the compilation and linking of a function and how it interacts with static and extern

Do note that inline works slightly differently in C and C++, we will be focusing only on C++

References:

Recommended:


read more

GSOC-2023

My Google Summer of Code project was done under the Ste||ar Group organisation. I was working on HPX, a C++ Standard Library for Concurrency and Parallelism. It implements all of the corresponding facilities as defined by the C++ Standard.

read more