3

I am using Visual C++ express 2008 try to compile code similar to below:

no problem

{
  ...
  AVRational test = {1, 1000};
  ...
}

but has problem when it is as below:

{
  ...
  AVRational test = (AVRational){1, 1000};
  ...
}

gave errors:

1>..\..\..\projects\test\xyz.cpp(1139) : error C2059: syntax error : '{'
1>..\..\..\projects\test\xyz.cpp(1139) : error C2143: syntax error : missing   ';' before '{'
1>..\..\..\projects\test\xyz.cpp(1139) : error C2143: syntax error : missing ';' before '}'

where AVRational (ffmpeg.org library) is defined as:

typedef struct AVRational{
    int num; ///< numerator
    int den; ///< denominator
} AVRational;

FFmpeg come with some pre-define value such as

#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}

which is used as below

av_rescale_q(seek_target, AV_TIME_BASE_Q, pFormatCtx->streams[stream_index]->time_base);

will failed to compile on Visual C++ express 2008

It seem like the same code will be compiled with no error/warning on gcc compiler. Why I get this error on VC++? Is it a C/C++ standard way to do casting on struct value? Anyway I can avoid this error while still able to use the defined AV_TIME_BASE_Q?

Sany Liew
  • 1,615
  • 21
  • 25
  • try surrounding your { } with ( ) ... I've seen that work in other contexts. – HypnoToad Apr 13 '14 at 03:52
  • do you mean do something like this "av_rescale_q(seek_target, (AV_TIME_BASE_Q), pFormatCtx->streams[stream_index]->time_base);"? Not working too. Similar errors appear. – Sany Liew Apr 13 '14 at 03:58
  • 6
    `AVRational test = (AVRational){1, 1000};` is not valid C++. It's a C99 feature called "compound literals", and gcc supports it as an extension. – Brian Bi Apr 13 '14 at 03:59
  • After a quick review of the ffmpeg.org site, which says it is platform independent, what FFmpeg version is being used? – CPlusPlus OOA and D Apr 13 '14 at 04:08
  • So, i think the problem is because VC++ 2008 does not support C99. Seem like VC++ 2013 does support that. Also I actually able to pass in a local AVRational test variable into av_rescale_q. It just that I can't use the predefined AV_TIME_BASE_Q. I must redefined it myself without the "compound literals". – Sany Liew Apr 13 '14 at 04:10
  • I think should not be too old as I downloaded from http://ffmpeg.zeranoe.com/builds/ which provided the static dev ffmpeg library for Windows. I think it is 2.0.1. – Sany Liew Apr 13 '14 at 04:22
  • Just tested. VC++ express 2013 does NOT allow the "compound literals" too. – Sany Liew Apr 13 '14 at 06:23
  • 1
    For possible fixes, have a look at http://stackoverflow.com/questions/3869963/compound-literals-in-msvc – cup Apr 13 '14 at 10:10

3 Answers3

7

Use av_get_time_base_q() instead of AV_TIME_BASE_Q for C++ or VS. This was fixed in a patch

Dmitry
  • 260
  • 3
  • 13
3

VC++ 2013 does not allow compound literals in C++ but it allows them in C. Options:

  1. Rename your program with a .c suffix
  2. Switch on the /TC flag for the program that does not compile.

The other alternative if you wish to keep to C++ is to change the declaration of AV_TIME_BASE_Q in the header file

static const AVRational AV_TIME_BASE_Q = {1, AV_TIME_BASE};

Then it will be using the constant instead of the compound literal.

cup
  • 7,589
  • 4
  • 19
  • 42
  • You are right. By right clicking the project -> properties -> configuration properties -> C/C++ -> Advanced -> compile as -> use the /TC option instead of default option, then the code will be compiled successfully. Did on VC++ express 2013. Thank you. – Sany Liew Apr 14 '14 at 06:54
0

For compound-literals errors in C++

wrong:

 this->buffer.enqueue((tone_t) { duration, frequency });

correct:

tone_t tone = { duration, frequency };
this->buffer.enqueue(tone);
Mike Yang
  • 2,581
  • 3
  • 24
  • 27