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.