user1174114
user1174114

Reputation: 188

what is wrong in this code? I have to use a volatile pointer to union, which gives error in operator overloading =

constvolatile.cpp:91:9: error: passing âvolatile GENERIC_COMMANDâ as âthisâ argument of âconst GENERIC_COMMAND& GENERIC_COMMAND::operator=(const T&) [with T = COMPLETION_WAIT, GENERIC_COMMAND = GENERIC_COMMAND]â discards qualifiers [-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);

            }

Upvotes: 0

Views: 1083

Answers (1)

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507185

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

Upvotes: 3

Related Questions