Problems with using `sizeof` in `requires` clause

This should compile, but it doesn’t

template <typename... U>
constexpr auto adder(U... u) ->  bool
    requires(sizeof...(U) == 3)
{
    return true;
}



bool f()
{
   return adder<int>(2,34,45);
}

I talked with engineering who agree that is a compiler issue and we’ve added TPR#33322 to track.

The work around would be to change:

return adder<int>(2,34,45);

to

return adder<int,int,int>(2,34,45);

Thanks for the report,
Mat

Thanks a for a quick reply. I’ll use the work-around for now.

Hi j.badwaik,

We should have TPR #33322 fixed in our 23.5 release.

% nvc++ --c++20 vpreq.cc -V23.3
"vpreq.cc", line 13: error: no instance of function template "f" matches the argument list
            argument types are: (int, unsigned int, double)
    f<int>(1, 2u, 3.0); // error
    ^

"vpreq.cc", line 14: error: no instance of function template "g" matches the argument list
            argument types are: (int, unsigned int, double)
    g<int>(4, 5u, 6.0); // error
    ^

2 errors detected in the compilation of "vpreq.cc".
% nvc++ --c++20 vpreq.cc -V23.5
%

Thanks again for the report,
Mat

Thank you! :-)

Hello, I have tried it out using nvcc version 12.1 and nvc++ version 23.5 and it still does not work on both of them using this example, even with the suggested temporary fix.

#include <concepts>
#include <iostream>

unsigned sum(std::unsigned_integral auto... args) requires (sizeof...(args) > 1)
{
  return (args + ...);
}

int main()
{
  std::cout << sum<unsigned, unsigned, unsigned, unsigned>(1u, 2u, 3u, 6u) << std::endl;
}

Thanks for the report dejvnayer. This is a similar but unrelated issue.

For this issue, it appears that nvc++ is having issues when a function parameter pack is expanded in a requires clause. I’ve added a problem report, TPR #33824, and sent it to engineering for investigation.

The work around would be to use a template parameter pack:

#include <concepts>
#include <iostream>

template <std::unsigned_integral... Args>
unsigned sum(Args... args) requires (sizeof...(Args) > 1)
{
  return (args + ...);
}

int main()
{
  std::cout << sum<unsigned, unsigned, unsigned, unsigned>(1u, 2u, 3u, 6u) << std::endl;
}

-Mat

1 Like

Thank you, Mat. I do not know if I explained clearly enough, but this issue is present when using nvcc as well, it is not related only to nvc++. I have tried it out using nvcc and gcc 12.1 and it emmits the same error.

David

Hi David,

nvcc seems to work fine for me when using g++ 12.1 as the host compiler.

Is it the exact same error? If so, my guess is that nvcc is configured to use nvc++ as the host compiler. If it’s a different error, you might be using an older g++ which doesn’t support concepts.

Here’s my output:

% g++ --version
g++ (GCC) 12.1.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

% nvcc --std=c++20 test2.cpp -ccbin g++
% a.out
12

% nvcc --std=c++20 test2.cpp -ccbin nvc++
"test2.cpp", line 11: error: no instance of function template "sum" matches the argument list
            argument types are: (unsigned int, unsigned int, unsigned int, unsigned int)
    std::cout << sum<unsigned, unsigned, unsigned, unsigned>(1u, 2u, 3u, 6u) << std::endl;
                 ^

1 error detected in the compilation of "test2.cpp".

-Mat

Hi Mat,

the problem in your case is that your file is treated as C++ file. When I rename it to .cpp it works fine as well. Try to rename it to .cu file or run the compilation like:

$ nvcc --std=c++20 -x cu test2.cpp -ccbin g++

Now you should get this error message

$ nvcc -ccbin /usr/bin/g++-12 -std=c++20 -x cu test2.cpp
$ test2.cpp(11): error: no instance of function template "sum" matches the argument list
                 argument types are: (unsigned int, unsigned int, unsigned int, unsigned int)
                 std::cout << sum<unsigned, unsigned, unsigned, unsigned>(1u, 2u, 3u, 6u) << std::endl;
                              ^

1 error detected in the compilation of "test2.cpp".

I tried it out using both GCC 11.3 and 12.1 without success.

Thanks.

David

Thanks, I’m now able to replicate the error. Looks to be coming from the CUDA C++ Front-end compiler (cudafe++). This is a different team in NVIDIA so I don’t have direct insights here.

We have a few options:

You can post the same question over on the CUDA nvcc forum: CUDA NVCC Compiler - NVIDIA Developer Forums

You can submit a NVBug from your https://developer.nvidia.com/ account page.

I can submit a NVBug if you prefer, but you wouldn’t get updates so it’s probably better to submit it yourself.

I looked through NVBugs for similar issues, but didn’t see anything. Though I could have missed it.

I have submitted a bug ID 4165263. Thank you, Mat.

Hi David,

I wanted to let you know that TPR #33824, the nvc++ failure, has been fixed in our 23.9 release.

I checked NVBugs for 4165263 and it appears that the nvcc issue has also been fixed in CUDA SDK 12.1.105, though I have not confirmed this.

-Mat

1 Like