I was playing around with the atomic implementation in C++. I have the below code excerpt from the aforementioned SO post:
#include <atomic>
#include <cstdint>
#include <iostream>
template <class value_t, class block_t> struct my_atomic {
using value_type = value_t;
using difference_type = value_type;
my_atomic() noexcept = default;
constexpr my_atomic(value_t desired) noexcept
: value(reinterpret_cast<block_t &>(desired)) {}
my_atomic(const my_atomic &) = delete;
my_atomic &operator=(const my_atomic &) = delete;
my_atomic &operator=(const my_atomic &) volatile = delete;
operator value_t() const noexcept {
const block_t value = this->value;
return reinterpret_cast<const value_t &>(value);
}
operator value_t() const volatile noexcept {
const block_t value = this->value;
return reinterpret_cast<const value_t &>(value);
}
private:
std::atomic<block_t> value;
};
using my_atomic_float = my_atomic<float, std::uint32_t>;
int main() {
my_atomic_float var{5};
float result = 5 * var;
std::cout << "result: " << result << '\n';
return 0;
}
When I try to compile with -Wall -Wpedantic -Werror
using g++
and clang++
, clang++
compiles the code whereas g++
does not. Well, of course, I can turn off the -Werror
switch, but I would like to understand if the above code is dangerous.
I have already read a couple of posts ([1], [2], and some others like [3]) and still don't know
- if I should just ignore/disable the warning, or if I should rewrite it, and,
- if I should rewrite it, how should I make a change? I have tried an intermediate
reinterpret_cast<char &>
, for instance, which did not work, either.
I would appreciate any help. Thanks!
EDIT. Sorry for not sharing the below:
~> g++ --version
g++ (GCC) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
~> g++ -Wall -Wpedantic -Werror -std=c++14 -O3 question.cpp -o question.out
question.cpp: In instantiation of ‘constexpr my_atomic<value_t, block_t>::my_atomic(value_t) [with value_t = float; block_t = unsigned int]’:
question.cpp:33:24: required from here
question.cpp:11:15: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
: value(reinterpret_cast<block_t &>(desired)) {}
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
question.cpp: In instantiation of ‘my_atomic<value_t, block_t>::operator value_t() const [with value_t = float; block_t = unsigned int]’:
question.cpp:34:22: required from here
question.cpp:19:12: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
return reinterpret_cast<const value_t &>(value);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
~> clang++ --version
clang version 5.0.1 (tags/RELEASE_501/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin