[Fixed] non portable use of CFSTR macro in libhb/ports.c

Archive of historical bug reports.
Please use the GitHub link above to report issues.
Forum rules
*******************************
Please be aware we are now using GitHub for issue tracking and feature requests.
- This section of the forum is now closed to new topics.

*******************************
Post Reply
jwardnh
Posts: 2
Joined: Wed Mar 15, 2017 3:43 pm

[Fixed] non portable use of CFSTR macro in libhb/ports.c

Post by jwardnh »

Please describe the problem in as much detail as possible:

We have found a portability issue when compiling libhb/ports.c.

Specifically if you use the Intel Mac compiler (icc) this compilation error occurs:

$ /site/spt/usr13/jward4/workspaces/cfe/dev/build_objs/efi2mac_debug/bin/icc -std=gnu99 -pipe -fmessage-length=0 -Wa ll -arch x86_64 -g0 -O3 -mfpmath=sse -msse2 -D__LIBHB__ -DUSE_PTHREAD -DSYS_DARWIN -DUSE_X265 -DHAS_STRERROR_R -DARC H_X86_64 -I./libhb/ -I./contrib/include -I./contrib/include/libxml2 -c ../libhb/ports.c -o libhb/ports.o
$ icc -std=gnu99 -pipe -fmessage-length=0 -Wall -arch x86_64 -g0 -O3 -mfpmath=sse -msse2 -D__LIBHB__ -DUSE_PTHREAD - DSYS_DARWIN -DUSE_X265 -DHAS_STRERROR_R -DARCH_X86_64 -I./libhb/ -I./contrib/include -I./contrib/include/libxml2 -c ../libhb/ports.c -o libhb/ports.o
icc: command line remark #10148: option '-msse2' not supported
../libhb/ports.c(1273): error: function call is not allowed in a constant expression
CFSTR("HandBrake is currently scanning and/or encoding");
^

compilation aborted for ../libhb/ports.c (code 2)

What are the steps to reproduce this problem:

A simlar error would occur if you compiled using with clang or Apple gcc with the
switch -fno-constant-cfstrings, i.e.:

$ gcc -fno-constant-cfstrings -std=gnu99 -pipe -fmessage-length=0 -Wall -arch x86_64 -g0 -O3 -mfpmath=sse -msse2 -D__LIBHB__ -DUSE_PTHREAD -DSYS_DARWIN -DUSE_X265 -DHAS_STRERROR_R -DARCH_X86_64 -I./libhb/ -I./contrib/include -I./contrib/include/libxml2 -c ../libhb/ports.c -o libhb/ports.o
../libhb/ports.c:1273:5: error: initializer element is not a compile-time constant
CFSTR("HandBrake is currently scanning and/or encoding");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/System/Library/Frameworks/CoreFoundation.framework/Headers/CFString.h:151:22: note: expanded from macro 'CFSTR'
#define CFSTR(cStr) __CFStringMakeConstantString("" cStr "")
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
$

The header file /System/Library/Frameworks/CoreFoundation.framework/Headers/CFString.h defines
the macro CFSTR conditionally depending upon whether an Apple specific builtin is available, i.e.:

#if TARGET_OS_WIN32 || TARGET_OS_LINUX
#undef __CONSTANT_CFSTRINGS__
#endif

#ifdef __CONSTANT_CFSTRINGS__
#define CFSTR(cStr) ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))
#else
#define CFSTR(cStr) __CFStringMakeConstantString("" cStr "")
#endif

If the latter definition is used (which would happens if the switch is used of TARGET_OS_LINUX or TARGET_OS_WIN32 is TRUE) then the code will not compile. This is because in C you are not allowed
to call a function (in this case __CFStringMakeConstantString) at global scope before main.
The builtin happens to work because it is folded, but that is an implementation defined detail
that your code is relying on if you want it to be portable.

Suggested fix:

Change the code so the initialization happens inside a function. In the case the function call is
initializing a variable called reasonForActivity which is only used inside hb_system_sleep_private_disable(). So move the variable inside that function.

Suggested change:

$ diff -c ports.c.orig ports.c
*** ports.c.orig Wed Mar 15 11:35:07 2017
--- ports.c Wed Mar 15 11:40:15 2017
***************
*** 1267,1277 ****
* OS Sleep Allow / Prevent
***********************************************************************/

- #ifdef __APPLE__
- // 128 chars limit for IOPMAssertionCreateWithName
- static CFStringRef reasonForActivity =
- CFSTR("HandBrake is currently scanning and/or encoding");
- #endif

void* hb_system_sleep_opaque_init()
{
--- 1267,1272 ----
***************
*** 1339,1344 ****
--- 1334,1344 ----
void hb_system_sleep_private_disable(void *opaque)
{
#ifdef __APPLE__
+
+ // 128 chars limit for IOPMAssertionCreateWithName
+ CFStringRef reasonForActivity =
+ CFSTR("HandBrake is currently scanning and/or encoding");
+
if (opaque == NULL)
{
hb_error("hb_system_sleep: opaque is NULL");
$


What version of HandBrake you are running:

1.0.3

What operating system and version and you running (e.g. OSX 10.11, Windows 7, Ubuntu 14):

OSX 10.4

Where did you download HandBrake from? handbrake.fr or somewhere else?
Github

If there was any error, exception or crash report displayed, please copy it and paste it here:

see above for compilation error.

Please include the scan or encode log:

Code: Select all

 To make the log easier to read, please paste your log here between the code brackets, or use a pastebin website. 
User avatar
Ritsuka
HandBrake Team
Posts: 1163
Joined: Fri Jan 12, 2007 11:29 am

Re: non portable use of CFSTR macro in libhb/ports.c

Post by Ritsuka »

jwardnh
Posts: 2
Joined: Wed Mar 15, 2017 3:43 pm

Re: non portable use of CFSTR macro in libhb/ports.c

Post by jwardnh »

thanks for the quick fix!

Judy
Post Reply