Search

Incorrectly duplicating object when it is a native one(NDT) in vs2010sp1(C++) by UnitUniverse

Closed
as Fixed Help for as Fixed

1
0
Sign in
to vote
Type: Bug
ID: 679623
Opened: 7/16/2011 2:36:15 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
0
Workaround(s)
0
User(s) can reproduce this bug
Recently i wrote a C++ TEMPLATE Library that should pass the type info transparently from the referenced sources to the target. Then I found the rvalue-referenced object being copied from the source(incorrectly maybe) rather than referencing to the original one like doing to const lvalue references.
The 'error' is exactly like this:
If a source is a UDT object from struct/union/class, there is no such error at all;
If a source is a NDT object like int/char/float, etc, thers is such limitation there.
I don't think the micro-code optimization to CPU is an excuse for this error(sorry about the word, i just attempt to say that is logically-possible reason for) while to rvalue references or constant lvalue references.
The sample code shows what i told, Assuming those were the instantiated templates.

Regards
Details (expand)

Visual Studio/Team Foundation Server/.NET Framework Tooling version

Visual Studio 2010 SP1

Steps to reproduce

I put the code here:
--------------------------------------------
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <conio.h>


class A1
{
public:
    static A1 GetRvA(int && v)
    {
        std::cout << "A1::GetRvA()" << std::endl;
        return A1((int &&)v);
    };

    ~A1(void)
    {
        i = 0xcdcdcdcd;
        std::cout << "~A1()" << std::endl;
    };

    int i;

private:
    A1(int && v): i(v)
    {
        std::cout << "A1() --" << (void *)&i << " from " << (void *)&v << std::endl;
    };

    A1(const A1 &);
    A1 & operator = (const A1 &);
};

class A2
{
public:
    static A2 GetRvA(int && v)
    {
        std::cout << "A2::GetRvA() --" << (void *)&v << std::endl;
        return A2((int &&)v);
    };

    ~A2(void)
    {
        i = 0xcdcdcdcd;
        std::cout << "~A2()" << std::endl;
    };

    int && i;
private:
    A2(int && v): i((int &&)v)
    {
        std::cout << "A2() --" << (void *)&i << " from " << (void *)&v << std::endl;
    };

    A2(const A2 &);
    A2 & operator = (const A2 &);
};

class A3
{
public:
    static A3 GetRvA(const int & v)
    {
        std::cout << "A3::GetRvA() --" << (void *)&v << std::endl;
        return A3((const int &)v);
    };

    ~A3(void)
    {
        i = 0xcdcdcdcd;
        std::cout << "~A3()" << std::endl;
    };

    /*const*/ int & i;
private:
    A3(const int & v): i((/*const*/ int &)v)
    {
        std::cout << "A3() --" << (void *)&i << " from " << (void *)&v << std::endl;
    };

    A3(const A3 &);
    A3 & operator = (const A3 &);
};

struct tagInt
{
    int i;

    tagInt(const int & v): i(v){};
};

class A4
{
public:
    static A4 GetRvA(tagInt && v)
    {
        std::cout << "A4::GetRvA() --" << (void *)&v.i << std::endl;
        return A4((tagInt &&)v);
    };

    ~A4(void)
    {
        //i = 0xcdcdcdcd;
        std::cout << "~A4()" << std::endl;
    };

    tagInt && i;
private:
    A4(tagInt && v): i((tagInt &&)v)
    {
        std::cout << "A4() --" << (void *)&i.i << " from " << (void *)&v.i << std::endl;
    };

    A4(const A4 &);
    A4 & operator = (const A4 &);
};

class B
{
public:
    B(A1 && obj): m(obj.i)
    {
        std::cout << "B(A1) --" << (void *)&obj.i << std::endl;
    };

    B(A2 && obj): m(obj.i)
    {
        std::cout << "B(A2) --" << (void *)&obj.i << std::endl;
    };

    B(A3 && obj): m(obj.i)
    {
        std::cout << "B(A3) --" << (void *)&obj.i << std::endl;
    };

    B(A4 && obj): m(obj.i.i)
    {
        std::cout << "B(A4) --" << (void *)&obj.i.i << std::endl;
    };

private:
    int m;
};

void foo(B && /*obj*/)
{
    return;
}


int _tmain(int /*argc*/, _TCHAR * /*argv*/[])
{
    {
        foo(B(A1::GetRvA(1))); // OK
        foo(B(A2::GetRvA(1))); // C4413 and Runtime Error(Got 0xcccccccc within B::m).
        foo(B(A3::GetRvA(1))); // No error during compile and runtime but the target becomes unmovable.
        foo(B(A4::GetRvA(1))); // OK.
    }
    _getch();
    return 0;
}

Product Language

English

Operating System

Windows 7

Operating System Language

English

Actual results

This is output here:
-----------------------------
A1::GetRvA()
A1() --0034F670 from 0034F664
B(A1) --0034F670
~A1()
A2::GetRvA() --0034F688
A2() --0034F534 from 0034F688
B(A2) --0034F534
~A2()
A3::GetRvA() --0034F6AC
A3() --0034F6AC from 0034F6AC
B(A3) --0034F6AC
~A3()
A4::GetRvA() --0034F6D0
A4() --0034F6D0 from 0034F6D0
B(A4) --0034F6D0
~A4()

Expected results

A1::GetRvA()
A1() --0034F670 from 0034F664
B(A1) --0034F670
~A1()
A2::GetRvA() --0034F688
A2() --0034F688 from 0034F688
B(A2) --0034F688
~A2()
A3::GetRvA() --0034F6AC
A3() --0034F6AC from 0034F6AC
B(A3) --0034F6AC
~A3()
A4::GetRvA() --0034F6D0
A4() --0034F6D0 from 0034F6D0
B(A4) --0034F6D0
~A4()
File Attachments
File Name Submitted By Submitted On File Size  
rvtuple.cpp 3/7/2012 4 KB
Sign in to post a comment.
Posted by UnitUniverse on 3/7/2012 at 7:45 PM
Hard to explain by several words...
I have figured out a way to solve this, working on both 2010(sp1) and v11.

I made a source file to describe what i said, which has been uploaded as the 'Attach a file'.

Thanks.
Posted by Microsoft on 11/23/2011 at 11:47 AM
Hi:
    A fix for this issue has been checked into the compiler sources. The fix should show up in the next release of Visual C++.

Xiang Fan
Visual C++ Team
Posted by UnitUniverse on 7/20/2011 at 1:23 PM
Any idea?
Posted by MS-Moderator08 [Feedback Moderator] on 7/17/2011 at 8:18 PM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for investigation. We will contact you if we require any additional information.
Posted by MS-Moderator01 on 7/16/2011 at 2:48 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.