Skip to content

<expected> in permissive mode: error C7608: atomic constraint should be a constant expression #4657

@danielvandenberg95

Description

@danielvandenberg95

Describe the bug

In one of my projects, std::expected throws errors
error C7608: atomic constraint should be a constant expression
and
error C2131: expression did not evaluate to a constant
I think the latter is caused by the former.

In order to reproduce the issue, I inlined headers, removing them untill the issue disappeared. and discarding as much code as possible. I ended up with the following code in one file in my project:

// xloctime internal header

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef _XLOCTIME_
#define _XLOCTIME_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#include <ctime>
#include <iterator>
#include <xlocnum>

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

_STD_BEGIN

_EXPORT_STD extern "C++" template <class _Elem, class _OutIt = ostreambuf_iterator<_Elem, char_traits<_Elem>>>
class time_put : public locale::facet { // facet for converting encoded times to text
public:
protected:
    __CLR_OR_THIS_CALL ~time_put() noexcept override {}

    virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem, const tm* _Pt, char _Specifier,
        char _Modifier = '\0') const {
        size_t _Count = 0;
        string _Str = "0";
        return _STD copy(&_Str[1], &_Str[_Count], _Dest); // Removing this line (replacing with return nullptr) causes the error to disappear.
    }

private:
    _Locinfo::_Timevec _Tnames; // locale-specific stuff for _Strftime
};


#if defined(_DLL_CPPLIB)

#if !defined(_CRTBLD) || defined(__FORCE_INSTANCE)
template class _CRTIMP2_PURE_IMPORT time_put<char, ostreambuf_iterator<char, char_traits<char>>>;
#endif // !defined(_CRTBLD) || defined(__FORCE_INSTANCE)

#endif // defined(_DLL_CPPLIB)
_STD_END

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // _STL_COMPILER_PREPROCESSOR
#endif // _XLOCTIME_


#include <expected>
#include <string>

struct test {
    int x;
    int y;
};
using err = std::string;

std::expected<std::pair<int, int>, err> testFunction() {
    return std::pair<int, int>{ 5, 5 };
}

The full output I get while compiling this is:

Build started at 16:36...
1>------ Build started: Project: MyProject, Configuration: Debug x64 ------
1>test.cpp
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\expected(572,18): error C7608: atomic constraint should be a constant expression
1>(compiling source file 'test.cpp')
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\expected(572,18):
1>the template instantiation context (the oldest one first) is
1>	V:\Projects\MyProject\MyProject\test.cpp(77,97):
1>	see reference to class template instantiation 'std::time_put<char,std::ostreambuf_iterator<char,std::char_traits<char>>>' being compiled
1>	V:\Projects\MyProject\MyProject\test.cpp(35,39):
1>	while compiling class template member function '_OutIt std::time_put<char,_OutIt>::do_put(_OutIt,std::ios_base &,_Elem,const tm *,char,char) const'
1>        with
1>        [
1>            _OutIt=std::ostreambuf_iterator<char,std::char_traits<char>>,
1>            _Elem=char
1>        ]
1>	V:\Projects\MyProject\MyProject\test.cpp(66,21):
1>	see reference to function template instantiation '_OutIt std::copy<char*,_OutIt>(_InIt,_InIt,_OutIt)' being compiled
1>        with
1>        [
1>            _OutIt=std::ostreambuf_iterator<char,std::char_traits<char>>,
1>            _InIt=char *
1>        ]
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(4589,31):
1>	see reference to function template instantiation '_OutIt std::_Copy_unchecked<_InIt,_InIt,_OutIt>(_InIt,_Sent,_OutIt)' being compiled
1>        with
1>        [
1>            _OutIt=std::ostreambuf_iterator<char,std::char_traits<char>>,
1>            _InIt=char *,
1>            _Sent=char *
1>        ]
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(4559,23):
1>	see reference to alias template instantiation 'std::_Sent_copy_cat<_InIt,_Sent,_OutIt>' being compiled
1>        with
1>        [
1>            _InIt=char *,
1>            _Sent=char *,
1>            _OutIt=std::ostreambuf_iterator<char,std::char_traits<char>>
1>        ]
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(4446,28):
1>	see reference to variable template 'const bool _Iterators_are_contiguous<char *,std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(4383,40):
1>	see reference to variable template 'const bool _Iterator_is_contiguous<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(4355,49):
1>	see reference to variable template 'bool contiguous_iterator<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(819,31):
1>	see reference to variable template 'bool random_access_iterator<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(807,34):
1>	see reference to variable template 'bool bidirectional_iterator<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(800,34):
1>	see reference to variable template 'bool forward_iterator<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(796,28):
1>	see reference to variable template 'bool input_iterator<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xutility(785,26):
1>	see reference to variable template 'bool input_or_output_iterator<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\__msvc_iter_core.hpp(416,8):
1>	see reference to variable template 'bool weakly_incrementable<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\__msvc_iter_core.hpp(402,32):
1>	see reference to variable template 'bool movable<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\concepts(245,8):
1>	see reference to variable template 'bool swappable<std::ostreambuf_iterator<char,std::char_traits<char> > >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\concepts(124,26):
1>	see reference to variable template 'bool _Use_ADL_swap<std::ostreambuf_iterator<char,std::char_traits<char> > &,std::ostreambuf_iterator<char,std::char_traits<char> > &>' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\expected(572,18):
1>	see reference to variable template 'const bool is_swappable_v<std::pair<int,int> >' being compiled
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\type_traits(2186,60):
1>	see reference to class template instantiation 'std::_Is_swappable<_Ty>' being compiled
1>        with
1>        [
1>            _Ty=std::pair<int,int>
1>        ]
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\type_traits(2147,102):
1>	see reference to class template instantiation 'std::_Is_swappable_with<_Ty &,_Ty &>' being compiled
1>        with
1>        [
1>            _Ty=std::pair<int,int>
1>        ]
1>	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\type_traits(2142,21):
1>	see reference to variable template 'const bool conjunction_v<std::_Swappable_with_helper<std::pair<int,int> &,std::pair<int,int> &,void>,std::_Swappable_with_helper<std::pair<int,int> &,std::pair<int,int> &,void> >' being compiled
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\expected(572,18): error C2131: expression did not evaluate to a constant
1>(compiling source file 'test.cpp')
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\expected(572,18):
1>failure was caused by a read of an uninitialized symbol
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\expected(572,18):
1>see usage of 'std::is_swappable_v<std::pair<int,int>>'
1>Done building project "MyProject.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 16:36 and took 01.019 seconds ==========

When enabling a precompiled header, this error goes away. I can not enable a precompiled header for this project though.

Command-line test case

I have not been able to reproduce it in command line. My attempt has been with:
cl /permissive /MP /GS /TP /W4 /wd"4458" /Gy- /Zc:wchar_t /Zi /Gm- /Od /Ob0 /sdl /Zc:inline /fp:precise /D "_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS" /D "_MBCS" /D "_SILENCE_CXX23_ALIGNED_STORAGE_DEPRECATION_WARNING" /D "_HEAPDEBUG=0" /D "DEBUG=1" /fp:except- /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++latest /FC /EHsc /nologo /diagnostics:column /JMC .\repro.cpp
as these are the closest to the command line options that my actual project is using.

Expected behavior

I would expect this to compile without issue.

STL version

Microsoft Visual Studio Professional 2022
Version 17.9.6

Additional context

I'm still trying to narrow down the issue, but seem to be stuck.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions