Home > OS >  error C2312 is thrown for ifstream::failure and ofstream::failure exceptions
error C2312 is thrown for ifstream::failure and ofstream::failure exceptions

Time:09-27

I am writing a small application that modifies a text file. It first creates a copy of the file in case something goes wrong.

The following function creates this copy in the same directory. It takes the file's name as an argument and returns true if the copy is successfully created, and false if it fails.

#include <iostream>
#include <filesystem>
#include <fstream>
#include <string>

using std::ifstream;
using std::ofstream;
using std::string;
using std::cerr;
using std::cin;
using std::cout;
using std::endl;

bool backupFile(string FileName) {
    cout << "Creating backup for " << FileName << "..." << endl;

    try { // for debugging purposes
        string NewName = "bkp_"   FileName;
        string CurLine;
        ifstream FileCopy(FileName);
        ofstream FileBackup(NewName);

        if (FileCopy.fail()) { // Could specify how file copy failed?
            cerr << "Error opening file " << FileName << ".";
            return false;
        }
        
        while (getline(FileCopy, CurLine)) { // Copy lines to new file
            //cout << "Copying " << CurLine << "\" to " << NewName << "." << endl;
            FileBackup << CurLine << "\n";
        }     


        cout << "File successfully backed up to " << NewName << endl;
        return true;
    }
    catch (const ifstream::failure& iE) {
        cerr << "Exception thrown opening original file: " << iE.what() << endl;
        return false;
    }
    catch (const ofstream::failure& oE) {
        cerr << "Exception thrown outputting copy: " << oE.what() << endl;
    }
    catch (...) {
        cerr << "Unknown exception thrown copying file." << endl;
        return false;
    }
}

I've used a few catch statements to indicate if there is an issue with the input (ifstream::failure), the output (ofstream::failure), or neither.

During compilation, however, the following error appears:

error C2312: 'const std::ios_base::failure &': is caught by 'const std::ios_base::failure &' on line 42

To me, the error implies that both ifstream::failure and ofstream::failure are caught on ifstream::failure, which seems strange. When I remove the catch for ofstream::failure, it runs fine.

Why is this the case?

CodePudding user response:

ifstream::failure and ofstream::failure are both the same type defined in the std::ios_base base class std::ios_base::failure, you can't catch the same type in two separate catch clauses.

Note that neither of your streams will actually throw any exceptions, by default std::fstream doesn't throw any exceptions. You have to turn exceptions on by calling exceptions:

FileCopy.exceptions(f.failbit);
FileBackup.exceptions(f.failbit);

The above will cause an std::ios_base::failure to be thrown when the stream enters the failed state. As you are already checking for FileCopy.fail() you could just expand that checking to cover other failure cases (e.g. check that FileCopy doesn't fail during getline and that FileBackup also doesn't fail) rather than enabling exceptions.

  • Related