﻿ V575. Function receives an odd argument.  # V575. Function receives an odd argument.

The analyzer found a potential error: the function receives a very odd value as an actual argument.

Consider the sample:

``````bool Matrix4::operator==(const Matrix4& other) const {
if (memcmp(this, &other, sizeof(Matrix4) == 0))
return true;
...``````

We deal with a misprint here: one round bracket is in a wrong place. Unfortunately, this error is not clearly visible and might exist in the code for a long time. Because of this misprint the size of memory being compared is calculated with the "sizeof(Matrix4) == 0" expression. Since the result of the expression is 'false', 0 bytes of memory are compared. This is the fixed code:

``````bool Matrix4::operator==(const Matrix4& other) const {
if (memcmp(this, &other, sizeof(Matrix4)) == 0)
return true;
...``````

Another example. The diagnostic detects cases where an array of enum elements is filled using the 'memset' function and the size of one element is other than one byte. The filling will not work correctly in this case because it is not each element but rather each byte that will get filled with a value.

Example of incorrect code:

``````enum E { V0, V1, V2, V3, V4 };
E array;
memset(array, V1, sizeof(array));``````

If the compiler makes each element, say, 4 bytes long, each of the elements will have the value 0x01010101 rather than 0x00000001 (V1) as the programmer expected.

Fixed code to fill the array correctly:

``````for (size_t i = 0; i < sizeof(array) / sizeof(array); ++i)
{
array[i] = V1;
}``````

Another way to fix it:

``````std::fill(begin(array), end(array), V1);
``````

Note. NULL is odd argument.

Sometimes programmers use constructs like the one below to calculate the amount of memory to be allocated for a buffer:

``````const char* format = getLocalizedString(id, resource);
int len = ::vsprintf(NULL, format, args);
char* buf = (char*) alloca(len);
::vsprintf(buf, format, args);``````

But one should keep in mind that the call ::vsprintf(NULL, format, args) is incorrect. Here's what MSDN has to say about it:

``````int vsprintf(*buffer, char *format, va_list argptr);
....``````

vsprintf and vswprintf return the number of characters written, not including the terminating null character, or a negative value if an output error occurs. If buffer or format is a null pointer, these functions invoke the invalid parameter handler, as described in Parameter Validation. If execution is allowed to continue, these functions return -1 and set errno to EINVAL.

This diagnostic relies on information about whether a particular pointer could be null. In some cases, this information is retrieved from the table of annotated functions, which is stored inside the analyzer itself.

'malloc' is one of such functions. Since it can return 'NULL', using the pointer returned by it without a prior check may result in null pointer dereferencing.

Sometimes our users wish to change the analyzer's behavior and make it think that 'malloc' cannot return 'NULL'. For example, to do that, they use the system libraries, where 'out of memory' errors are handled in a specific way.

They may also want to tell the analyzer that a certain function can return a null pointer.

In that case, you can use the additional settings, described in the section "How to tell the analyzer that a function can or cannot return nullptr".

 According to Common Weakness Enumeration, potential errors found by using this diagnostic are classified as CWE-628.
 You can look at examples of errors detected by the V575 diagnostic.

371
13 624