Moved Permanently

The document has moved here.


Apache/2.2.11 (Unix) PHP/5.2.10 Server at viva64.com Port 8102
Print version

V111. Call function 'foo' with variable number of arguments. N argument has memsize type

The analyzer found a possible error related to the transfer of the actual argument of memsize type into the function with variable number of arguments. The possible error may consist in the change of demands made to the function on the 64-bit system.

Let's examine an example.

const char *invalidFormat = "%u";
size_t value = SIZE_MAX;
printf(invalidFormat, value);

The given code does not take into account that size_t type does not coincide with unsigned type on the 64-bit platform. It will cause the printing of the incorrect result in case if value > UINT_MAX. The analyzer warns you that memsize type is used as an actual argument. It means that you should check the line invalidFormat assigning the printing format. The correct variant may look as follows:

const char *validFormat = "%Iu";
size_t value = SIZE_MAX;
printf(validFormat, value);

In the code of a real application, this error can occur in the following form, e.g.:

wsprintf(szDebugMessage,
          _T("%s location %08x caused an access violation.\r\n"),
         readwrite,
         Exception->m_pAddr);

The second example.

char buf[9];
sprintf(buf, "%p", pointer);

The author of this inaccurate code did not take into account that the pointer size may excess 32 bits later. As a result, this code will cause buffer overflow on the 64-bit architecture. After checking the code on which the V111 warning message is shown you may choose one of the two ways: to increase the buffer size or rewrite the code using safe constructions.

char buf[sizeof(pointer) + 1];
sprintf(buf, "%p", pointer);
// --- or ---
std::stringstream s;
s << pointer;

The third example.

char buf[9];
sprintf_s(buf, sizeof(buf), "%p", pointer);

While examining the second example you could rightly notice that in order to prevent the overflow you should use functions with security enhancements. In this case the buffer overflow won't occur but unfortunately the correct result won't be shown as well.

If the arguments types did not change their digit capacity the code is considered to be correct and warning messages won't be shown. The example:

printf("%d", 10*5);
CString str;
size_t n = sizeof(float);
str.Format(StrFormat, static_cast<int>(n));

Unfortunately, we often cannot distinguish the correct code from the incorrect one while diagnosing the described type of errors. This warning message will be shown on many of calls of the functions with variable items number even when the call is absolutely correct. It is related to the principal danger of using such C++ constructions. Most frequent problems are the problems with the use of variants of the following functions: printf, scanf, CString::Format. The generally accepted practice is to refuse them and to use safe programming methods. For example, you may replace printf with cout and sprintf with boost::format or std::stringstream.

This type of diagnostic messages is influenced by the analyzer's Enable Pedantic mode setting. If it is enabled the analyzer starts warning about potential errors in the following code:

const char *str = "ABC";
printf("String : %s", str);

An error in this code is unlikely but still possible as the analyzer doesn't know how the function printf works and how it reacts to changing arguments' dimension.