Вопрос:

Как избежать «недостижимого оператора» из-за вычисляемых во время компиляции значений?

c++ cuda compiler-warnings nvcc unreachable-statement

460 просмотра

1 ответ

43430 Репутация автора

Если я напишу следующий код 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.

Есть ли что-то, что я мог сделать? Кроме того, не является ли это «ошибкой» или ошибкой, о которой я должен сообщить как ошибка?

Автор: einpoklum Источник Размещён: 01.04.2017 03:38

Ответы (1)


1 плюс

3741 Репутация автора

Как насчет:

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();
}
Автор: Tomek Размещён: 01.04.2017 06:49
Вопросы из категории :
32x32