VST3 SDK bug? How is it supposed to build?

Check out this line of code.

It’s an invalid cast from NSURL* to CFURLRef. It’s not bridged so it messes up the reference count which means it will fail the static ARC check (and would leak even if it passed). I can’t even disable ARC (which would be wrong anyway) as there’s an explicit check for it which is supposed to make it a hard compilation error either way.

This stops me from building VST3ManifestHelper unless I patch the VST3 SDK code and change the static cast to bridge cast (which I think is the correct fix).

I can’t see how this isn’t a bug in the VST3 SDK, but at the same time I’m assuming this doesn’t affect everyone, otherwise it would have been fixed a long time ago.

What gives? The only ways I can explain this are

A) my understanding is incorrect

B) there’s a secret compiler flag that does prevent the static check (that hasn’t got to do with -fobjc_arc) that I’m missing

C) the currently popular XCode toolsets fail to pick up this error due to some sort of a bug but mine somehow does

What do you guys reckon?

The docs for CFURL say that it’s toll-free bridged to NSURL, so the line you’ve highlighted looks alright to me. My guess is that the build failure has some other root cause.

Please can you let us know:

  • What’s the exact text of the error message you’re seeing when building? If there’s lots of errors, please provide the first/topmost errors.
  • What Xcode and macOS version are you using?
  • What JUCE version are you using?
  • Are you using an external VST3 SDK, or the one bundled in JUCE?
  • Are you using the Projucer or CMake? JUCE normally builds without ARC enabled - have you added any flags to the build that might affect this setting?

I’m aware they’re toll-free bridged, but are you sure that implies you can safely C+±style static_cast between them?

juce/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_mac.mm:218:88: error: cast of Objective-C pointer type 'NSURL *' to C pointer type 'CFURLRef' (aka 'const __CFURL *') requires a bridged cast
                                                CFPtr < CFArrayRef > archs(CFBundleCopyExecutableArchitecturesForURL(static_cast<CFURLRef>(url)));
                                                                                                                                 ^~~~~~~~  ~~~
juce/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_mac.mm:218:96: note: use __bridge with C-style cast to convert directly (no change in ownership)
                                                CFPtr < CFArrayRef > archs(CFBundleCopyExecutableArchitecturesForURL(static_cast<CFURLRef>(url)));
                                                                                                                     ~~~~~~~~~~~~~~~~~~~~^
                                                                                                                     (__bridge CFURLRef)
juce/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_mac.mm:218:98: note: use CFBridgingRetain call to make an ARC object available as a +1 'CFURLRef' (aka 'const __CFURL *')
                                                CFPtr < CFArrayRef > archs(CFBundleCopyExecutableArchitecturesForURL(static_cast<CFURLRef>(url)));
                                                                                                                     ~~~~~~~~~~~~~~~~~~~~~~^
                                                                                                                     (CFBridgingRetain)
$ xcodebuild -version
Xcode 15.2
Build version 15C500b

macOS Sonoma 14.3.1
JUCE 7.0.12
bundled VST3 SDK

It’s a Projucer project. I don’t explicitly specify anything in particular, but given the feature test at module_mac.mm:42 does pass, I gather it must be implicitly enabled?

edit: just realised I wasn’t very clear above, the types are indeed bridged, but the cast is not a bridged cast

I’m not certain, but the code example on this page implies that a bridging cast isn’t always necessary:

I’ve not heard of any similar issues, and this version of the manifest helper has been out for quite a while at this point. This makes me think that there’s something a bit unusual/non-standard about your project or compiler toolchain. Do you see the same issue if you try to build one of the JUCE example plugins (e.g. AudioPluginDemo) as a VST3?