Topic: Initialization of aggregates with const members


Author: iltchenko@yahoo.com (Andrei Iltchenko)
Date: Mon, 30 Jul 2001 17:29:14 GMT
Raw View
Greg Chicares <chicares@mindspring.com> wrote in message news:<3B6374D7.BEF8533B@mindspring.com>...

> In this example, does either foo or bar require a constructor?

The code below does not use (3.2/2) the implicitly-declared dafault
constructors of the classes 'foo' and 'bar'.


>   union foo
>   {
>     int  const x;
>     char y;
>   };
>
>   struct bar
>   {
>     int  const x;
>     char y;
>   };
>
>   int main()
>   {
>     foo f = {1};
>     bar b = {1};
>     return f.x + b.x;
>   }
>
>   gcc-2.95.2 -Wall -ansi -pedantic accepts the code
>   gcc-3_0-branch of CVS agrees with that
>   borland 5.5.1 -w -A rejects it:
>     Error Constant member 'foo::x' in class without constructors
>     Error Constant member 'bar::x' in class without constructors
>   comeau 4.2.45.2 accepts it with the warning
>     class "bar" defines no constructor to initialize the following:
>       const member "bar::x"
>     In strict mode, without -tused, Compile succeeded
>
> I reason as follows that this program is strictly conforming; have
> I got this right?

Yeah! The program is strictly conforming and bcc32 5.5.1 is at fault
terminating the translation. An aggrigate or a POD class type may have
a const-qualified non-static data member. You can also take a look at
the thread "memcpy to POD with const member" that took place on this
news group and where similar issues where touched upon.


> foo and bar are both aggregates, so it is OK to initialize both with
> brace-enclosed initializer-clauses [8.5.1/2], in which case ctors are
> not considered [8.5/14].

Correct, the constructors are not used.


> I tried making a case that ctors are required, but it seems invalid:
>
> A default ctor is implicitly declared [12.1/5] as if it were written
>
>   inline foo::foo()
>     // empty mem-initializer-list
>   {
>     // empty function body
>   }
>
> x and y are nonstatic data members not named by a mem-initializer-id
> because there is no ctor-initializer. Neither is of class type, but
> both are of const type--so the default ctor would be ill formed if
> user-written [12.6.2/4].
>
> Therefore, the program would be ill formed [12.1/7] if the default
> ctor were defined, but it is (implicitly) defined only when it is
> used--and yet it is not used. So I don't think that argument valid.

Correct.


Regards,

Andrei Iltchenko.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Matvei Brodski <mbrodski@bear.nospam.com>
Date: Mon, 30 Jul 2001 18:02:46 GMT
Raw View
Greg Chicares wrote:

[snip]

>   struct bar
>   {
>     int  const x;
>     char y;
>   };

[snip]


> x and y are nonstatic data members not named by a mem-initializer-id
> because there is no ctor-initializer. Neither is of class type, but
> both are of const type--so the default ctor would be ill formed if
> user-written [12.6.2/4].

What do you mean - ill formed?
I can write a default ctor for bar:

bar::bar() : x(0), y('a') {}

What am I missing?

Matvei.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Greg Chicares <chicares@mindspring.com>
Date: Tue, 31 Jul 2001 00:18:01 GMT
Raw View
Matvei Brodski wrote:
>
> Greg Chicares wrote:
>
> [snip]
>
> >   struct bar
> >   {
> >     int  const x;
> >     char y;
> >   };
>
> [snip]
>
> > x and y are nonstatic data members not named by a mem-initializer-id
> > because there is no ctor-initializer. Neither is of class type, but
> > both are of const type--so the default ctor would be ill formed if
> > user-written [12.6.2/4].
>
> What do you mean - ill formed?
> I can write a default ctor for bar:
>
> bar::bar() : x(0), y('a') {}

Indeed you could write that. That would be OK.

> What am I missing?

Instead of

> > so the default ctor would be ill formed if user-written [12.6.2/4].

I might more clearly have said:

There is no user-declared constructor for class bar, so a default
constructor is implicitly declared. If that implicitly-declared
constructor ever were implicitly defined, it would look like

  inline foo::foo()
    // empty mem-initializer-list
  {
    // empty function body
  }

which would be ill-formed due to the const data member [12.6.2/4]:

  If a given nonstatic data member or base class is not named by a
  mem-initializer-id (including the case where there is no
  mem-initializer-list because the constructor has no
  ctor-initializer), then [...] if the entity is of const-qualified
  type [...], the program is ill-formed.

But that implicitly-declared constructor is not implicitly defined,
so that rule is not violated.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Greg Chicares <chicares@mindspring.com>
Date: Sun, 29 Jul 2001 11:42:16 GMT
Raw View
In this example, does either foo or bar require a constructor?

  union foo
  {
    int  const x;
    char y;
  };

  struct bar
  {
    int  const x;
    char y;
  };

  int main()
  {
    foo f = {1};
    bar b = {1};
    return f.x + b.x;
  }

  gcc-2.95.2 -Wall -ansi -pedantic accepts the code
  gcc-3_0-branch of CVS agrees with that
  borland 5.5.1 -w -A rejects it:
    Error Constant member 'foo::x' in class without constructors
    Error Constant member 'bar::x' in class without constructors
  comeau 4.2.45.2 accepts it with the warning
    class "bar" defines no constructor to initialize the following:
      const member "bar::x"
    In strict mode, without -tused, Compile succeeded

I reason as follows that this program is strictly conforming; have
I got this right?

foo and bar are both aggregates, so it is OK to initialize both with
brace-enclosed initializer-clauses [8.5.1/2], in which case ctors are
not considered [8.5/14].

I tried making a case that ctors are required, but it seems invalid:

A default ctor is implicitly declared [12.1/5] as if it were written

  inline foo::foo()
    // empty mem-initializer-list
  {
    // empty function body
  }

x and y are nonstatic data members not named by a mem-initializer-id
because there is no ctor-initializer. Neither is of class type, but
both are of const type--so the default ctor would be ill formed if
user-written [12.6.2/4].

Therefore, the program would be ill formed [12.1/7] if the default
ctor were defined, but it is (implicitly) defined only when it is
used--and yet it is not used. So I don't think that argument valid.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]