Если я напишу следующий код CUDA:
#include <stdio.h>
template <unsigned N>
__global__ void foo()
{
printf("In kernel foo() with N = %u\n", N);
if (N < 10) { return; }
printf("Wow, N is really high!\n");
/* a whole lot of code here which I don't want to indent */
}
int main() {
foo<5><<<1,1>>>();
foo<20><<<1,1>>>();
return 0;
}
Я получаю предупреждение компилятора:
a.cu(8): warning: statement is unreachable
detected during instantiation of "void foo<N>() [with N=5U]"(12): here
Я «чувствую», что не должен получать это предупреждение, поскольку недоступный код недоступен только для определенных значений параметра шаблона. И если я напишу «эквивалент процессора», так сказать:
#include <cstdio>
template <unsigned N>
void foo()
{
std::printf("In kernel foo() with N = %u\n", N);
if (N < 10) { return; }
std::printf("Wow, N is really high!\n");
/* a whole lot of code here which I don't want to indent */
}
int main() {
foo<5>();
foo<20>();
return 0;
}
и построить это с помощью gcc (5.4.0) — я не получаю никаких предупреждений, даже если я компилирую с -Wall
,
Теперь я могу обойти это, написав
if (not (N < 10)) {
printf("Wow, N is really high!\n");
/* a whole lot of code here which I don't want to indent */
}
но я бы предпочел избежать необходимости обращать свою логику, чтобы прыгать через «обруч» nvcc. Я мог бы также написать
if (not (N < 10)) {
return;
}
else {
printf("Wow, N is really high!\n");
/* a whole lot of code here which I don't want to indent */
}
но — я не хочу делать отступ для всего этого кода (и та же проблема может возникнуть снова, требуя еще большего отступа внутри блока else.
Есть ли что-то, что я мог сделать? Кроме того, не является ли это «ошибкой» или ошибкой, о которой я должен сообщить как ошибка?
Как насчет:
template<unsigned N, bool>
struct FooImpl
{
static void foo()
{
std::printf("In kernel foo() with N = %u\n", N);
}
};
template<unsigned N>
struct FooImpl<N, false>
{
static void foo()
{
std::printf("In kernel foo() with N = %u\n", N);
std::printf("Wow, N is really high!\n");
/* a whole lot of code here which I don't want to indent */
}
};
template <unsigned N>
__global__ void foo()
{
FooImpl<N, N < 10>::foo();
}
Других решений пока нет …