4

I'm currently debugging an issue in our build where in variadic arguments, the number of arguments ain't as expected.

Currently my code looks similar to:

class CustomException : public BaseException
{
public:
    template<typename ...T>
    CustomException(T &&...args) : BaseException(std::forward<T>(args)...)
    {
        static_assert(sizeof...(T) == 2);
    }
};
throw CustomException{size_t{}, size_t{}};

Based on this code, one would expect 2 arguments are being passed to the Ctor.

Surprisingly, this code does as expected with MSVC and fails on the static_assert with Clang.

Does any of you know a trick to force clang to reveal what it assumes the variadic argument pack is?

Edit Problem is related to copy construction that is required to throw, very specific to Clang-Cl

JVApen
  • 11,008
  • 5
  • 31
  • 67
  • 2
    Maybe [__PRETTY_FUNCTION__ can help](https://stackoverflow.com/a/16338804/1708801) – Shafik Yaghmour Sep 01 '18 at 09:03
  • one of these static asserts is guaranteed to fail so this code should not compile – user7860670 Sep 01 '18 at 09:15
  • [no repro](https://wandbox.org/permlink/pJawjxyFSZwTjj3G), code fails only on one static assert with clang – user7860670 Sep 01 '18 at 09:19
  • 1
    [still no repro](https://wandbox.org/permlink/PdCLh5qmk4LDi1WL), throw does not change anything – user7860670 Sep 01 '18 at 09:21
  • Possible duplicate of [static\_assert dependent on non-type template parameter (different behavior on gcc and clang)](https://stackoverflow.com/questions/30078818/static-assert-dependent-on-non-type-template-parameter-different-behavior-on-gc) – Passer By Sep 01 '18 at 13:40
  • This is technically UB, so clang can do whatever it wants. If you want to print something, you could `[[deprecated]] template struct print {};` – Passer By Sep 01 '18 at 13:43
  • Well, the answer seems to spot a bug, but in my defense the question _is_ UB. – Passer By Sep 01 '18 at 13:45
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/179244/discussion-between-jvapen-and-passer-by). – JVApen Sep 01 '18 at 13:50
  • `template CustomException(T &&...args)` -- that is code smell. Do not have over greedy ctors. `CustomException()` and `template, CustomExceptiom>{}, bool> =true>(T0&&, Ts&&...)`. – Yakk - Adam Nevraumont Sep 01 '18 at 15:08

1 Answers1

2

The problem on hand seems to be a compiler bug, logged as https://bugs.llvm.org/show_bug.cgi?id=38801

The full reproduction:

test.cpp

struct A
{
   template<typename ... T>
   A(T &&...t)
   {
      static_assert(sizeof...(T) == 2);
   }

   A(const A &) = default;
   //A(A &) = default;
   A(A &&) = default;
   A &operator=(const A &) = default;
   A &operator=(A &&) = default;
};


int main(int, char **)
{
   throw A{size_t{}, size_t{}};
   return 0;
}

run.bat

clang-cl.exe -fms-compatibility-version=19.11 /DBOOST_USE_WINDOWS_H -w -Wno-unused-command-line-argument /Zc:inline /nologo /c /GR /EHsc /fp:precise /FS /std:c++17 /diagnostics:caret /O2 /I. /MDd /Zc:forScope /bigobj /Zc:wchar_t test.cpp

error

test.cpp(7,7):  error: static_assert failed
      static_assert(sizeof...(T) == 2);
      ^             ~~~~~~~~~~~~~~~~~
test.cpp(20,10):  note: in instantiation of function template specialization 'A::A<A &>' requested here
   throw A{size_t{}, size_t{}};
         ^
1 error generated.
JVApen
  • 11,008
  • 5
  • 31
  • 67