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

#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

これを Windows 用にコンパイルします。しかし、構文エラーが発生します

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]

どういう意味ですか?

4

2 に答える 2

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];

ただし、お勧めしません。

于 2013-03-07T10:26:09.617 に答える
4

それはC99 複合リテラルです。

配列を定義してから、同じ式で配列にインデックスを付けています。が 0 の場合levelは 18 ビット分シフトし、1 の場合は 20 ビット分シフトします。

これを Visual Studio でビルドしようとしている場合、Visual Studio は C99 をサポートしていないため、それが問題になります。

これを修正するには、リファクタリングしてインライン配列を削除し、代わりに通常の配列にする必要があります。

于 2013-03-07T08:38:46.697 に答える