Ошибка переключения :: не может появиться в константном выражении - PullRequest
6 голосов
/ 29 сентября 2010

это странно ...

Я играю с некоторым алгоритмом декомпрессии. Вместо того, чтобы проходить через char buffer[] и выполнять циклы до тех пор, пока не будет найден стоп-бит в buffer[i], я пытаюсь использовать некоторые приемы битовой маски, но с символами.

У меня есть следующий пример:

// In a *.h file  
const char ch = '\x81';  
// To avoid Endianess  
union CharUInt  
{  
    char sz[4];  
    unsigned int u;  
};  
// Legal because char[] is declared before uint32 in the union  
const CharUInt Mask1 = {'\x81', '\x0', '\x0', '\x81'};  
const CharUInt Mask2 = {'\x0', '\x81', '\x81', '\x0'};  
// Proxy / Auxillary uint32 as usimg Mask2.u in the switch blocked produced the same errors  
const unsigned int uMask1 = Mask1.u;  
const unsigned int uMask2 = Mask2.u;  
const unsigned int uMask_ = (uMask1 & uMask2);  
// buf is always long enough  
bool Foo(char buf[])  
{  
    const CharUInt Type = {buf[0], buf[1], buf[2], buf[3]};  
    unsigned int uType = (Type.u & uMask_);  
    switch(uType)  
    {  
    case uMask1:  
        // do stuff  
    case uMask2:    
        // do more stuff  
        return true;  
        break;  
    default:  
        // do different stuff  
        return false;  
        break;  
    }  
};  

Не принимая во внимание синтаксис union (фактические компиляции кода работают нормально для этого) и не учитывая, хороша ли функция-возвращение для Foo, я получаю
'uMask1' cannot appear in a constant-expression
и если используются сами союзы, я получаю
'Mask1' cannot appear in a constant-expression
'.' cannot appear in a constant-expression
и, конечно, ошибки также относятся к uMask2 и Mask2.u

Что мне не хватает?

Заранее спасибо

Ответы [ 2 ]

6 голосов
/ 29 сентября 2010

Путаница возникает из-за того, что const и const равны двум.

Случаи в выражении switch требуют «константных выражений».Или другими словами: выражения, которые могут быть «вычислены» компилятором во время компиляции.Это может быть жестко запрограммированное число (например, 42), или что-то, что было определено ранее как число (с использованием #define).

Const также используется компилятором со значением «как только эта переменнаязначение, оно больше не изменится ".Например, в следующем коде:

void myFunction (const int value)
{
...
}

значение будет постоянным.Я не смогу изменить значение const, но это не делает его «постоянным выражением» для компилятора.

В вашем случае, uMask1 является const (больше не может его изменить), но неконстантное выражение.

1 голос
/ 29 сентября 2010

case выражение условия должно иметь целочисленный тип или быть преобразованным в целочисленный тип и должно быть постоянным

6.4.2 [stmt.switch]

Условиедолжен иметь целочисленный тип, тип перечисления или тип класса, для которого существует одна функция преобразования в целочисленный тип или тип перечисления (12.3).Если условие относится к типу класса, условие преобразуется путем вызова этой функции преобразования, и результат преобразования используется вместо исходного условия для оставшейся части этого раздела.Интегральные акции выполняются.Любой оператор в операторе switch может быть помечен одной или несколькими метками регистра следующим образом:

выражение константы регистра:

где выражение константы должно быть интегральным выражением константы.Интегральное выражение-константа (5.19) неявно преобразуется в повышенный тип условия переключения.Никакие две константы регистра в одном и том же переключателе не должны иметь одинакового значения после преобразования в продвинутый тип условия переключателя.

Ваше выражение не является константным выражением, даже если сама переменнаяconst, поэтому вы не можете включить его.Вам нужно будет использовать if.

У вас есть еще одна проблема:

Вы создаете union,

union CharUInt  
{  
    char sz[4];  
    unsigned int u;  
};

... затем выинициализируйте sz члена этого объединения,

static const CharUInt Mask1 = {'\x81', '\x0', '\x0', '\x81'};  

... и затем вы получите доступ к u члену этого объединения.

static const unsigned int uMask1 = Mask1.u;  

Это вызывает неопределенное поведение в соответствии сстандарт.На языке стандарта 2 члена профсоюза не могут быть активными одновременно.Это означает, что вы не можете относиться к союзу как к заклинателю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...