Инициализация диапазона массива C - PullRequest
5 голосов
/ 18 октября 2011

Очень простой вопрос , где работает этот код?

static void *gostruct[] = 
{
    [0 ... 255] = &&l_bad,
    ['\t'] = &&l_loop, [' '] = &&l_loop, ['\r'] = &&l_loop, ['\n'] = &&l_loop,
    ['"'] = &&l_qup,
    [':'] = &&l_loop,[','] = &&l_loop,
    ['['] = &&l_up, [']'] = &&l_down, // tracking [] and {} individually would allow fuller validation but is really messy
    ['{'] = &&l_up, ['}'] = &&l_down,
    ['-'] = &&l_bare, [48 ... 57] = &&l_bare, // 0-9
    ['t'] = &&l_bare, ['f'] = &&l_bare, ['n'] = &&l_bare // true, false, null
};

Прочитав его, ясно, что он инициализирует массив, содержащий 256 записей, для значения && l_bad и затем переопределяетопределенные индексы с конкретными значениями.Но этот код не компилируется в VS2010, к которому у меня есть доступ, поэтому мне интересно, где это допустимый код C.

ПРИМЕЧАНИЕ. Этот фрагмент кода был взят из анализатора JSON на github что, насколько я понимаю, создает таблицы переходов для обработки строк JSON.

Ответы [ 4 ]

9 голосов
/ 18 октября 2011

Эта конструкция называется Назначенные инициализаторы .
Использование Диапазон в Назначенных инициализаторах является специфическим расширением GNU gcc.

Чтобы инициализировать диапазон элементов одним и тем же значением, напишите [first ... last] = value.Это расширение GNU.Например,

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

Компиляция с помощью -pedantic скажет вам об этом.
Обратите внимание, что это непереносимо, поскольку это расширение, специфичное для компилятора.

3 голосов
/ 18 октября 2011

Используется расширение номера GNU C.

http://www.gnu.org/s/gnu-c-manual/gnu-c-manual.html

'as a GNU C extension, you can initialize a range of elements 
to the same value, by specifying the first and last indices, in the 
form [first] ... [last]'

'As a GNU C extension, you can also take the address of a label 
with the label address operator &&. The result is a void* pointer 
which can be used with goto.'

Похоже, это наиболее вероятно, используется как таблица переходов для парсера, весь этот разделпотребуется переписать, если вы собираетесь портировать его на windows.

Вы, вероятно, обнаружите, что вы реализуете простой оператор switch и замените переходы lookup и goto, что-то вроде perl поможет вам с 'набрав 'упражнения:)

2 голосов
/ 27 августа 2014

По ссылке

В ISO C99 вы можете задавать элементы в любом порядке, указав индексы массива или имена структурных полей, к которым они применяются, и GNU C позволяет это как расширение в режиме C90. Это расширение не реализовано в GNU C ++.

И диапазон, и определенный инициализатор поддерживаются ISO C99 и не только расширением GNU. Вы можете попробовать включить ISO C99 (я не знаю как) в Visual Studio 2010.

Ссылка: https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

1 голос
/ 18 октября 2011

Использование диапазонов в назначенных инициализаторах является расширением gcc, не поддерживаемым в стандарте C99.

Также код принимает адрес меток, который, как я считаю, также является расширением gcc.

ТакНет, это не правильный код C, просто правильный код gcc c.

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