2013-03-07 155 views
1
options->dict_size = UINT32_C(1) << (uint8_t []){ 
     18, 20, 21, 22, 22, 23, 23, 24, 25, 26 }[level]; 

http://svn.r-project.org/R/trunk/src/extra/xz/lzma/lzma_encoder_presets.c化合物C99字面等效在MSVC

#ifndef UINT32_C 
# if UINT_MAX != 4294967295U 
#  error UINT32_C is not defined and unsigned int is not 32-bit. 
# endif 
# define UINT32_C(n) n ## U 
#endif 

编译此为窗户。但越来越语法错误

error C2059: syntax error : '{' 

error C2143: syntax error : missing ';' before '{' 

error C2337: 'level' : attribute not found 

typedef struct { 
    uint32_t dict_size; 
    // ... 
} lzma_options_lzma; 

有没有人尝试过呢?

此外,我从来没有见过像uint8_t []{...}[level]这样的代码;

这是什么意思?

+0

怎么样分别声明数组? – 2013-03-07 09:06:09

+0

我试过..但是const uint32_t level = preset&LZMA_PRESET_LEVEL_MASK;水平已经被宣布,我无法解释如何调整(uint8_t [])18,20,21,22,22,23,23,24,25,26} [level]; – Capricorn 2013-03-07 09:10:43

回答

5
const static uint8_t shift_lookup[] = { 
    18, 20, 21, 22, 22, 23, 23, 24, 25, 26 }; 
options->dict_size = UINT32_C(1) << shift_lookup[level]; 

其中shift_lookup是一些尚未在代码中使用的名称。

(uint8_t []){...}是一个C99复合文字,它是一个未命名的数组类型的对象。 MSVC不执行C99。为了在C89中获得相同的结果,你必须给它一个名字。

(uint8_t []){...}[level]是数组的正常索引操作符,应用于文字。

对于这种特定的情况,如果数组恰好是字符类型,C89实际上已经有一种可以工作的字面量:字符串文字。

options->dict_size = UINT32_C(1) << "\x12\x14\x15\x16\x16\x17\x17\x18\x19\x1a"[level]; 

虽然我不推荐它。

+1

+1为可怕的字符串使用!:) – unwind 2013-03-07 12:34:03

+0

谢谢史蒂夫。我应该认为这是非常简单的 – Capricorn 2013-03-07 12:36:42

4

这是一个C99 compound literal

它定义了一个数组,然后在同一个表达式中将数组索引到数组中。如果level为零,则它将移位18位,如果它是一位,它将移位20位,依此类推。

如果您试图使用Visual Studio进行构建,那就是您的问题,因为Visual Studio不支持C99。

修复它需要重构删除内联数组,而不是使其成为一个常规数组。

+0

如何使用MSVC获得相同的效果?我尝试使用类似这样的东西:options-> dict_size = UINT32_C(1)<<(uint8_t level []){ \t \t \t 18,20,21,22,22,23,23,24,25,26};但没有运气。我需要使用开关吗? – Capricorn 2013-03-07 08:57:26

+0

@Capricorn:As * unwind“写道:VC不支持复合文字。 – alk 2013-03-07 10:36:50