Topic: Can complete objects be disjoint


Author: Francis Glassborow <francis.glassborow@btinternet.com>
Date: Tue, 11 Jan 2011 10:04:10 CST
Raw View

Elsewhere (alt.comp.lang.learn.c-c++ a respected poster claims that the
Standard allows complete objects to be disjoint. There is no
disagreement that subobjects can be disjoint (essential to support
virtual inheritance.) However it is my claim that complete objects must
occupy a single contiguous region of storage. Yes member pointers and
references can point/refer to objects elsewhere but those are not a
direct part of a complete object. I do have some reservations about
references but I think that in this aspect they should be consider in
the same way that we consider pointers. I am open to persuasion on that
issue.

Now my main piece of 'evidence' is illustrated by this code:

template<typename T>
void foo(int n){
   T array[n];
   std::cout << sizeof(array)/sizeof(T) << std::endl:
}

I believe that calling this function must result in the value of n being
output. If I am mistaken in this belief please enlighten me.

However if I am correct, I cannot see how a standard conforming program
can have a type that that is disjoint.

The simple question is:

Can a complete C++ object (other languages define objects in other ways)
have a disjoint region of storage.

Thanks in advance for taking time to consider this question

A happy and prosperous 2011 to all.

Francis


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Leigh Johnston <leigh@i42.co.uk>
Date: Tue, 11 Jan 2011 11:40:12 CST
Raw View
On 11/01/2011 16:04, Francis Glassborow wrote:
>
>
> Elsewhere (alt.comp.lang.learn.c-c++ a respected poster claims that the
> Standard allows complete objects to be disjoint. There is no
> disagreement that subobjects can be disjoint (essential to support
> virtual inheritance.) However it is my claim that complete objects must
> occupy a single contiguous region of storage. Yes member pointers and
> references can point/refer to objects elsewhere but those are not a
> direct part of a complete object. I do have some reservations about
> references but I think that in this aspect they should be consider in
> the same way that we consider pointers. I am open to persuasion on that
> issue.
>
> Now my main piece of 'evidence' is illustrated by this code:
>
> template<typename T>
> void foo(int n){
> T array[n];
> std::cout << sizeof(array)/sizeof(T) << std::endl:
> }

Surely that is illegal C++ (i.e. there is not support for VLAs).

/Leigh


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Francis Glassborow <francis.glassborow@btinternet.com>
Date: Tue, 11 Jan 2011 15:16:28 CST
Raw View
On 11/01/2011 17:40, Leigh Johnston wrote:
>
> On 11/01/2011 16:04, Francis Glassborow wrote:
>>
>>
>> Elsewhere (alt.comp.lang.learn.c-c++ a respected poster claims that the
>> Standard allows complete objects to be disjoint. There is no
>> disagreement that subobjects can be disjoint (essential to support
>> virtual inheritance.) However it is my claim that complete objects must
>> occupy a single contiguous region of storage. Yes member pointers and
>> references can point/refer to objects elsewhere but those are not a
>> direct part of a complete object. I do have some reservations about
>> references but I think that in this aspect they should be consider in
>> the same way that we consider pointers. I am open to persuasion on that
>> issue.
>>
>> Now my main piece of 'evidence' is illustrated by this code:
>>
>> template<typename T>
>> void foo(int n){
>> T array[n];
>> std::cout << sizeof(array)/sizeof(T) << std::endl:
>> }
>
> Surely that is illegal C++ (i.e. there is not support for VLAs).
>
> /Leigh
I missed making n a template parameter (which had been my intent)

so please read it as it was meant (the body of the code is the essential
part) the size of an array dic=vided by the sizeof an element should
give the number of elements.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "dietmar_kuehl@yahoo.com" <dietmar.kuehl@gmail.com>
Date: Tue, 11 Jan 2011 15:18:29 CST
Raw View
On Jan 11, 4:04 pm, Francis Glassborow
<francis.glassbo...@btinternet.com> wrote:
> Elsewhere (alt.comp.lang.learn.c-c++ a respected poster claims that the
> Standard allows complete objects to be disjoint. There is no
> disagreement that subobjects can be disjoint (essential to support
> virtual inheritance.) However it is my claim that complete objects must
> occupy a single contiguous region of storage.

While trying to answer this question, I just stumbled over 3.9
(basic.types)
pargraph 1 of n3225: this paragraph starts a note which doesn't seem
to
end. I think, that this is an editorial issue, though. Paragraph 2 of
this
section clearly states that trivially copyable objects can be
memcpy()ed
back and forth.

Paragraph 4 of this section clearly states that the bytes are
contiguous for
an object of type T:

   The object representation of an object of type T is the sequence of
N
    unsigned char objects taken up by the object of type T, where N
equals
    sizeof(T).

OK, this is quoting the latest draft but I'd be surprised if the C+
+2003
document stated or intended something different.

> Now my main piece of 'evidence' is illustrated by this code:
>
> template<typename T>
> void foo(int n){
>    T array[n];
>    std::cout << sizeof(array)/sizeof(T) << std::endl:
> }

This is neither valid C++ (1998, 2003, 0x) nor valid C code: C++
doesn't
have variable length arrays and C doesn't have templates. This might
compile with gcc's extention to support variable length arrays in C++
but
I'm unsure what this is supposed to demonstrate: sizeof(T) happens to
the byte offset between two objects in an array of T, as stated in
5.3.3
(expr.sizeof), paragraph 2, last sentence (also taken from n3225):

   When applied to an array, the result is the total number of bytes in
the
   array. This implies that the size of an array of n elements is n
times the
   size of an element.

> The simple question is:
>
> Can a complete C++ object (other languages define objects in other ways)
> have a disjoint region of storage.

The short answer is: no. The longer answer is: pointed to objects (v-
tables,
memory allocated to store e.g. elements in an array, etc.) are not
part of
the C++ object.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date: Wed, 12 Jan 2011 10:00:53 CST
Raw View
* dietmar_kuehl@yahoo.com, on 11.01.2011 22:18:
>
> On Jan 11, 4:04 pm, Francis Glassborow
> <francis.glassbo...@btinternet.com>  wrote:
>> Elsewhere (alt.comp.lang.learn.c-c++ a respected poster claims that the
>> Standard allows complete objects to be disjoint. There is no
>> disagreement that subobjects can be disjoint (essential to support
>> virtual inheritance.) However it is my claim that complete objects must
>> occupy a single contiguous region of storage.
>
> While trying to answer this question, I just stumbled over 3.9
> (basic.types)
> pargraph 1 of n3225: this paragraph starts a note which doesn't seem
> to
> end. I think, that this is an editorial issue, though. Paragraph 2 of
> this
> section clearly states that trivially copyable objects can be
> memcpy()ed
> back and forth.
>
> Paragraph 4 of this section clearly states that the bytes are
> contiguous for
> an object of type T:
>
>     The object representation of an object of type T is the sequence of
> N
>      unsigned char objects taken up by the object of type T, where N
> equals
>      sizeof(T).

If that paragraph had clearly stated that the bytes are contiguous for an object
of any type, then that would have been a defect, since it would prevent virtual
inheritance.

However, happily, there's nothing that states what you say it states.


Cheers & hth.,

- Alf

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


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Leigh Johnston <leigh@i42.co.uk>
Date: Thu, 13 Jan 2011 08:11:19 CST
Raw View
On 12/01/2011 16:00, Alf P. Steinbach /Usenet wrote:
>
> * dietmar_kuehl@yahoo.com, on 11.01.2011 22:18:
>>
>> On Jan 11, 4:04 pm, Francis Glassborow
>> <francis.glassbo...@btinternet.com> wrote:
>>>
>>> Elsewhere (alt.comp.lang.learn.c-c++ a respected poster claims that the
>>> Standard allows complete objects to be disjoint. There is no
>>> disagreement that subobjects can be disjoint (essential to support
>>> virtual inheritance.) However it is my claim that complete objects must
>>> occupy a single contiguous region of storage.
>>
>> While trying to answer this question, I just stumbled over 3.9
>> (basic.types)
>> pargraph 1 of n3225: this paragraph starts a note which doesn't seem
>> to
>> end. I think, that this is an editorial issue, though. Paragraph 2 of
>> this
>> section clearly states that trivially copyable objects can be
>> memcpy()ed
>> back and forth.
>>
>> Paragraph 4 of this section clearly states that the bytes are
>> contiguous for
>> an object of type T:
>>
>> The object representation of an object of type T is the sequence of
>> N
>> unsigned char objects taken up by the object of type T, where N
>> equals
>> sizeof(T).
>
> If that paragraph had clearly stated that the bytes are contiguous for
> an object
> of any type, then that would have been a defect, since it would prevent
> virtual
> inheritance.
>
> However, happily, there's nothing that states what you say it states.
>
>

A complete object occupies a contiguous region of storage; I think
that is all that is meant.

/Leigh


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Fri, 14 Jan 2011 08:56:44 CST
Raw View
dietmar_kuehl@yahoo.com wrote:

>
> On Jan 11, 4:04 pm, Francis Glassborow
> <francis.glassbo...@btinternet.com> wrote:
>> Elsewhere (alt.comp.lang.learn.c-c++ a respected poster claims that the
>> Standard allows complete objects to be disjoint. There is no
>> disagreement that subobjects can be disjoint (essential to support
>> virtual inheritance.) However it is my claim that complete objects must
>> occupy a single contiguous region of storage.
>
> While trying to answer this question, I just stumbled over 3.9
> (basic.types)
> pargraph 1 of n3225: this paragraph starts a note which doesn't seem
> to
> end. I think, that this is an editorial issue, though. Paragraph 2 of
> this
> section clearly states that trivially copyable objects can be
> memcpy()ed
> back and forth.
>
> Paragraph 4 of this section clearly states that the bytes are
> contiguous for
> an object of type T:
>
>    The object representation of an object of type T is the sequence of
> N
>     unsigned char objects taken up by the object of type T, where N
> equals
>     sizeof(T).
>

I also stumbled about that. Shouldn't that say "The object representation of
an object of trivially copyable or standard layout type T is the sequence
..."  (see 1.8/5). Surely some base class subobjects aren't contiguous.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date: Fri, 14 Jan 2011 08:55:23 CST
Raw View
* Leigh Johnston, on 13.01.2011 15:11:
>
> On 12/01/2011 16:00, Alf P. Steinbach /Usenet wrote:
>>
>> * dietmar_kuehl@yahoo.com, on 11.01.2011 22:18:
>>>
[snip]
>>>
>>> The object representation of an object of type T is the sequence of
>>> N
>>> unsigned char objects taken up by the object of type T, where N
>>> equals
>>> sizeof(T).
>>
>> If that paragraph had clearly stated that the bytes are contiguous for
>> an object
>> of any type, then that would have been a defect, since it would prevent
>> virtual
>> inheritance.
>>
>> However, happily, there's nothing that states what you say it states.
>>
>
> A complete object occupies a contiguous region of storage; I think
> that is all that is meant.

The text does not say "complete".


Cheers & hth.,

- Alf

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


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Pedro_Lamar=E3o?= <pedro.lamarao@ccppbrasil.org>
Date: Fri, 14 Jan 2011 08:56:43 CST
Raw View
On Tuesday, January 11, 2011 2:04:10 PM UTC-2, francis.glassborow wrote:

> The simple question is:
>
> Can a complete C++ object (other languages define objects in other ways)
> have a disjoint region of storage.

Is padding to achieve alignment considered disjointness in this context?

--
  P.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Francis Glassborow <francis.glassborow@btinternet.com>
Date: Fri, 21 Jan 2011 11:14:23 CST
Raw View
On 14/01/2011 14:56, Pedro Lamar   o wrote:
>
> On Tuesday, January 11, 2011 2:04:10 PM UTC-2, francis.glassborow wrote:
>
>> The simple question is:
>>
>> Can a complete C++ object (other languages define objects in other ways)
>> have a disjoint region of storage.
>
> Is padding to achieve alignment considered disjointness in this context?
>
> --
>    P.
>
>

No, it is part of the raw memory assigned to the object (i.e. the
quantity returned by sizeof. However it is interesting to note that
members of a derived object can use padding from a base object so that a
base object can be interleaved with the extra parts of a derived object.
However I do not think that a member of a derived object can itself be
split across several pieces of disjoint padding.

In recent discussion within the UK C++ Committee the consensus was,
IIUC, that a most derived object could not be disjoint (note that this
is not the same as a complete object, which also cannot be disjoint,
because a complete object might have several data members each of which
was derived from one or more bases.

It seems that only base class sub-objects in the context of virtual
inheritance can be disjoint And when there is more than one level of
inheritance at least one virtual class sub-object may have to be disjoint:

class xyz{
    float f;
};

class a : virtual xyz {int i;};
class b : virtual xyz {int j;};
class c : virtual xyz  {int k;};

class d : a,b,c {float d};

Ay least one of the a, b and c subobjects of d must be disjoint.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date: Sat, 22 Jan 2011 10:47:52 CST
Raw View
* Francis Glassborow, on 21.01.2011 18:14:
>
> On 14/01/2011 14:56, Pedro Lamar   o wrote:
>>
>> On Tuesday, January 11, 2011 2:04:10 PM UTC-2, francis.glassborow wrote:
>>
>>> The simple question is:
>>>
>>> Can a complete C++ object (other languages define objects in other ways)
>>> have a disjoint region of storage.
[snip useful exchange about exploiting padding]


> In recent discussion within the UK C++ Committee the consensus was,
> IIUC, that a most derived object could not be disjoint (note that this
> is not the same as a complete object, which also cannot be disjoint,
> because a complete object might have several data members each of which
> was derived from one or more bases.

To be clear, the difference is that a complete object can be a complete object
of non-class type, e.g. an 'int'.

A complete object of class type is called a most derived object,    1.8/4.

In this forum it is a necessary and useful distinction. Thanks for bringing that
up. In earlier discussion a non-POD class type was just assumed.


> It seems that only base class sub-objects in the context of virtual
> inheritance can be disjoint

Well that's what's being discussed. ;-)

The current standard does not seem to forbid it.

The way I read it the current standard is not self-contradictory when it defines
object representation in    3.9/4, but some others think so.

If that paragraph is clarified, then it can help to close the issue.

My preferred resolution (if    3.9/4 were to be changed) is, I think, just as
yours, that complete objects /should not/ be able to be disjoint. Where we
differ is whether as it is, the standard is clear about this issue. It seems
that paradoxically, you think the standard is clear but that the paragraph is
inconsistent, while I think it's unclear (and allows disjointness for e.g. a
local variable) but consistent. If someone who thinks it is unclear *and*
inconsistent chimed in, then to me that would feel, uh, less confusing... :-)

But, anyway, even if a complete object (of non-POD class type) can be disjoint,
I do not think there is any way that that can be detected portably, i.e. I do
not think there is any detectable effect for portable code?


> And when there is more than one level of
> inheritance at least one virtual class sub-object may have to be disjoint:
>
> class xyz{
> float f;
> };
>
> class a : virtual xyz {int i;};
> class b : virtual xyz {int j;};
> class c : virtual xyz {int k;};
>
> class d : a,b,c {float d};
>
> Ay least one of the a, b and c subobjects of d must be disjoint.

Yes.

Cheers, & hth.,

- Alf

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


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]