0

constvolatile.cpp:91:9: 错误:将 'volatile GENERIC_COMMAND' 作为 'const GENERIC_COMMAND& GENERIC_COMMAND::operator=(const T&) [with T = COMPLETION_WAIT, GENERIC_COMMAND = GENERIC_COMMAND]' 的 'this' 参数传递,丢弃限定符 [-fpermissive]

            #include <iostream>
            using namespace std;

             typedef unsigned int uint32_t;
             typedef unsigned long long  uint64_t;

               union GENERIC_COMMAND
                {
                    struct
                    {
                        uint64_t first_operand  :   60;
                        uint64_t opcode         :   4;
                        uint64_t second_operand :   64;
                    };

                    struct
                    {
                        uint32_t dword1;
                        uint32_t dword2;
                        uint32_t dword3;
                        uint32_t dword4;
                    };

                    struct
                    {
                        uint64_t qword1;
                        uint64_t qword2;
                    };

                    GENERIC_COMMAND() {
                    }
                    GENERIC_COMMAND(volatile const GENERIC_COMMAND&){}

                    template <typename T>
                    volatile GENERIC_COMMAND& operator=(const T& rhs) volatile
                    {
                        this->dword1 = rhs.dword1;
                        this->dword2 = rhs.dword2;
                        this->dword3 = rhs.dword3;
                        this->dword4 = rhs.dword4;
                        return *this;
                    }
                };


             union COMPLETION_WAIT
                {
                    struct
                    {
                        uint64_t s              :   1;
                        uint64_t i              :   1;
                        uint64_t f              :   1;
                        uint64_t store_address  :   49;
                        uint64_t reserved1      :   8;
                        uint64_t opcode         :   4;
                        uint64_t store_data     :   64;
                    };
                    struct
                    {
                        uint32_t dword1;
                        uint32_t dword2;
                        uint32_t dword3;
                        uint32_t dword4;
                    };
                };


             void add_completion_wait_command(uint32_t s, uint32_t i, uint32_t f,
                                    uint64_t store_address, uint64_t store_data,
                                    bool auto_flush)
                {
                    COMPLETION_WAIT command;
                    command.dword1 = 0;     
                    command.dword2 = 0;    
                    command.dword3 = 0;    
                    command.dword4 = 0;     

                    command.s = s;
                    command.i = i;
                    command.f = f;
                    command.store_address = store_address >> 3;
                    command.opcode = 0x1;
                    command.store_data = store_data;

                    GENERIC_COMMAND generic;
                    static_cast<GENERIC_COMMAND>(generic = command);

                }

            main()
            {
                    cout<< "in main"<< endl;
                    volatile GENERIC_COMMAND* A;//this has to be volatile only.
                    COMPLETION_WAIT cw;
                    A = new volatile union GENERIC_COMMAND;
                    static_cast<GENERIC_COMMAND>(A[0] = cw);

            }
4

1 回答 1

3

Your operator= needs to be volatile. Just as a member function needs to be const to be invoked on a const object. If your member function is not volatile, the compiler would optimize its body, which is not what you want for a volatile object. So the language has this useful rule.

It is well known that this error happens even with the implicitly declared operator=, and is documented as one of the incompatibilities to the C language.

EDIT: I would like to mention that the object you assign to is not volatile, so a compiler is free to optimize away operations on it, even if the pointer used to access it has the volatile qualifier. Add volatile to the type of it

new volatile union GENERIC_COMMAND
于 2012-07-24T12:07:51.833 回答