使用vs2015编译ffmpeg的编码demo,其中有一行为:
printf("Send frame %3"PRId64"\n", frame->pts);
该demo只有一个文件:encode_video.c
编译很顺利,一次性通过,而且可以正常运行。后添加了解码文件,所以就把这个文件改成了 encode_video.cpp,然后再编译,结果就编译不过了,提示如下:
encode_video.cpp(43): error C3688: 文本后缀“PRId64”无效;未找到文文本运算符或文本运算符模板“operator """"PRId64”
开始半天没想通,因为也没有添加什么新的头文件,也没有做过什么编译选项的修改,PRId64的定义如下:
#define PRId64 "lld"
再仔细查看,也还是能找到这个定义,说明不是包含头文件的问题。后来突然想到,文件的扩展名由.c改为.cpp,那应该是c、c++编译器之间的差别,于是修改为如下的样子:
printf("Send frame %3" PRId64 "\n", frame->pts);
在 PRId64 两边各自加上一个空格,然后再编译顺利通过。
从这个问题的解决可以看出,
c支持的形式:"abc""defg""hijk",它相当于所有的字符串连接起来:"abcdefghijk"
c++支持的形式:"abc" "defg" "hijk",即每段字符串中间应该加空格,它相当于所有的字符串连接起来:"abcdefghijk"
其实这个结论并不完全正确,我把定义直接找成字符串后再测试发现(注:以下没有用.c测试,而是中测试了.cpp的情形)如下的情况:
printf("Send frame %3""lld""\n", frame->pts);
printf("Send frame %3" "lld" "\n", frame->pts);
以上的两行都可以编译通过。如此说来,就是如果直接使用字符串,则两段之间是否加空格都不要紧,但如果使用了预定义的字符串,则预定义符号的两边应该加上空格。这样的规则,也许是为了防止预定义符号和某些字符串挨着时产生误解吧