I have found the following code:
char query[255];
sprintf(query, "SELECT NOMBRE, ");
switch (tipo)
{
case TIPO_1:
sprintf(query, "%s ID", query);
break;
case TIPO_2:
sprintf(query, "%s APELLIDO", query);
break;
}
And what bothers me is the use of query
playing the role of both the read parameter and the write parameter of sprintf
.
The code works fine and does what is expected of it in our compiler and in our tests.
Assuming the size of the array is not exceeded. And that whenever query is used as a read parameter, it is the first parameter after the format parameter and the format starts with "%s".
Is it a correct use? Or is there a situation where it could malfunction?
If we check what the function's documentation in GNU says :
In your case you are overlapping the input buffer with the output buffer, so the result, as indicated in the first comment, depends only on the implementation you use at any given time.
In any case, although it works for specific situations, it is something to avoid given the randomness of the result. There are much more robust solutions that only require the use of an additional variable.
With respect to C standard library functions like
sprintf
, C++ references the C standard, with some qualifications (but none forsprintf
). For its part, the C standard (in §7.19.6.6 in C99, §7.21.6.6 in C11) says that if a copy occurs between overlapping objects, undefined behavior occurs.According to both standards, as soon as undefined behavior occurs the result can be unpredictable.