2013-06-26 5 views
2

Независимо от любых потенциальных ловушек это использование, я нашел этот фрагмент кода в одном из заголовочных файлов FFmpeg:C++ из C99 временной локальной переменной массива

/** 
* Convenience macro, the return value should be used only directly in 
* function arguments but never stand-alone. 
*/ 
#define av_err2str(errnum) \ 
    av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, AV_ERROR_MAX_STRING_SIZE, errnum) 

Мой вопрос о (char[AV_ERROR_MAX_STRING_SIZE]){0}.
Он по существу создает массив char[] в стеке и передает его адрес стека как char*, который должен быть заполнен на месте av_make_error_string().

Это синтаксис C99.

Имеет ли pre-C++ 11 эквивалентный синтаксис?
Будет ли это также работать с C++ 11?

+0

Используйте различные настройки C++ на ideone.com и попробуйте сами? http://ideone.com/ – kfsone

+0

Возможный дубликат [C++ Compound literal] (http://stackoverflow.com/questions/9436480/c-compound-literal) –

ответ

3

Да, но в C++ время жизни массива фактически что-то временно (только живое на протяжении всего его выражения выражения выражения, грубо говоря). На вашем примере C99 время жизни массива будет на самом деле его окружающим блоком.

template<int I> 
struct Array { 
    Array() {} 
    char data[I]; 
}; 

Тогда вы можете сказать

av_make_error_string(
    (Array<AV_ERROR_MAX_STRING_SIZE>().data, 
    AV_ERROR_MAX_STRING_SIZE, 
    errnum) 

Единственная цель определенного пользователем конструктора, чтобы предотвратить нулевой инициализацию data, когда вы делаете на Array<>(). Если вы хотите инициализировать его, удалите конструктор. Разумеется, boost :: array просто работает так же, как и

av_make_error_string(
    (boost::array<char, AV_ERROR_MAX_STRING_SIZE>().c_array(), 
    AV_ERROR_MAX_STRING_SIZE, 
    errnum) 
+0

Хороший ответ. Интересно, нет ли способа синтаксиса на чистом языке (как на C99), т. Е. Нет необходимости в дополнительных классах. –