Home > front end >  Error "invalid use of non-static member function" : Results depend on compiler / OS?
Error "invalid use of non-static member function" : Results depend on compiler / OS?

Time:01-29

With the MCVE below, when I compile source classes_test.cc with

$ c   --version
c  .exe (Rev3, Built by MSYS2 project) 10.2.0
$ c  .exe -Wall -Wunused -Wuninitialized -g -o classes_test classes_test.cc -std=c  17

under Windows 10 Msys2 (without option -std=c 17 I get the same), I get the expected results

$ ./classes_test.exe
Using GNU G: True
Prototype of BaseClass::get_bc() is int (BaseClass::*)()

When I try the same in g under Ubuntu, I get compilation error

$ c   --version
c   (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
$ c   -Wall -Wunused -Wuninitialized -g -o classes_test classes_test.cc -std=c  17
classes_test.cc: In function ‘int main()’:
classes_test.cc:63:83: error: invalid use of non-static member function ‘int BaseClass::get_bc()’
  63  | aseClass::get_bc()" << " is " << type(BaseClass::get_bc) << endl;
      |                                                  ^~~~~~

How can the difference be explained?

How can I make code work, consistently in both Linux and Msys2?

#include <iostream>
#include <cstdio>
#include <vector>

#include <string>
#include <typeinfo>

using namespace std;

struct BaseClass {
  public:
    explicit BaseClass() : _baseClass_int(0) {};
    explicit BaseClass(const int bci) : _baseClass_int(bci) {};

    ~BaseClass() {};

    int get_bc() { return _baseClass_int; }
    void set_bc(const int bci) { _baseClass_int = bci; }
  private:
    int _baseClass_int;
};

#ifdef __GNUG__
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
#include <string>
#define USING_GNUG  ("True")

std::string demangle(const char* name) {

    int status = -4; // some arbitrary value to eliminate the compiler warning

    // enable c  11 by passing the flag -std=c  11 to g  
    std::unique_ptr<char, void(*)(void*)> res {
        abi::__cxa_demangle(name, NULL, NULL, &status),
        std::free
    };

    return (status==0) ? res.get() : name ;
}

#else
#define USING_GNUG  ("False")

// does nothing if not g  
std::string demangle(const char* name) {
    return name;
}

#endif


template <class T>
std::string type(const T& t) {

    return demangle(typeid(t).name());
}

int main() {

    cout << "Using GNU G: " << USING_GNUG << endl;
    cout << "Prototype of " << "BaseClass::get_bc()" << " is " << type(BaseClass::get_bc) << endl;

    return 0;
}

CodePudding user response:

The code is ill-formed, but MinGW enables some Microsoft-style extensions by default.

Compile with -fno-ms-extensions to fix that.

CodePudding user response:

As per comment by Nathan Oliver, the correct argument for type is &BaseClass::get_bc. With that, code works fine.

Plus, as mentioned by HolyBlackCat, the way to force Msys2 to report the error (instead of being permissive) is by adding flag -fno-ms-extensions to the compilation line. Note that this does not fix the problem.

  •  Tags:  
  • Related