Я играл с атомарной реализацией в C++. У меня есть приведенный ниже фрагмент кода из вышеупомянутого сообщения SO:
#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;
}
Когда я пытаюсь скомпилировать с помощью -Wall -Wpedantic -Werror
, используя g++
и clang++
, clang++
компилирует код, а g++
— нет. Ну, конечно, я могу выключить переключатель -Werror
, но хотелось бы понять, не опасен ли приведенный выше код.
Я уже прочитал пару сообщений ([1], [2] и некоторые другие, такие как [3]) и до сих пор не знаю
- если я должен просто игнорировать/отключить предупреждение, или если я должен переписать его, и,
- если я должен переписать его, как я должен внести изменения? Например, я пробовал промежуточный вариант
reinterpret_cast<char &>
, который тоже не сработал.
Буду признателен за любую помощь. Спасибо!
ИЗМЕНИТЬ. Извините, что не поделился нижеследующим:
~> 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
gcc
, @SergeyA. Я немного прочитал тему, может быть, недостаточно. Тем не менее, я знаю, что это начинает происходить, когда срабатывает уровень оптимизации больше 1. Дело в том, что gcc отказывается компилироваться (или, по крайней мере, предупреждает меня о проблеме), тогда как clang молча компилирует при использовании той же оптимизации. уровни. Что касается второй части моего вопроса, я был бы очень признателен, если бы вы дали мне подсказку о том, как переписать вышеуказанную функциональность, не нарушая строгое правило алиасинга. - person Arda Aytekin   schedule 16.03.2018atomic<float>
, по крайней мере, доC++20
, аналогичную той, которая определена в связанном вопросе SO, или той, которая определена в документация по CUDA. Кажется, они тоже нарушают строгое правило псевдонимов. - person Arda Aytekin   schedule 16.03.2018