【问题标题】:How do I access a const volatile std::array?如何访问 const volatile std::array?
【发布时间】:2018-08-31 13:18:06
【问题描述】:

我正在尝试创建一个 volatile 数组,我需要使用运算符 [] 访问它。

我找不到对 std::array 执行此操作的方法,但是内置数组可以正常工作。

使用 GCC 8.2.0 如下:

#include <iostream>
#include <array>
int main()
{
    const volatile std::array<int,2> v = {1,2};
    std::cout << v[0] << std::endl ;
}

给予

<source>: In function 'int main()':

<source>:6:21: error: passing 'const volatile std::array<int, 2>' as
'this' argument discards qualifiers [-fpermissive]

 std::cout << v[0] << std::endl ;

                 ^

In file included from <source>:2:

/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/array:185:7: note:
in call to 'constexpr std::array<_Tp, _Nm>::value_type& std::array<_Tp, 
_Nm>::operator[](std::array<_Tp, _Nm>::size_type) [with _Tp = int; long 
unsigned int _Nm = 2; std::array<_Tp, _Nm>::reference = int&; 
std::array<_Tp, _Nm>::value_type = int; std::array<_Tp, _Nm>::size_type = 
long unsigned int]'

   operator[](size_type __n) noexcept

   ^~~~~~~~

Compiler returned: 1

同时

#include <iostream>
int main()
{
    const volatile int v[2] = {1,2};
    std::cout << v[0] << std::endl ;
}

工作得很好。

如何访问 const volatile std::array?

【问题讨论】:

  • 只是出于好奇:为什么需要一个 volatile 数组开始?
  • @BaummitAugen 我正在编写一个代码,该代码需要在编译时使用 std::array 计算一些复杂的东西并调查生成的程序集。我使用 volatile 强制编译器创建 std::array ,即使我不对其执行任何操作。

标签: c++ constants volatile


【解决方案1】:

你没有。

std::array 有两个重载 operator [](size_t)*this 的一种是 const,*this 是非常量的一种。这些都不适合你 - 因为*this 是 const volatile。

如果您使用 const_cast 删除 volatile 限定符,则结果可能会编译,甚至看起来可以工作。然而,实际结果是未定义的行为(因为底层对象实际上是 is volatile);这意味着当您为客户做重要演示时,它将停止工作。

对于语言律师:n4296 是 C++14 之前标准的最后一个委员会草案。第 7.1.6.1 节 [dcl.type.cv] 第 6 段说:

如果尝试通过使用具有非易失性限定类型的泛左值来引用具有易失性限定类型定义的对象,则程序行为是未定义的。

我很确定所有版本的标准中都存在类似的语言。


如果您使用volatile 来支持多线程 - 请不要。它实际上没有帮助。您需要使用std::atomicstd::mutex 来执行此操作。易失性可用于对微处理器地址空间中的特殊寄存器进行建模。

【讨论】:

  • 使用已丢弃 volatile 的引用有什么要求?对于const,只要您从不“修改”对象,您就可以使用该引用,但是volatile 呢?
  • 您介意调整您的第三段,因为使用const_cast 会是一个非常糟糕的主意吗?如果你这样做,我会投赞成票?
  • @Bathsheba - 更好?它的意思是“甚至不要考虑这样做”——但我忘记了大多数人不像我那样对 UB 过敏。
  • @FrançoisAndrieux:呸!在n4296 7.1.6.1 [dcl.type.cv] 第 6 段中明确指出:“如果尝试通过使用带有非volatile 限定类型,程序行为未定义”。我很确定所有版本的标准中都存在类似的语言。
  • @MartinBonner 谢谢。你的答案有效。我知道它很脏,它不适用于可交付代码,只是用于一些复杂编译时算法的实验,在这些实验中我必须使用volatile 在调查程序集时查看一些变量。
【解决方案2】:

const volatile int v[2] 是两个 const volatile ints 的数组,而不是两个 ints 的 const volatile 数组。

使用类似的std::array 编译:

int main()
{
    std::array<const volatile int, 2> w = {1,2};
    std::cout << w[0] << std::endl ;
}

【讨论】:

  • 谢谢。我碰巧有一个函数std::array&lt;double,2&gt; f(),我按以下方式分配const volatile auto x = f();,所以const_cast即使很脏,也更适合我的应用程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2017-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多