Подтвердить что ты не робот

Case switch: ошибка: метка case не сводится к целочисленной константе

int value;

const int signalmin = some_function();

switch(value)
{
   case signalmin:
   break;
}

Я прочитал значение some_function и использую это значение int для включения регистра. Компилятор C99 возвращает:

ошибка: метка регистра не сводится к целочисленной константе

Но я не могу использовать #define потому что значение int читается перед выполнением переключателя.

4b9b3361

Ответ 1

switch метки должны быть постоянными выражениями, их нужно оценивать во время компиляции. Если вы хотите разветвляться на значения времени выполнения, вы должны использовать if.

A const -qualified variable не является константным выражением, это просто значение, которое вам не разрешено изменять.

Форма целочисленных константных выражений подробно описана в 6.6 (6) [C99 и черновик стандарта n1570 стандарта C2011]:

6 Целочисленное константное выражение должно иметь целочисленный тип и должно иметь только операнды которые являются целыми константами, константами перечисления, символьными константами, sizeofвыражения, результаты которых представляют собой целые константы, выражения _Alignof и плавающие константы, которые являются непосредственными операндами приведения. Операторы Cast в целочисленной константе выражение должно преобразовывать только арифметические типы в целые типы, за исключением как части операнд к оператору sizeof или _Alignof.

Ограничение того, что только выражения sizeof, результат которых является целочисленной константой, разрешают исключать выражения sizeof, операнд которых является массивом переменной длины.

Ответ 2

Позвольте мне включить пример. Следующее было протестировано в версии gcc 4.6.3 с флагами -std=c99 -pedantic:

#define SOME_HARDCODED_CONSTANT 0 //good
int foo(int i, int b){
    const int c=0; //bad
    int a=0; //bad

    switch(i){
        case c:     //compile error
        case a:     //compile error.
        case (b+a): //compile error
        case SOME_HARDCODED_CONSTANT: //all good
        case 5: //all good
    }
}

Как отмечали другие, аргументы case не могут быть оценены во время выполнения. Для этого используйте блок if-else.

Ответ 3

В C. Все метки case должны быть константами времени компиляции. В C квалификатор const не создает константу времени компиляции, он просто обозначает, что переменная времени выполнения доступна только для чтения.

A switch не является подходящей структурой управления для того, что вы пытаетесь сделать.

Ответ 4

В C переменные не должны использоваться в ярлыках case switch, а константные выражения разрешены там.

Ответ 5

В OSX, clang, кажется, воспринимает константы как ярлыки case без жалоб.

#include <stdio.h>

#define SOME_HARDCODED_CONSTANT 0 //good for sure
int foo(int i, int b){ 
    const int c=1; //no problem!!!

    switch(i){
        case SOME_HARDCODED_CONSTANT: //all good
            printf("case SOME_HARDCODED_CONSTANT\n"); break;
        case c:     //no compile error for clang
            printf("case c\n"); break;
        case 5: //all good
            printf("case 5\n"); break;
    }   
    return i+b;
}

int main() {
    printf("test foo(1,3): %d\n", foo(1,3));
}

Вывод:

$> cc test.c -o test; ./test 
case c
test foo(1,3): 4