Что-нибудь не так с (char[32]) {0} в Visual Studio 2012?

#c #visual-studio #ffmpeg

#c #visual-studio #ffmpeg

Вопрос:

===== Предыстория ====

Эта проблема возникает из-за использования примера мультиплексирования библиотеки fFmpeg.c в visual studio 2012, я обнаружил ошибку:

 error C2143: Syntax error missing ) before {
  

в

 printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%dn",
    av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
    av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
    av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
    pkt->stream_index);    
  

и я нашел

 #define AV_TS_MAX_STRING_SIZE 32
#define av_ts2str(ts) av_ts_make_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts)
  

для устранения нерелевантного оператора я просто заменяю большой printf на

 printf("pts:%s n",
    (char[32]){0}
    );
  

но ошибка все та же, похоже, ошибка из

 (char[32]){0}
  

===== вопрос ====

Поскольку этот пример исходного файла muxing.c является официальным (я думаю), возможно, это не так, так что утверждение неверно или несовместимо с компилятором VS? или я здесь чего-то не хватает?

Комментарии:

1. Этот блог и документы ffmpeg предполагают, что он опирается на поддержку C99. Visual Studio поддерживает только C89. Вы можете либо скомпилировать в Windows с использованием gcc (что может быть непросто при настройке), либо перейти по ссылкам выше к инструменту преобразования, который изменяет исходный код ffmpeg, чтобы он соответствовал C89

2. (char[32]){0} является составным литералом. Это особенность C99. Компиляторы Microsoft «C» не поддерживают C99, что является позором. Попробуйте использовать порт MinGW GCC для компиляции вашего кода.

3. Составные литералы поддерживаются в VS2013.

4. @tab Я пробовал с visual 2013, но там безуспешно.

Ответ №1:

Конструкция, которая выглядит как приведение блока фигурных скобок к массиву, называется составным литералом. Это одна из функций C99, которая не была реализована в линейке компиляторов Visual Studio.

К сожалению, простого способа исправить эту проблему не существует, поскольку составной литерал создает временный анонимный массив, который автоматически освобождается. Следовательно, ваш nice short printf был бы преобразован во что-то вроде этого:

 char buf1[AV_TS_MAX_STRING_SIZE] = {0};
av_ts_make_string(buf1, pkt->pts);
char buf2[AV_TS_MAX_STRING_SIZE] = {0};
av_ts_make_string(buf1, pkt->dts);
char buf3[AV_TS_MAX_STRING_SIZE] = {0};
av_ts_make_string(buf1, pkt->duration);

printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%dn",
    buf1, av_ts2timestr(pkt->pts, time_base),
    buf2, av_ts2timestr(pkt->dts, time_base),
    buf3, av_ts2timestr(pkt->duration, time_base),
    pkt->stream_index);   
  

Ответ №2:

Помимо того, что говорит dasblinkenlight, есть способ скомпилировать ffmpeg (и, возможно, другой исходный код, использующий эту и другие конструкции C99) с MSVC. Скрипт может автоматически преобразовать этот код C99 в, надеюсь, эквивалентный код C89.

Подробности смотрите здесь.