Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutable anonymous struct

I want to define an aggregate with a number of mutable fields (to save it in std::set or std::priority_queue and modify it in future, surely saving the container invariants). I tried the following syntax and it was compiled successfully:

#include <cstdlib>

int
main()
{
    struct X
    {
        mutable struct 
        {
            int i;
            int j;            
        };
    };
    X const x{};
    //x.i = 1;
    return EXIT_SUCCESS;
}

Live example for clang 3.8.

But statement x.i = 1; gives an error:

error: cannot assign to variable 'x' with const-qualified type 'const X'

My intention was to group a plenty of sequential fileds and apply mutable keyword to the group.

Is this syntax wrong? If so, what is an intention of compiler makers to allow such a syntax if any?

ADDITIONAL:

Code:

#include <cstdlib>

int
main()
{
    struct X
    {
        mutable struct 
        {
            int i;
            int j;            
        };
        void f() const { i = 1; }
    };
    X const x{};
    //x.i = 1;
    x.f();
    return EXIT_SUCCESS;
}

gives an error too:

error: cannot assign to non-static data member within const member function 'f'

note: member function 'main()::X::f' is declared const here void f() const { i = 1; }

like image 743
Tomilov Anatoliy Avatar asked Oct 29 '25 07:10

Tomilov Anatoliy


1 Answers

The trouble comes from the mix between the non-standard (in C++) usage of anonymous struct together with the mutable. The latter is a storage class specifier that is meant to be used for members and not for types.

Alternative 1: define an intermediate member for your anonymous struct:

You can define a member that will then be mutable, according to the rules of standard C++:

struct X
{
    mutable struct 
    {
        int i;
        int j;            
    } y;
};
X const x{};
x.y.i = 1;

Live demo

Alternative 2: make every members in the anonymous struct mutable:

You can otherwise define the members within the struct as being mutable. As the anonymous struct merges these members into the enclosing struct, the mutable property will be passed on:

struct X
{
    struct 
    {
        mutable int i;
        mutable int j;            
    };
};

Online demo

What does the standard say ?

The standatad C++ doen't allow anonymous struct. Anonymous struct is a compiler extension for C11 compatibility.

The C++ standard allows however anonymous unions. But it sets restrictions, notably:

9.5/6: A storage class is not allowed in a declaration of an anonymous union in a class scope.

So when compiling the following code:

  struct X
    {
        mutable union 
        {
            int i;
            int j;            
        };
    }; 

the compiler shall and will issue a very specific error:

prog.cpp:11:13: error: a storage class on an anonymous aggregate in class  scope is not allowed
         mutable union 

I think that it is not consistent to allow using a storage class specifier on an anonymous struct (and apparently ignoring it) and to issues an error for an anonymous union. According to me, this shall be reported as a compiler bug. In anycase, you should adopt alternative 1 (portable & compliant) or alternative 2 (compiler dependent, but more consistent with the standard).

like image 193
Christophe Avatar answered Oct 31 '25 11:10

Christophe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!