Our website uses cookies to enhance your browsing experience.
Accept
to the top
close form

Fill out the form in 2 simple steps below:

Your contact information:

Step 1
Congratulations! This is your promo code!

Desired license type:

Step 2
Team license
Enterprise license
** By clicking this button you agree to our Privacy Policy statement
close form
Request our prices
New License
License Renewal
--Select currency--
USD
EUR
* By clicking this button you agree to our Privacy Policy statement

close form
Free PVS-Studio license for Microsoft MVP specialists
** By clicking this button you agree to our Privacy Policy statement

close form
To get the licence for your open-source project, please fill out this form
** By clicking this button you agree to our Privacy Policy statement

close form
I am interested to try it on the platforms:
** By clicking this button you agree to our Privacy Policy statement

close form
check circle
Message submitted.

Your message has been sent. We will email you at


If you haven't received our response, please do the following:
check your Spam/Junk folder and click the "Not Spam" button for our message.
This way, you won't miss messages from our team in the future.

>
>
>
V510. The 'Foo' function receives class…
menu mobile close menu
Analyzer diagnostics
General Analysis (C++)
General Analysis (C#)
General Analysis (Java)
Diagnosis of micro-optimizations (C++)
Diagnosis of 64-bit errors (Viva64, C++)
Customer specific requests (C++)
MISRA errors
AUTOSAR errors
OWASP errors (C#)
Problems related to code analyzer
Additional information
toggle menu Contents

V510. The 'Foo' function receives class-type variable as 'N'th actual argument. This is unexpected behavior.

Dec 15 2011

Variadic function (a function whose last formal parameter is an ellipsis) takes an object of a class type as an actual argument that is part of an ellipsis, which may indicate a logical error. Only POD-types can serve as actual arguments for ellipsis.

POD is an abbreviation for "Plain Old Data", i.e. "Plain data in C style". The following types and structures refer to POD-types:

  • Scalar types: possibly cv-qualified arithmetic (integral and floating-point), pointer, pointer to member, enumeration or 'std::nullptr_t';
  • Class types ('class', 'struct', or 'union') that meet the following requirements:
    • Every copy constructor (if any) is trivial (it is implicitly-defined or defaulted);
    • Every move constructor (if any) is trivial;
    • Every copy assignment operator (if any) is trivial;
    • Every move assignment operator (if any) is trivial;
    • Has a trivial non-deleted destructor;
    • Has no virtual functions or virtual base classes;
    • Has one or more default constructors, all of which are trivial;
    • All non-static data members have the same access control;
    • Has no virtual functions or virtual base classes;
    • Has no non-static data members of reference type;
    • All non-static data members and base classes are themselves standard layout types;
    • Either has no base classes with non-static data members, or has no non-static data members in the most derived class and at most one base class with non-static data members;
    • Has no base classes of the same type as the first non-static data member.

If a class object is passed to an ellipsis function, this almost always indicates an error in program. The V510 rule helps detect incorrect code of the following kind:

wchar_t buf[100];
std::wstring ws(L"12345");
swprintf(buf, L"%s", ws);

The object's contents are saved into the stack instead of the pointer to the string. This code will cause generating "abracadabra" in the buffer or a program crash.

The correct version of the code must look this way:

wchar_t buf[100];
std::wstring ws(L"12345");
swprintf(buf, L"%s", ws.c_str());

Since you might pass anything you like into functions with a variable number of arguments, almost all the books on C++ programming do not recommend using them. They suggest employing safe mechanisms instead, for instance, boost::format.

Note about C++11

In new standard, it is said that: C++11 5.2.2/7: Passing a potentially-evaluated argument of class type having a non-trivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.

Thus, it is possible to pass into function' ellipsis "more various kinds" of objects. However, we decided not to change anything in this rule. In 99% of cases transferring a complex class as an argument is a misprint or another kind of error. This code should be reviewed. In case of inconvenience caused by large amount of false alarms related to this warning, it is possible to mark these functions to suppress it massively. An example:

//-V:MySuperPrint:510

It is possible to read about multiple warning suppression in details in section "Suppression of false alarms".

Note one specific thing about using the CString class from the MFC library

We must see an error similar to the one mentioned above in the following code:

CString s;
CString arg(L"OK");
s.Format(L"Test CString: %s\n", arg);

The correct version of the code must look in the following way:

s.Format(L"Test CString: %s\n", arg.GetString());

Or, as MSDN suggests [1], you may use the explicit cast operator LPCTSTR implemented in the CString class to get a pointer to the string. Here is a sample of correct code from MSDN:

CString kindOfFruit = "bananas";
int howmany = 25;
printf("You have %d %s\n", howmany, (LPCTSTR)kindOfFruit);

However, the first version "s.Format(L"Test CString: %s\n", arg);" is actually correct as well like the others. This topic is discussed in detail in the article "Big Brother helps you" [2].

The MFC developers implemented the CString class in a special way so that you could pass it into functions of the printf and Format types. It is done rather intricately and if you want to make it out, study implementation of the CStringT class in the source codes.

So, the analyzer makes an exception for the CStringT type and considers the following code correct:

CString s;
CString arg(L"OK");
s.Format(L"Test CString: %s\n", arg);

Related materials

This diagnostic is classified as:

You can look at examples of errors detected by the V510 diagnostic.