CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Jul 2012
    Posts
    7

    Question Error when using volatile object in overload assignment operator.

    /*using GENERIC_COMMAND* A; as volatile generates error. but here i have to use union object as volatile i.e. volatile GENERIC_COMMAND* A; */

    #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;
    };

    template <typename T>
    const GENERIC_COMMAND& operator=(const T& rhs)
    {
    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;
    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;
    A[0] = cw;
    //....
    }

  2. #2
    Join Date
    Dec 2009
    Posts
    145

    Re: Error when using volatile object in overload assignment operator.

    I don't understand why you wrap up your structs like above but your definition of how many bytes to use for a particular object shows your misunderstandings of structure memory layout. I used to have an interview with 4x year old project manager of a UK company and he made me laugh for his naive calculation of byte numbers being used after such a struct definition (as he claimed to be the sum of all object inside the struct), I wasn't the question maker or one with a final decision to report true or false, I was pretty much insulted of my C/C++ skills as if his embedded C knowledge were always up to date with old UK instruments. But that helps me conclude myself that whenever I meet anyone who asked me to write down clearly every single line of code to i.e traverse a tree, then I do believe this guy is just good enough to be my yoga or gym teacher.
    Back to your problem, your client stub doesn't make any sense out of volatile main usage. There is nothing that says your unions can not be modified and needs the keyword to redefine the situation; and concurrency is not easily resolved in just a single keyword if you would want to make your system more robust with full features of qualified software. Many people prefer a vector in place of an array (pointer).

  3. #3
    Join Date
    Jul 2012
    Posts
    7

    Re: Error when using volatile object in overload assignment operator.

    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;
    }

    using above assignment operator i could able to resolve error, but still i see warnings.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Error when using volatile object in overload assignment operator.

    Quote Originally Posted by ritulguru View Post
    /*using GENERIC_COMMAND* A; as volatile generates error. but here i have to use union object as volatile i.e. volatile GENERIC_COMMAND* A; */
    First, please use code tags when posting code. The code you posted is almost unreadable.
    Code:
    #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;
            };
    
            template <typename T>
            const GENERIC_COMMAND& operator=(const T& rhs)
            {
                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;
            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;
            A[0] = cw;
    		//....
    }
    See what code tags do for you?

    Secondly, I took the code you posted and attempted to compile it using the online Comeau C++ compiler. It fails to compile:
    Code:
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 9: error: declaration does not declare anything
              struct
              ^
    
    "ComeauTest.c", line 16: error: declaration does not declare anything
              struct
              ^
    
    "ComeauTest.c", line 24: error: declaration does not declare anything
              struct
              ^
    
    "ComeauTest.c", line 33: error: union "GENERIC_COMMAND" has no member "dword1"
                  this->dword1 = rhs.dword1;
                        ^
    
    "ComeauTest.c", line 34: error: union "GENERIC_COMMAND" has no member "dword2"
                  this->dword2 = rhs.dword2;
                        ^
    
    "ComeauTest.c", line 35: error: union "GENERIC_COMMAND" has no member "dword3"
                  this->dword3 = rhs.dword3;
                        ^
    
    "ComeauTest.c", line 36: error: union "GENERIC_COMMAND" has no member "dword4"
                  this->dword4 = rhs.dword4;
                        ^
    
    "ComeauTest.c", line 44: error: declaration does not declare anything
              struct
              ^
    
    "ComeauTest.c", line 54: error: declaration does not declare anything
              struct
              ^
    
    "ComeauTest.c", line 69: error: union "COMPLETION_WAIT" has no member "dword1"
              command.dword1 = 0;     
                      ^
    
    "ComeauTest.c", line 70: error: union "COMPLETION_WAIT" has no member "dword2"
              command.dword2 = 0;    
                      ^
    
    "ComeauTest.c", line 71: error: union "COMPLETION_WAIT" has no member "dword3"
              command.dword3 = 0;    
                      ^
    
    "ComeauTest.c", line 72: error: union "COMPLETION_WAIT" has no member "dword4"
              command.dword4 = 0;     
                      ^
    
    "ComeauTest.c", line 74: error: union "COMPLETION_WAIT" has no member "s"
              command.s = s;
                      ^
    
    "ComeauTest.c", line 75: error: union "COMPLETION_WAIT" has no member "i"
              command.i = i;
                      ^
    
    "ComeauTest.c", line 76: error: union "COMPLETION_WAIT" has no member "f"
              command.f = f;
                      ^
    
    "ComeauTest.c", line 77: error: union "COMPLETION_WAIT" has no member
              "store_address"
              command.store_address = store_address >> 3;
                      ^
    
    "ComeauTest.c", line 78: error: union "COMPLETION_WAIT" has no member "opcode"
              command.opcode = 0x1;
                      ^
    
    "ComeauTest.c", line 79: error: union "COMPLETION_WAIT" has no member "store_data"
              command.store_data = store_data;
                      ^
    
    "ComeauTest.c", line 33: error: union "COMPLETION_WAIT" has no member "dword1"
                  this->dword1 = rhs.dword1;
                                     ^
              detected during instantiation of "const GENERIC_COMMAND
                        &GENERIC_COMMAND::operator=(const T &) [with
                        T=COMPLETION_WAIT]" at line 82
    
    "ComeauTest.c", line 34: error: union "COMPLETION_WAIT" has no member "dword2"
                  this->dword2 = rhs.dword2;
                                     ^
              detected during instantiation of "const GENERIC_COMMAND
                        &GENERIC_COMMAND::operator=(const T &) [with
                        T=COMPLETION_WAIT]" at line 82
    
    "ComeauTest.c", line 35: error: union "COMPLETION_WAIT" has no member "dword3"
                  this->dword3 = rhs.dword3;
                                     ^
              detected during instantiation of "const GENERIC_COMMAND
                        &GENERIC_COMMAND::operator=(const T &) [with
                        T=COMPLETION_WAIT]" at line 82
    
    "ComeauTest.c", line 36: error: union "COMPLETION_WAIT" has no member "dword4"
                  this->dword4 = rhs.dword4;
                                     ^
              detected during instantiation of "const GENERIC_COMMAND
                        &GENERIC_COMMAND::operator=(const T &) [with
                        T=COMPLETION_WAIT]" at line 82
    
    "ComeauTest.c", line 92: error: no operator "=" matches these operands
                operand types are: volatile GENERIC_COMMAND = COMPLETION_WAIT
              A[0] = cw;
                   ^
    
    24 errors detected in the compilation of "ComeauTest.c".
    
    In strict mode, with -tused, Compile failed
    Hit the Back Button to review your code and compile options.
    Compiled with C++0x extensions enabled.
    What compiler are you using?

    Let's do something simple:
    Code:
    union foo
    {
        struct s1
        {
            int m_x;
        };
    
        struct s2
        {
            int m_x2;
        };
        s1 m_s1;
        s2 m_s2;
    };
    
    int main()
    {
        foo f;
        f.m_s1.m_x = 0;
    }
    Look at what's in red. You are missing declaring actual instances of your structs. You can't just declare structs -- you must actually create them. Given this, I don't see how your code would have compiled under any C++ compiler.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; July 27th, 2012 at 06:46 AM.

  5. #5
    Join Date
    Jul 2012
    Posts
    7

    Re: Error when using volatile object in overload assignment operator.

    thanks for mentioning that.
    I am using g++ compiler. I have tried running the same on DEV C++ 4.9.9.2 bloodshed.
    I do not get any warning which you are getting.
    Sorry, I am not familiar to Comeau C++ compiler.
    You can try this code on either g++(linux) or Dev C++(windows).

  6. #6
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Error when using volatile object in overload assignment operator.

    >> //this has to be volatile only.
    No, it doesn't. What makes you think it does?

    gg

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Error when using volatile object in overload assignment operator.

    Quote Originally Posted by ritulguru View Post
    thanks for mentioning that.
    I am using g++ compiler. I have tried running the same on DEV C++ 4.9.9.2 bloodshed.
    Turn on the ANSI switch and you will see the same errors.
    Code:
    -Wall -pedantic
    I believe those are the switches for g++.

    The problem is that by default, the g++ compiler will compile non-standard C++ code. If you turn on the ANSI compiler switch, you will see the same errors I'm seeing now. The code you posted is not ANSI C++, it is C++ with compiler extensions that are non-standard. Once you start using extensions, then all bets are off as to how your code will behave (then it's your responsibility to read the manual).
    I do not get any warning which you are getting.
    Turn on the ANSI switch and you will get the errors with the g++ compiler. The g++ compiler must be able to compile C++ code without any extensions (and if extensions are used, it must emit an error), else it can't claim to be an ANSI C++ compiler.
    Sorry, I am not familiar to Comeau C++ compiler.
    It is an online, ANSI C++ compiler. If the code fails to compile on that compiler, chances are great that the code is not compliant. Many professional C++ programmers who want to test if their code is compliant go to the on-line Comeau compiler to test their code. Obviously your code is not compliant.
    You can try this code on either g++(linux) or Dev C++(windows).
    No need to. I know if I set the right switches, the code will fail to compile. And BTW, the Dev C++ is not a compiler -- it uses g++ 3.x underneath the hood, so you see the same issues with both g++ under Linux and g++ using Dev-C++.

    Here is the code that must compile with all ANSI C++ compilers.
    Code:
    #include <iostream>
    using namespace std;
    
     typedef unsigned int uint32_t;
     typedef unsigned long long  uint64_t;
    
       union GENERIC_COMMAND
        {
            struct s1
            {
                uint64_t first_operand  :   60;
                uint64_t opcode         :   4;
                uint64_t second_operand :   64;
            };
    
            struct s2
            {
                uint32_t dword1;
                uint32_t dword2;
                uint32_t dword3;
                uint32_t dword4;
            };
    
            struct s3
            {
                uint64_t qword1;
                uint64_t qword2;
            };
    
            s1 m_s1;
            s2 m_s2;
            s3 m_s3;
    
            template <typename T>
            const GENERIC_COMMAND& operator=(const T& rhs)
            {
                m_s2.dword1 = rhs.m_s2.dword1;
                m_s2.dword2 = rhs.m_s2.dword2;
                m_s2.dword3 = rhs.m_s2.dword3;
                m_s2.dword4 = rhs.m_s2.dword4;
                return *this;
            }
        };
    
     
     union COMPLETION_WAIT
        {
            struct s1
            {
                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 s2
            {
                uint32_t dword1;
                uint32_t dword2;
                uint32_t dword3;
                uint32_t dword4;
            };
            s1 m_s1;
            s2 m_s2;
        };
    
     
     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.m_s2.dword1 = 0;     
            command.m_s2.dword2 = 0;    
            command.m_s2.dword3 = 0;    
            command.m_s2.dword4 = 0;     
    
            command.m_s1.s = s;
            command.m_s1.i = i;
            command.m_s1.f = f;
            command.m_s1.store_address = store_address >> 3;
            command.m_s1.opcode = 0x1;
            command.m_s1.store_data = store_data;
    
            GENERIC_COMMAND generic;
            generic = command;
           
        }
    
    int main()
    {
        cout<< "in main"<< endl;
        GENERIC_COMMAND* A;
        COMPLETION_WAIT cw;
        A = new union GENERIC_COMMAND;
        A[0] = cw;
        //....
    }
    As you can see, there is no need for volatile. Maybe you believed that you needed volatile since you used all of that non-standard syntax.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; July 27th, 2012 at 10:37 AM. Reason: Corrected the g++ compiler switches

  8. #8
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Error when using volatile object in overload assignment operator.

    Quote Originally Posted by Paul McKenzie
    Code:
    -Wall -pendantic
    I believe those are the switches for g++.
    To be pedantic, -pendantic should be -pedantic
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Error when using volatile object in overload assignment operator.

    Quote Originally Posted by laserlight View Post
    To be pedantic, -pendantic should be -pedantic
    Yep, you're right.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Jul 2012
    Posts
    7

    Re: Error when using volatile object in overload assignment operator.

    @Paul: I have to use a pointer to volatile object, as memory allocation function i am using (which is not mentioned here) returns pointer to volatile object.
    before it was getting compiled without volatile qualifier, problem introduced after adding volatile qualifier.

    After compiling with options -Wall -pedantic, i do get below warnings.
    warning: ISO C++ prohibits anonymous structs.
    thanks for mentioning this.

  11. #11
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Error when using volatile object in overload assignment operator.

    >> memory allocation function i am using returns pointer to volatile object.
    Why does it return pointer to volatile? Is it memory mapped I/O?

    You can use const_cast<>() to remove the volatile qualification if you can't fix the API.

    gg

  12. #12
    Join Date
    Jul 2012
    Posts
    7

    Re: Error when using volatile object in overload assignment operator.

    yes, it is mmapIO.
    if i have to use volatile, then how can i use it properly without any warnings?

  13. #13
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Error when using volatile object in overload assignment operator.

    >> yes, it is mmapIO
    Out of curiosity, what platform will this be running on? What I/O is this memory mapped to?

    >> how can i use it properly without any warnings?
    If you post the code being compile and the warning that is given, we can help.

    gg

  14. #14
    Join Date
    Jul 2012
    Posts
    7

    Re: Error when using volatile object in overload assignment operator.

    constvolatile.cpp: In function ‘void add(uint32_t, uint32_t, uint32_t, uint64_t, uint64_t, bool)’:
    constvolatile.cpp:82: warning: object of type ‘volatile GENERIC_COMMAND&’ will not be accessed in statement
    constvolatile.cpp: In function ‘int main()’:
    constvolatile.cpp:93: warning: object of type ‘volatile GENERIC_COMMAND&’ will not be accessed in statement
    ritul@ritul-laptop:~/Desktop$

    line:82: generic = command;
    line:93: A[0] = cw;

  15. #15
    Join Date
    Jul 2012
    Posts
    7

    Re: Error when using volatile object in overload assignment operator.

    used static_cast<> and copy constructor to remove warning that volatile object will not be accessed by implicit reference.
    Code:
    #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() {
    			cout << "constructor." << endl;
    		}
    		GENERIC_COMMAND(volatile const GENERIC_COMMAND&) {
    			cout << "copy constructor." << endl;
    		}
    
    		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;
    		//generic = command;
    		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);//this will remove the warning that volatile object can not be accessed by implicit reference.
    	}

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured