I have a C code in which I have this line.
sprintf_s(var, outfile_ppm, local_filecounter++);
Here, var
is char*
type and local_filecounter
is int
type.
When I run the code it gives me this warning:
warning: implicit declaration of function 'sprintf_s' is invalid in C99 [-Wimplicit-function-declaration]
What is this warning and how can I get rid of it?
The sprintf_s
function is part of the Annex K / TR 24731 bounds checking interfaces. However, anyone interested in these interfaces should read N1967 Field Experience With Annex K — Bounds Checking Interfaces. Here is an excerpt:
Despite more than a decade since the original proposal and nearly ten years since the ratification of ISO/IEC TR 24731-1:2007, and almost five years since the introduction of the Bounds checking interfaces into the C standard, no viable conforming implementations has emerged. The APIs continue to be controversial and requests for implementation continue to be rejected by implementers.
Indeed, if you look at the GCC C11 status page, you'll see (emphasis added):
Bounds-checking (Annex K) [Optional]: Library issue (not implemented)
The only major implementation of Annex K (sprintf_s
and other similar _s
versions of functions) is in Visual Studio. The popular explanation given is that these functions are used by Microsoft internally, in their own code base to solve security problems.
Other implementations rely on tools like Valgrind, mudflap, the address sanitizer, etc. to solve the same set of problems, and few code bases outside of Microsoft actually use these functions, so there is very little motivation to implement them.
In other words, if you are not using Visual Studio, you can't use these functions. Fortunately, they are not necessary.
The invocation of sprintf_s
in the question is highly suspect to begin with…
// Wait, what? Something smells fishy...
sprintf_s(var, outfile_ppm, local_filecounter++);
The third argument to sprintf_s
should be a format string, but local_filecounter++
looks far too suspicious to be a format string.
Typically, you would use snprintf
, which truncates its output to fit the buffer, or asprintf
if you are okay using functions outside the C standard.
char var[256];
snprintf(var, sizeof(var), outfile_ppm, localfile_counter++);
Note that if var
does not have array type you can't use sizeof(var)
to calculate its size, and the usual caveats about arrays decaying to pointers when used as function arguments apply here.
Summary: You can't use sprintf_s()
unless you switch to Visual Studio or implement it yourself. Tough cookies.
Minor Note: In theory, you should define __STDC_WANT_LIB_EXT1__
if you want sprintf_s
. In practice, however, the only major implementation which defines sprintf_s
at all does so regardless of the macro's presence—as far as I know. Things may have changed.