Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #5354 > unrolled thread

Rationale behind user provided ctor requirement for const objects of non-POD class types

Started byNikos Chantziaras <realnc@arcor.de>
First post2011-05-23 12:07 +0300
Last post2011-05-25 02:37 +0200
Articles 7 — 4 participants

Back to article view | Back to comp.lang.c++


Contents

  Rationale behind user provided ctor requirement for const objects of non-POD class types Nikos Chantziaras <realnc@arcor.de> - 2011-05-23 12:07 +0300
    Re: Rationale behind user provided ctor requirement for const objects of non-POD class types "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-05-23 12:11 +0200
      Re: Rationale behind user provided ctor requirement for const objects of non-POD class types Nikos Chantziaras <realnc@arcor.de> - 2011-05-23 13:32 +0300
        Re: Rationale behind user provided ctor requirement for const objects of non-POD class types "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-05-23 13:36 +0200
          Re: Rationale behind user provided ctor requirement for const objects of non-POD class types "Balog Pal" <pasa@lib.hu> - 2011-05-23 14:44 +0200
            Re: Rationale behind user provided ctor requirement for const objects of non-POD class types Öö Tiib <ootiib@hot.ee> - 2011-05-24 16:04 -0700
              Re: Rationale behind user provided ctor requirement for const objects of non-POD class types "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-05-25 02:37 +0200

#5354 — Rationale behind user provided ctor requirement for const objects of non-POD class types

FromNikos Chantziaras <realnc@arcor.de>
Date2011-05-23 12:07 +0300
SubjectRationale behind user provided ctor requirement for const objects of non-POD class types
Message-ID<ird841$112$1@news.grnet.gr>
(Originally posted to comp.std.c++, but that newsgroup is dead.)

Recently, I've seen a compiler (clang) that will not compile code like this:

   struct A {
         A() {}
   };

   class B {
         A a_;
   };

   int foo()
   {
         const B b;
         return 0;
   }

It will not compile it because 'b' is const B, which does not have a 
user defined ctor.  C++'03 [dcl.init] p9 says:

   If no initializer is specified for an object, and the object
   is of (possibly cv-qualified) non-POD class type (or array
   thereof), the object shall be default-initialized; if the
   object is of const-qualified type, the underlying class type
   shall have a user-declared default constructor.

Why is that?  Why can't a const B constructed the same way as a 
non-const B, using the implicitly defined default constructor?

[toc] | [next] | [standalone]


#5356

From"Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date2011-05-23 12:11 +0200
Message-ID<irdbge$8da$1@dont-email.me>
In reply to#5354
* Nikos Chantziaras, on 23.05.2011 11:07:
> (Originally posted to comp.std.c++, but that newsgroup is dead.)
>
> Recently, I've seen a compiler (clang) that will not compile code like this:
>
>    struct A {
>          A() {}
>    };
>
>    class B {
>          A a_;
>    };
>
>    int foo()
>    {
>          const B b;
>          return 0;
>    }
>
> It will not compile it because 'b' is const B, which does not have a user
> defined ctor.  C++'03 [dcl.init] p9 says:
>
>    If no initializer is specified for an object, and the object
>    is of (possibly cv-qualified) non-POD class type (or array
>    thereof), the object shall be default-initialized; if the
>    object is of const-qualified type, the underlying class type
>    shall have a user-declared default constructor.
>
> Why is that?  Why can't a const B constructed the same way as a non-const B,
> using the implicitly defined default constructor?

Bjarne Stroustrup's "The Design & Evolution of C++" is a good source of answers 
to such questions.

Unfortunately I don't have it.

But often these rationales are nothing but common sense. So I guess if you check 
out D&E, and if it gives a rationale, it will be that

this unchanging "value" shall have been explicitly defined by the source code, 
because generally it makes no sense to /name a value/ and not define that value 
explicitly.

There are times where it might makes sense (if had been allowed) to write e.g.

   int const  someIntValue;

but from the compiler's point of view this seems like the programmer had 
forgotten to supplyh the value to be named, and anyway in such cases it's no big 
hardship to explicitly state what that value is,

   int const  someIntValue = int();

And likewise in your example.


Cheers & hth.,

- Alf

-- 
blog at <url: http://alfps.wordpress.com>

[toc] | [prev] | [next] | [standalone]


#5357

FromNikos Chantziaras <realnc@arcor.de>
Date2011-05-23 13:32 +0300
Message-ID<irdd3g$co2$1@news.grnet.gr>
In reply to#5356
On 05/23/2011 01:11 PM, Alf P. Steinbach /Usenet wrote:
> * Nikos Chantziaras, on 23.05.2011 11:07:
>> [...]
>> C++'03 [dcl.init] p9 says:
>>
>> If no initializer is specified for an object, and the object
>> is of (possibly cv-qualified) non-POD class type (or array
>> thereof), the object shall be default-initialized; if the
>> object is of const-qualified type, the underlying class type
>> shall have a user-declared default constructor.
>>
>> Why is that? Why can't a const B constructed the same way as a
>> non-const B,
>> using the implicitly defined default constructor?
>[...]
> But often these rationales are nothing but common sense. So I guess if
> you check out D&E, and if it gives a rationale, it will be that
> this unchanging "value" shall have been explicitly defined by the source
> code, because generally it makes no sense to /name a value/ and not
> define that value explicitly.
>
> There are times where it might makes sense (if had been allowed) to
> write e.g.
>
> int const someIntValue;
>
> but from the compiler's point of view this seems like the programmer had
> forgotten to supplyh the value to be named, and anyway in such cases
> it's no big hardship to explicitly state what that value is,
>
> int const someIntValue = int();
>
> And likewise in your example.

Good thinking, but it doesn't seem to apply.  Consider this:

   #include <iostream>

   class A {
       int x_;
   public:
       A() : x_(5) { }
       int x() const { return x_; }
   };

   class B: public A { };

   int main()
   {
       const B b;
       std::cout << b.x() << "\n";
   }

With compilers that accept this, the output of the program is "5".  But 
the C++ standard says that it should not be compilable.  In this case 
however, 'b' has a perfectly fine initial state.

Also, let's not forget that an object can have mutable members, so the 
requirement for a user defined ctor for const B makes even less sense.

[toc] | [prev] | [next] | [standalone]


#5358

From"Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date2011-05-23 13:36 +0200
Message-ID<irdgff$5n0$1@dont-email.me>
In reply to#5357
* Nikos Chantziaras, on 23.05.2011 12:32:
> On 05/23/2011 01:11 PM, Alf P. Steinbach /Usenet wrote:
>> * Nikos Chantziaras, on 23.05.2011 11:07:
>>> [...]
>>> C++'03 [dcl.init] p9 says:
>>>
>>> If no initializer is specified for an object, and the object
>>> is of (possibly cv-qualified) non-POD class type (or array
>>> thereof), the object shall be default-initialized; if the
>>> object is of const-qualified type, the underlying class type
>>> shall have a user-declared default constructor.
>>>
>>> Why is that? Why can't a const B constructed the same way as a
>>> non-const B,
>>> using the implicitly defined default constructor?
>> [...]
>> But often these rationales are nothing but common sense. So I guess if
>> you check out D&E, and if it gives a rationale, it will be that
>> this unchanging "value" shall have been explicitly defined by the source
>> code, because generally it makes no sense to /name a value/ and not
>> define that value explicitly.
>>
>> There are times where it might makes sense (if had been allowed) to
>> write e.g.
>>
>> int const someIntValue;
>>
>> but from the compiler's point of view this seems like the programmer had
>> forgotten to supplyh the value to be named, and anyway in such cases
>> it's no big hardship to explicitly state what that value is,
>>
>> int const someIntValue = int();
>>
>> And likewise in your example.
>
> Good thinking, but it doesn't seem to apply.  Consider this:
>
>    #include <iostream>
>
>    class A {
>        int x_;
>    public:
>        A() : x_(5) { }
>        int x() const { return x_; }
>    };
>
>    class B: public A { };
>
>    int main()
>    {
>        const B b;
>        std::cout << b.x() << "\n";
>    }

I think this is completely like the `someIntValue` case. You want any value of 
class `B`, or perhaps the default value. Then for this special case it's no big 
deal to write

   B const b = B();

just as with the `someIntValue`.


> With compilers that accept this, the output of the program is "5".  But the C++
> standard says that it should not be compilable.  In this case however, 'b' has a
> perfectly fine initial state.
>
> Also, let's not forget that an object can have mutable members, so the
> requirement for a user defined ctor for const B makes even less sense.

As I see it mutable members are pretty irrelevant, because their mutability 
should not affect the externally visible state. E.g., a mutable member might be 
used for caching for some costly-to-compute result, for example a matrix 
determinant, but the using code does not see any state change. Thus, declaring a 
`const` object of such a well-designed class is no different; it is conceptually 
to name an unchanging value, which "should" be specified.


Cheers & hth.,

- Alf


-- 
blog at <url: http://alfps.wordpress.com>

[toc] | [prev] | [next] | [standalone]


#5361

From"Balog Pal" <pasa@lib.hu>
Date2011-05-23 14:44 +0200
Message-ID<irdkr1$2cng$1@news.ett.com.ua>
In reply to#5358
"Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
> I think this is completely like the `someIntValue` case. You want any 
> value of class `B`, or perhaps the default value. Then for this special 
> case it's no big deal to write
>
>   B const b = B();

Provided B is copyable :-((.  The "can e declaration" bullshit takes its 
usual toll. Normally you'd say

 B const b();

but that is interpreted as a function.

At least we know the rationalte for that one: inherited from C without 
change. Just like for() scoping this should be revised too.

I tried the b{} form with the code example upstream in current Cameau, no 
luck. Not sure whether it is the mandated behavior or just the brace init is 
not yet implemented.

[toc] | [prev] | [next] | [standalone]


#5462

FromÖö Tiib <ootiib@hot.ee>
Date2011-05-24 16:04 -0700
Message-ID<cbd27800-24ca-4e5a-9e7e-34369de6569e@w10g2000yqa.googlegroups.com>
In reply to#5361
On May 23, 3:44 pm, "Balog Pal" <p...@lib.hu> wrote:
> "Alf P. Steinbach /Usenet" <alf.p.steinbach+use...@gmail.com>
>
> > I think this is completely like the `someIntValue` case. You want any
> > value of class `B`, or perhaps the default value. Then for this special
> > case it's no big deal to write
>
> >   B const b = B();
>
> Provided B is copyable :-((.  The "can e declaration" bullshit takes its
> usual toll. Normally you'd say
>
>  B const b();
>
> but that is interpreted as a function.

So you need non-copyable, immutable and default-constructed instance.

If such need is common then the class may be made to provide reference
to one with a static member function. I sometimes do it for "null"
objects.

 B const& b = B::none();

If you really need separate instance (why?) then aren't there some
syntax that will be not interpreted as function like 'B const b(());'
or something?

[toc] | [prev] | [next] | [standalone]


#5470

From"Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date2011-05-25 02:37 +0200
Message-ID<irhii8$hul$1@dont-email.me>
In reply to#5462
* Öö Tiib, on 25.05.2011 01:04:
> On May 23, 3:44 pm, "Balog Pal"<p...@lib.hu>  wrote:
>> "Alf P. Steinbach /Usenet"<alf.p.steinbach+use...@gmail.com>
>>
>>> I think this is completely like the `someIntValue` case. You want any
>>> value of class `B`, or perhaps the default value. Then for this special
>>> case it's no big deal to write
>>
>>>    B const b = B();
>>
>> Provided B is copyable :-((.  The "can e declaration" bullshit takes its
>> usual toll. Normally you'd say
>>
>>   B const b();
>>
>> but that is interpreted as a function.
>
> So you need non-copyable, immutable and default-constructed instance.
>
> If such need is common then the class may be made to provide reference
> to one with a static member function. I sometimes do it for "null"
> objects.
>
>   B const&  b = B::none();
>
> If you really need separate instance (why?) then aren't there some
> syntax that will be not interpreted as function like 'B const b(());'
> or something?

I think that with C++03 rules

   B const& b = B();

should do it, while with C++98 this would (as I recall) require a copy 
constructor to be accessible.

But I don't have time to check out the standard, sorry.


Cheers,

- Alf

-- 
blog at <url: http://alfps.wordpress.com>

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web