Как мне получить доступ к const volatile std :: array? - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь создать энергозависимый массив, и мне нужно получить к нему доступ с помощью оператора [].

Я не нахожу способа сделать это для 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?

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

const volatile int v[2] является массивом из двух постоянных энергозависимых int с, а не постоянным массивом из двух int с.

Использование аналогичных std::array компиляций:

int main()
{
    std::array<const volatile int, 2> w = {1,2};
    std::cout << w[0] << std::endl ;
}
0 голосов
/ 31 августа 2018

Вы не.

std::array имеет две перегрузки operator [](size_t). Один для *this является константным, один, если *this не является константным. Ни один из них не будет работать для вас - потому что *this постоянно изменчив.

Если вы используете const_cast для удаления изменяемого квалификатора, результат, вероятно, скомпилируется, и может даже показаться, что он работает. Однако фактический результат - неопределенное поведение (потому что базовый объект на самом деле является volatile); это означает, что он перестанет работать, когда вы придете к важной демонстрации для клиента.

Для языковых юристов: n4296 - последний проект стандарта комитета до C ++ 14. Раздел 7.1.6.1 [dcl.type.cv] пункт 6 гласит:

Если предпринята попытка обратиться к объекту, определенному с типом, определенным с помощью volatile, с использованием glvalue с типом, не определенным с помощью volatile, поведение программы не определено ".

Я почти уверен, что подобный язык существует во всех версиях стандарта.


Если вы используете volatile для поддержки многопоточности - не надо. Это на самом деле не помогает. Вам нужно использовать std::atomic или std::mutex, чтобы сделать это. Volatile полезно для моделирования специальных регистров в адресном пространстве микропроцессора.

...