解除引用类型惩罚指针

时间:2018-03-16 13:40:52

标签: c++ reinterpret-cast strict-aliasing

我正在玩C ++中的atomic implementation。我在上面提到的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 -Werrorg++使用clang++进行编译时,clang++会编译代码,而g++则不会。好吧,当然,我可以关闭-Werror开关,但我想了解上述代码是否有危险。

我已经阅读了几篇帖子([1][2]和其他一些帖子,例如[3]),但仍然不知道

  1. 如果我应该忽略/禁用警告,或者我应该重写它,
  2. 如果我要改写它,我应该如何改变?例如,我尝试过一个中间版reinterpret_cast<char &>,它也不起作用。
  3. 我将不胜感激任何帮助。谢谢!

    编辑。很抱歉不共享以下内容:

    ~> 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
    

0 个答案:

没有答案