Non-type template parameter type changes randomly
Asked Answered
D

1

12

I am unsure whether this is a compiler bug, or whether I have done something that goes against the standard to cause undefined behaviour. Here is my code:

#include <iostream>
template<auto InputSize, typename SizeType = decltype(InputSize)>
class StaticArray
{
public:
    using size_type = SizeType;
    using size_type2 = decltype(InputSize);
};

int main()
{
    //StaticArray<2, int> s1;
    StaticArray<2ull, int> s3;
    std::cout << typeid(decltype(s3)::size_type).name() << "\t" << typeid(decltype(s3)::size_type2).name() << "\n";
    return 0;
}

If the commented out line stays commented out, I get the correct output: int unsigned __int64. However, if I uncomment the line, I get the output int int. For reference I am compiling this in x86 debug, on MSVC 2017 v15.9.2.

Depersonalize answered 4/7, 2019 at 11:5 Comment(6)
This looks like an obvious compiler bug.Burress
s1 has nothing to do with the following lines. Has to be a bug.Rouse
@L.F. I was not sure whether I was violating something regarding templates (I just learned today that I could use auto in the template parameter list), which was causing UB. If it's indeed a bug, I'll report it to MS.Depersonalize
auto in templates is still an experimental feature in all compilers. So sometimes it may not work.Branle
@Branle experimental? It's C++17 though...Minutes
Not including <typeinfo> makes this program ill-formedJoyce
G
5

It looks like a compiler bug, please see https://godbolt.org/z/k2ng-1 . If the version of MSVC is less or equal of 19.16 it has the problem you showed, from 19.20 everything works fine.

Edit: below the test code should the link break in the future:

#include <type_traits>

template<auto InputSize, typename SizeType = decltype(InputSize)>
class StaticArray
{
public:
    using size_type = SizeType;
    using size_type2 = decltype(InputSize);
};

int main()
{
    StaticArray<2, int> s1;
    StaticArray<2ull, int> s3;

    static_assert(std::is_same_v<decltype(s3)::size_type, int>, "ERROR 1");
    static_assert(std::is_same_v<decltype(s3)::size_type2, unsigned long long>, "ERROR 2");
}
Gender answered 4/7, 2019 at 11:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.