Search

Move-construction can slice objects by SecurityException

Closed
as Fixed Help for as Fixed

2
0
Sign in
to vote
Type: Bug
ID: 640619
Opened: 1/31/2011 2:21:49 PM
Access Restriction: Public
0
Workaround(s)
0
User(s) can reproduce this bug
I've spent some hours debugging an access violation. It turned out that a std::ifstream was sliced to a std::istream due to a typo in the code. I'm curious whether it is legal what happened to me, because the compiler first calls ifstream(ifstream&&) and then istream(istream&&), although the object is only returned once. Please see the code I provided.

#include <cassert>
#include <fstream>


std::ifstream OpenRead(const char* file) {
    std::ifstream stream(file, std::ios_base::in | std::ios_base::binary);
    if( !stream.good() )
        throw "Unable to open file!";

    stream.exceptions(std::ios_base::badbit);
    return stream;
}


int main() {
    static const char* filename = "main.cpp";

    std::istream input = OpenRead(filename);        // access violation
    //std::ifstream input = OpenRead(filename);        // fixes the bug
    char test = input.get();
    assert( test == '#' );
}
Details (expand)

Visual Studio/Silverlight/Tooling version

Visual Studio 2010

What category (if any) best represents this feedback?

Compatibility

Steps to reproduce

#include <cassert>
#include <fstream>


std::ifstream OpenRead(const char* file) {
    std::ifstream stream(file, std::ios_base::in | std::ios_base::binary);
    if( !stream.good() )
        throw "Unable to open file!";

    stream.exceptions(std::ios_base::badbit);
    return stream;
}


int main() {
    static const char* filename = "main.cpp";

    std::istream input = OpenRead(filename);        // access violation
    //std::ifstream input = OpenRead(filename);        // fixes the bug
    char test = input.get();
    assert( test == '#' );
}

Product Language

English

Operating System

Windows 7

Operating System Language

English

Actual results

The stream object gets silently sliced, causing an access violation during the next read.

Expected results

Compile error.
File Attachments
0 attachments
Sign in to post a comment.
Posted by Microsoft on 2/1/2011 at 2:52 PM
Hi,

Thanks for reporting this bug. We've already fixed it, and the fix will be available in VC11. Originally, the C++0x Working Paper gave basic_istream and basic_ostream public move constructors, move assignment operators, and swaps, so that's what we implemented in VC10. In Working Paper N3090 on March 29, 2010, they were made protected instead of public. That was way too late for VC10, but we've already made this change for VC11. Now this code will emit:

error C2248: 'std::basic_istream<_Elem,_Traits>::basic_istream' : cannot access protected member declared in class 'std::basic_istream<_Elem,_Traits>'

If you have any further questions, feel free to E-mail me at stl@microsoft.com .

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by Microsoft on 1/31/2011 at 6:57 PM
Thanks for your feedback.
We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Microsoft on 1/31/2011 at 2:59 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.