These days I was fiddling with a project study for a data model with a kind of reflection suitable to my needs. While I got my first study running with the recent stable version of g++, I failed in Visual Studio 19. Too bad, because the latter is my primary platform…
Effectively, I try to store a pointer to member variable into another static member variable. Thereby, it's really desirable for me to do this inline (to fit into my bigger concept).
I reduced the failing detail to the following MCVE:
struct Field { };
struct Class {
template <typename CLASS>
struct BuiltInInfoT {
Field CLASS::*const pField; // member pointer
};
};
struct Object: Class {
Field field1;
static inline BuiltInInfoT<Object> field1BuiltInfo = { &Object::field1 };
};
int main()
{
Object obj;
}
Puzzled that this seems to work in g++ but not in MSVC, I had a look on Compiler Explorer what other compilers say about this. So, I found that recent clang and even the recent ICC (I never used before) accept this.
Live Demo on Compiler Explorer
I tried the same with an even simpler previous example where I didn't use any templates:
#include <iostream>
struct Test {
struct Info { int Test::*p; };
int a;
static inline Info infoA = { &Test::a };
int b;
static inline Info infoB = { &Test::b };
Test(int a, int b): a(a), b(b) { }
};
#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__
int main()
{
DEBUG(Test test(123, 456));
DEBUG(std::cout << (test.*(test.infoA.p)) << '\n');
DEBUG(std::cout << (test.*(test.infoB.p)) << '\n');
}
The result is the same: g++, clang, and ICC compile this fine but MSVC complains.
Live Demo on Compiler Explorer
So, now I'm a bit uncertain.
Is it a bug of MSVC that might be worth to be reported? Or am I expecting something I should not rely on?
Disclaimer:
Of course, I googled this topic the last 3 days and found zillions of tutorials about how to use a member pointer – including the answer to SO: What is the meaning of this star (*) symbol in C++? — Pointer to member I've written myself. Maybe, I was missing the essential keyword but I promise I really tried hard.
In case, you're wondering what I'm trying to do…
The actual project study as Live Demo on coliru from which I made my above MCVE.
Update:
After a long discussion, @doug helped me to find out that this seems to be subject of the Visual Studio property settings. With a clean started project, I got all the above mentioned samples running in my local VS 2019. (Before, I used CMake-generated projects as usual.) I will compare the options of two resp. VS projects to find out the significant difference and post an update if I found something…
@doug gave me the hint that he got my code running in VS 2019 without any complaints.
After a long chat, he gave me the hint to test my above samples in a new created VS solution. All I had to do, was to enable C++17 (/std:c++17
) and then MSCV compiled all the samples without complaints.
I must admit that I usually use CMake to prepare the VS solutions:
project (OFM)
cmake_minimum_required(VERSION 3.10.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
include_directories("${CMAKE_SOURCE_DIR}")
file(GLOB sources *.cc)
file(GLOB headers *.h)
add_executable(testOFM
${sources} ${headers})
So, I had to find the relevant difference in the VS project settings. Finally, I found it:
/permissive-
In the projects settings, it is
- C/C++
- Language
- Standards conformance: Yes (/permissive)
The MS online doc.:
/permissive- (Standards conformance)
Specify standards conformance mode to the compiler. Use this option to help you identify and fix conformance issues in your code, to make it both more correct and more portable.
That's exactly what I want: to be standard conform and portable.
Adjusting this option in my CMake generated project, I got it compiled and running as well.
The demos on Compiler Explorer compiled properly (with the sufficient command line arguments):
Live Demo on Compiler Explorer
Live Demo on Compiler Explorer
and even the initial study (where my trouble started from):
Live Demo on Compiler Explorer
What I wonder: When I wrote my CMake script I already used
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
with the exact intention to be standard conform and portable.
So, there seems to be something else I have to setup in CMake. (The last resort could be a platform-specific setting but I will investigate to find something else if possible.)
Concerning my problem, I found
CMake Issue #17068:
MSVC toolset 14.1+: Set /permissive- when CXX_EXTENSIONS==OFF?
After I have fixed my CMake script with a compiler specific option:
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if (MSVC)
add_compile_options(/permissive-)
endif()
and generated my VS solution / projects again the code compiled without any complaints as well.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments