Warnings in juce_PluginUtilities.cpp when _CRT_SECURE_NO_WARNINGS disabled

I build my Visual Studio projects without defining _CRT_SECURE_NO_WARNINGS so that I catch the usage of the potentially insecure functions silenced with that macro.

Because of that, I’m getting the following warnings in getUUIDForVST2ID():

juce_pluginutilities.cpp(57): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
juce_pluginutilities.cpp(59): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
juce_pluginutilities.cpp(62): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
juce_pluginutilities.cpp(63): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
juce_pluginutilities.cpp(75): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
juce_pluginutilities.cpp(76): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Projucer does a blanket #define _CRT_SECURE_NO_WARNINGS for every project, and that’s why most people don’t get those warnings. My projects are not managed by Projucer and that’s why I’m getting them.
To my knowledge, they are the only of this kind in the whole JUCE codebase (I’m using 6.1.1 from master at the moment), so I’m asking if it were possible to fix them locally to that function.

For example, I know that that code is copied from the Steinberg code, but perhaps it’s easy to fix those calls like it’s done around line 83:

#if ! JUCE_MSVC
 sscanf
#else
 sscanf_s
#endif
 (uidString, "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
  &p0, &p1, &p2, &p3[0], &p3[1], &p3[2], &p3[3], &p3[4], &p3[5], &p3[6], &p3[7]);

Otherwise, I’ve noticed it’s sufficient to wrap the entire function body in:

JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
JUCE_END_IGNORE_WARNINGS_MSVC

because those are just deprecation (4996) warnings after all.

Thanks for reporting this issue, it should be fixed here:

1 Like

Thanks @reuk !
TIL this new technique that combines lambdas, auto&&, and parameter packs. Can there be anything more representative of modern C++? Bring a mage hat to this man! :mage:

2 Likes

Sorry if this is a bit off topic regarding the original topic, but while this was mentioned here: Inspired by this commit, I wanted to use that those lambda parameter packs in some own code today as well. But I’m wondering if this actually does perfect forwarding @reuk? I mean, with a usual templated function I would have written

template <typename... Args>
void juce_sprintf (Args&&... args) { sprintf (std::forward<Args> (args)...); };

Now here, no explicit forwarding is done.

const auto juce_sprintf = [] (auto&&... args) { sprintf (args...); };

Is the lambda version still forwarding the arguments perfectly due to some compiler magic or does it not forward the arguments perfectly (which might still be totally fine in the context where this is used)?

This isn’t doing perfect forwarding, but that’s fine in this context - the arguments are all ints or pointers, so they don’t really benefit from perfect forwarding.

To perfect-forward with auto, you need to do something like this:

[] (auto&&... x) { myWrappedFunction (std::forward<decltype (x)> (x)...); }
2 Likes

Ah right, that makes sense. Thanks for clearing this up :slight_smile: