Annex K, which the _s functions come from is only supported on Windows so far. (And it’s not 100% standard compliant, but that’s another detail)
For most of them you could just make a wrapper using the preprocessor, but some of them get kind of tough to deal with. The most notable for me is the scanf family of functions that requires you to pass the length of strings right after them.
The two options you have are:
Use SDL’s libc if you have SDL in your project.
get rid of the _s warnings for Windows.
The latter you can be achieve by putting:
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Disables warnings on _s functions (4996)
In your CMakeLists.txt, or
#define _CRT_SECURE_NO_WARNINGS before any include of stdio.h
The option to make a “wrapper” would look like such:
#define __STDC_WANT_LIB_EXT1__ 1 //Not necessary on Windows, but technically required by standard
#define MYFUNC(x, y, ...) myfunc_s(x, y, __VA_ARGS__)
#define MYFUNC(x, y, ...) myfunc(x, y, __VA_ARGS__)
You’d want to put this in its own header and import that in every file that needs stdio.h.
There’s more than 3, about 100, all replacements of these good old stdio/stdlib C functions. Unfortunately they’re not picked up in the Wiki. Best place to go is the header file I mentioned (/SDL2/include/SDL_stdinc.h). If you want to find out what they all do then google the part without “SDL_”. So if you wanted to know how SDL_atoi works, google “atio”. A trick that works in Visual Studio is if you start typing “SDL_” and then the function you want, it will give you a list of matches in knows (picked up from the project’s header files) while you type, including the parameters it takes.
It looks like the function arguments in your sprintf_s example are in precisely the same order as the expected arguments of SDL_snprintf (as in buf, bufsize, format, ...rest). You could just swap in the SDL function name for that call.
Hmm, this is probably mostly academic in this particular instance but Microsoft’s version seems to behave a bit differently in cases where the buffer is too small to hold the full string. snprintf will merely truncate a string to fit the buffer whereas sprintf_s will only write a NUL byte to buf in such cases. Sadly MS’ documentation is a bit too vague to my liking.
The functions snprintf() and vsnprintf() do not write more than size bytes (including the terminating null byte (’\0’)). If the output was truncated due to this limit, then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated.
sprintf_s returns the number of bytes stored in buffer, not counting the terminating null character.
The other main difference between sprintf_s and sprintf is that sprintf_s takes a length parameter specifying the size of the output buffer in characters. If the buffer is too small for the formatted text, including the terminating null, then the buffer is set to an empty string by placing a null character at buffer, and the invalid parameter handler is invoked.
What in the world were they thinking? I guess it works if you bother reading up on the details but still.
Are they in the public SDL2 API, and therefore entirely legitimate to call from my programs, or are they private functions for SDL internal use (which would explain them not being in the Wiki)? Perhaps I’m untypical, but I care about such things!
I can understand the caution. They’re public. No need to #include anything extra. No need to call SDL_Init before using them. Perfectly safe because there are plenty of us using them and they’ve been refined a lot. I’d encourage everyone to use them and remove the need for any horrible visual-c runtime DLLs. Some functions are missing, but it should be enough to cover everyone.