Jo is right.  I sent this a few minutes ago in response to Alok's message
about the assignment operator and how that somehow makes the exhibited
behavior correct... but I don't think it went through so I'm re-sending.
 Sorry if this is a double post.  Of course as Jo said, it's not even using
the assignment operator in this case, but the point is the same either way
since assignment and copy construction is equivalent in this argument.


The docs use the term "assign" because that's the C++ assignment operator.
 Assigning value types is not supposed to create a reference.

Simplest example is:

int a = 0;
int b = a;
a = 1;

At this point, b is obviously still 0 even though you "assigned" a to it.

Or a better example:

std::vector<CRef> a1;
a1.push_back(CRef());
a1.push_back(CRef());
std::vector<CRef> a2(a1);
a2.push_back(CRef());

size_t n1 = a1.size();  //n1 == 2
size_t n2 = a2.size();  //n2 == 3

The problem is they're treating CRefArray like it's a reference to an array
of CRefs rather than just a straight-up array of CRefs.

I would expect that behavior if a2 was a reference to a CRefArray, e.g.

CRefArray a1;
a1.Add(CRef());
a1.Add(CRef());
CRefArray*&* a2(a1);
a2.Add(CRef());

Now a1.GetCount() == a2.GetCount() makes sense.

It gets even more evil if you do this:

CRefArray a1;
a1.Add(CRef());
a1.Add(CRef());
const CRefArray a2(a1);
a1.Add(CRef());

Even though a2 is declared const, the last line doesn't respect its
constness (or at least the constness I expected).



On Mon, Apr 30, 2012 at 5:03 PM, jo benayoun <jobenay...@gmail.com> wrote:

> in this case,
>
> """
> CRefArray a1;
> a1.Add(CRef());
> a1.Add(CRef());
> CRefArray a2(a1);
> a2.Add(CRef());
> """
>
> The copy constructor is invoked and is not the one you mentioned Alok but
> this one "CRefArray(const CRefArray &other)" which have different behaviors
> and purposes than the overloaded assignment operator.
>
> """*Copy constructor* is called every time a copy of an object is made.
> When you pass an object by value, either into a function or as a function's
> return value, a temporary copy of that object is made.
>
> Assignment operator is called whenever you assign to an object. Assignment
> operator must check to see if the right-hand side of the assignment
> operator is the object itself. It executes only the two sides are not equal
> """
>
> Referring to the docs : "Constructs a 
> CRefArray<http://download.autodesk.com/global/docs/softimage2012/en_us/sdkguide/si_cpp/classXSI_1_1CRefArray.html>object
>  from another
> CRefArray<http://download.autodesk.com/global/docs/softimage2012/en_us/sdkguide/si_cpp/classXSI_1_1CRefArray.html>object."
>  which is the expected behavior.
>
> For completeness, the copy constructor in the case of an array, a string,
> a ptr or whatever container has a main purpose to "pass" an implicit shared
> memory block to save memory specially in
> the case of "passing arguments by value". A deep copy is done only at the
> first call of a method non-const which should create a brand new underlying
> object (concept called copy-on-write).
> In this case, it seems its not what happens ... which is a bug in all case
> unless its a wanted behavior and it should be specified in the doc !
> A more comprehensible example is the python "list" example:
> doing an assignment "mylist = myotherlist" creates a shallow copy and
> returns the "myotherlist" object to the mylist which is not the case of
> calling the ctor directly with "mylist = list(myotherlist)". That's a
> behavior that could be implemented here.
>
> """
> mylist = [1, 2]
> print mylist
> myotherlist = mylist
> mylist.append(6)
> print mylist
> print myotherlist
> myoolist = list(mylist)
> mylist.append(9)
> print mylist
> print myotherlist
> print myoolist
> """
>
>
> "Set<http://download.autodesk.com/global/docs/softimage2012/en_us/sdkguide/si_cpp/classXSI_1_1CRefArray.html#acb58b1fecf704752ebcf59a50444cf37>(const
> CValueArray<http://download.autodesk.com/global/docs/softimage2012/en_us/sdkguide/si_cpp/classXSI_1_1CValueArray.html>&in_valarray)"
> I dont see any overloaded cast method nor ctors for a CRefArray to
> CValueArray. Even if there was, it would mean that your CValueArray have to
> be built from a CRefArray before being passed by reference. Which is an
> overhead instead of using the copy ctor.
> "const" is a keyword that we use to assure to the compiler, we will not
> try to modify the underlying memory block nor call any procedures that
> could do this. Of course, the compiler takes this as serious and do
> optimizations in consequences which is a good thing for us.
>
> jo
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> 2012/4/30 piotrek marczak <piotrek.marc...@gmail.com>
>
>>   Maybe a2.Set(a1) or a2+=a1 would work?
>>
>> newbie question
>> isn’t “const” keyword a hint that we won’t change input array?
>>   *From:* Alok Gandhi <alok.gan...@modusfx.com>
>> *Sent:* Tuesday, May 01, 2012 1:31 AM
>> *To:* softimage@listproc.autodesk.com
>> *Subject:* Re: CRefArray doesn't respect C++ copy semantics
>>
>> The docs say that:
>>
>>   
>> CRefArray<http://download.autodesk.com/global/docs/softimage2012/en_us/sdkguide/si_cpp/classXSI_1_1CRefArray.html>&
>> operator= ( const 
>> CRefArray<http://download.autodesk.com/global/docs/softimage2012/en_us/sdkguide/si_cpp/classXSI_1_1CRefArray.html>&
>> *in_refArray* )
>>
>> *Assigns* a 
>> CRefArray<http://download.autodesk.com/global/docs/softimage2012/en_us/sdkguide/si_cpp/classXSI_1_1CRefArray.html>object
>>  to this one.
>>  *Parameters:*   in_refArray A constant 
>> CRefArray<http://download.autodesk.com/global/docs/softimage2012/en_us/sdkguide/si_cpp/classXSI_1_1CRefArray.html>object.
>> *Returns:* A new reference object.
>>
>> So what I think is happening is that the copy constructor is doing
>> exactly what it is supposed to do and returns the new CRefArray object
>> which still points to a1, 'assigns' is the operative word here. To keep
>> them separate I would rather do:
>>
>>
>>     CRefArray a1;
>>     a1.Add(CRef());
>>     a1.Add(CRef());
>>     CRefArray a2;
>>
>>     for(int i=0; i<a1.GetCount(); i++)
>>     {
>>         a2.Add(a1[i]);
>>     }
>>
>>     a2.Add(CRef());
>>
>>     //a2.Add(CRef());
>>     LONG n1 = a1.GetCount();  // expected n1 == 2
>>     LONG n2 = a2.GetCount();  // expected n2 == 3
>>
>> which gives me correctly:
>>
>> # VERBOSE : cRefArrayTest_Execute called
>> # VERBOSE : Count a1: 2
>> # VERBOSE : Count a2: 3
>>
>>
>>
>> On 4/30/2012 7:13 PM, Nicolas Burtnyk wrote:
>>
>> Yeah, exactly as I unfortunately discovered :(
>>
>> On Mon, Apr 30, 2012 at 3:49 PM, Alok Gandhi <alok.gan...@modusfx.com>wrote:
>>
>>> A quick test gives me following result:
>>>
>>> # VERBOSE : cRefArrayTest_Execute called
>>> # VERBOSE : Count a1: 3
>>> # VERBOSE : Count a2: 3
>>>
>>>
>>> On 4/30/2012 6:24 PM, Nicolas Burtnyk wrote:
>>>
>>>  I ran into this today while trying to figure out why my code was
>>> broken.
>>> Thought I'd pass this along and hopefully save someone some wasted time
>>> in the future...
>>>
>>>  CRefArray a1;
>>> a1.Add(CRef());
>>> a1.Add(CRef());
>>> CRefArray a2(a1);
>>> a2.Add(CRef());
>>>  LONG n1 = a1.GetCount();  // expected n1 == 2
>>> LONG n2 = a2.GetCount();  // expected n2 == 3
>>>
>>> I expected a2 to be a copy of a1 before the last add and so I assumed a1
>>> would have 2 elements.
>>> Instead, I was surprised to find that n1 == n2 == 3!
>>>
>>>
>>>
>>> No virus found in this message.
>>> Checked by AVG - www.avg.com
>>> Version: 2012.0.1831 / Virus Database: 2090/4557 - Release Date: 10/17/11
>>> Internal Virus Database is out of date.
>>>
>>>
>> No virus found in this message.
>> Checked by AVG - www.avg.com
>> Version: 2012.0.1831 / Virus Database: 2090/4557 - Release Date: 10/17/11
>> Internal Virus Database is out of date.
>>
>>
>

Reply via email to