[cfe-dev] Class Template Argument Deduction failure

Arthur O'Dwyer via cfe-dev cfe-dev at lists.llvm.org
Mon Apr 29 07:12:50 PDT 2019


On Mon, Apr 29, 2019 at 5:46 AM Lorenzo Cavallini via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Hello everyone,
> I'm writing to report what I think is an issue related to Class Template
> Argument Deduction (CTAD for short). Compiling this short snippet:
>
> #include <cstdio>
> #include <vector>
>
> template<typename T>
> void printV(const std::vector<T>& v)
> {
>     if (v.size() == 1) {
>         printf("%d ", v[0]);
>         return;
>     }
>     int middle = v.size()/2;
>     printV(std::vector{v.begin(), v.end()+middle});
> }
>
> int main()
> {
>     std::vector<int> v = {10,1};
>     printV(v);
>     return 0;
> }
>
> will result in clang generating an infinite error report (at least, I left
> it running for several hours, then I stopped the process...), due to (I
> guess) wrongly deducted template arguments.
>

The Clang issue is not related to CTAD.  You can achieve the same
"infinite" error message via explicitly (wrongly) supplied template
arguments, too. Just replace

    printV(std::vector{v.begin(), v.end()+middle});
with

    using VI = std::vector<typename std::vector<T>::const_iterator>;
    printV(VI{v.begin(), v.end()+middle});

By the way, CTAD is behaving as intended here: you gave an initializer-list
of const_iterators, and so you get a vector of const_iterators. If you
didn't want a vector of const_iterators, you should have used the
sequence-container-constructor syntax (round parens), not the
braced-initializer-list syntax (braces).
See also "*Contra* CTAD"
<https://quuxplusone.github.io/blog/2018/12/09/wctad/> and "The Knightmare
of Initialization in C++"
<https://quuxplusone.github.io/blog/2019/02/18/knightmare-of-initialization/>
.

Here's an ultra-reduced test case.

[[nodiscard]] int dummy();


template<class T>

void printV(T t) {

    dummy();

    printV(&t);

}


int main() {

    printV(42);

}

The same O(1024^2) lines of error output are produced, but much faster,
because Clang doesn't have to instantiate all those nested template types
(or render their names in the error messages).

I think it might be convenient if Clang lowered the nested template limit
from 1024 to, say, 32, in the case that a warning or error message has been
produced already.

–Arthur
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190429/69bc942e/attachment.html>


More information about the cfe-dev mailing list