1

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…

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56

2 Answers2

3

@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:

  • the VS created project contains /permissive-
  • the CMake created project doesn't.

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.

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
  • Excellent! This obscure problem is likely to surface again for others. Especially as it also appears on compiler explorer w/o permissive-. Glad I could help. – doug Oct 25 '20 at 19:15
1

@Scheff has identified a problem likely to affect others re inline static member initialization. It's particularly problematic as it differently affects compiler explorer c++17 defaults v MSVC IDE c++17 defaults. See his answer and analysis:

Using the default c++ settings (c++14) for MSVC which doesn't allow inline static members.

Change the setting to c++17 or higher. This is the usual cause of inline static initialization on the same line.

However, after chat, it turns out c++17 is being used but the difference is that it's being used with CMake. Apparently there is a difference between CMake and an MSBuild solution/project file. The latter works, the former doesn't. Under investigation and will update with results.

doug
  • 3,840
  • 1
  • 14
  • 18
  • The setting for MSVC is `/std:c++17 /O2`. Am I missing something? – Scheff's Cat Oct 25 '20 at 17:14
  • @Scheff Possible problem with compiler explorer? Works fine on my current MSVC in x86, x64 both release and debug – doug Oct 25 '20 at 17:19
  • What is your current MSVC? I have installed MSVC 19 locally two weeks ago and it was the first where I spotted my issue. I have version `19.27.29112 für x64` installed. – Scheff's Cat Oct 25 '20 at 17:21
  • @Scheff Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29112 for x86. The code looks perfectly reasonable to me. At least >= c++17 – doug Oct 25 '20 at 17:25
  • @Scheff One possibility is that when you changed from x86 to x64 the version info didn't cary over because it was only set for x86. I've screwed that up. – doug Oct 25 '20 at 17:27
  • I rebuilt locally for x86 and get the exact same complaints. I tried on [Compiler Explorer](https://godbolt.org/z/osdr1c) and again no difference. (Btw. I'm using CMake so that I get a VS solution with one platform only - the chance to mixup platforms accidentally is low.) – Scheff's Cat Oct 25 '20 at 17:30
  • That's really strange. We are both running the same compiler and version. Probably go to chat. I can set the compiler verbose mode and post the output if that would help. I'm using the IDE (msbuild) with a solution/project file. Sounds like a difference with CMake. If so this becomes a more critical question. – doug Oct 25 '20 at 17:34
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/223593/discussion-between-scheff-and-doug). – Scheff's Cat Oct 25 '20 at 17:37
  • After a long discussion, @doug helped me to find out that this seems to be subject of the 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. I will compare the options to find out the significant difference and post an update if I found something... – Scheff's Cat Oct 25 '20 at 18:14