Unidata / netcdf-cxx4

Official GitHub repository for netCDF-C++ libraries and utilities.
Other
124 stars 49 forks source link

Errors with rvalue references in C++11 mode #17

Closed Luthaf closed 9 years ago

Luthaf commented 9 years ago

The following code throw a NcBadId exception at the auto attr = wrap.file.getAtt("Conventions"); line.

#include <string>
#include <netcdf>

using namespace std;
using namespace netCDF;

class Wrapper {
public:
    Wrapper(string name, string mode) {
        if (mode == "r")
            file = NcFile(name, NcFile::read);
        else if (mode == "w")
            file = NcFile(name, NcFile::write);
    }
    NcFile file;
};

int main(int argc, char** argv) {
    Wrapper wrap("file.nc", "r");
    auto attr = wrap.file.getAtt("Conventions");
    return 0;
}

While when I use direct initialisation for the file member, everything works.

class Wrapper {
public:
     Wrapper(string name, string mode) : file(name, NcFile::read) {}
    NcFile file;
};

Maybe the library is using the default generated operator=(const NcFile&), and this one is not correct. My compiler is clang based on LLVM 3.5.

Luthaf commented 9 years ago

More investigation on that. It looks like it is not the operator=(const NcFile&) which one is missing, but the C++11 operator=(NcFile&&), which is generated by the compiler in that case.

The same issue appears with other constructs like :

NcFile file("file.nc", NcFile::read);
// No "Foo" var in file.nc, this should throw. The operator=(NcVar&&) is used
NcVar var = file.getVar("Foo"); 
if (var.isNull())
    cout << "Error !" << endl;  // This does NOT happen

var.getAtt("Bar"); // Boom ! NcBadId here

This usage is fine though :

NcFile file("file.nc", NcFile::read);
// No "Foo" var in file.nc, this should throw. The NcVar(NcVar&&) constructor is used
NcVar var(file.getVar("Foo")); 
if (var.isNull())
    cout << "Error !" << endl;  // This DOES happen
Luthaf commented 9 years ago

Ok, I was wrong all long ... I was not using the latest version, and I ran into this bug. I will propose a PR adding open and close methods to get around this bug.