Main Content

AUTOSAR C++14 Rule A5-2-2

Traditional C-style casts shall not be used

Description

Rule Definition

Traditional C-style casts shall not be used.

Rationale

C-style casts are difficult to distinguish in source code. Such casts cannot communicate the goal and necessity of the conversion. Code containing C-style casts is difficult to understand and debug.

Avoid C-style casts. C++ introduces explicit casting operations that are easily identified and clearly communicate the goal and necessity of each cast. Use these casting operations instead.

Polyspace Implementation

Polyspace® flags C-style casts and functional notation casts in your code. Compliant C++ style casting operations include:

  • std::static_cast

  • std::reinterpret_cast

  • std::const_cast

  • std::dynamic_cast

  • {} notation casts

The reference_cast operation from the Boost library and the safe_cast operation from the Microsoft® library are also allowed.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

In this example, the function Foo() shows several C++ casting operations. These operations are easily identified. They communicate the goal of necessity of the casting operations. For instance, in Base* obj4 = const_cast<Base*>(&obj3), it is clear that the cast operation removes the const qualifier from obj3. These casting operations are compliant and Polyspace does not flag them.

The function Bar() shows several C-style casts and functional notation casts. These operations are difficult to locate, and their purposes are unclear. Polyspace flags these casts.

#include <cstdint>
class Base
{
public:
	explicit Base(std::int32_t) {}
	virtual void Fn() noexcept {}
};
class Derived : public Base
{
public:
	void Fn() noexcept override {}
};
class myClass
{
};
std::int32_t G() noexcept
{
	return 7;
}

void Foo() noexcept(false)
{
	Base obj = Base{10};        // Compliant
	const Base obj3(5);
	Base* obj4 = const_cast<Base*>(&obj3);        //Compliant
	Base* obj2;
	myClass* d1 = reinterpret_cast<myClass*>(obj4); // Compliant 
	Derived* d2 = dynamic_cast<Derived*>(obj2);       // Compliant
	std::int16_t var1 = 20;
	std::int32_t var2 = static_cast<std::int32_t>(var1);      // Compliant
	std::int32_t var4 = 10;
	float f1 = static_cast<float>(var4);                    // Compliant

	std::int32_t var5 = static_cast<std::int32_t>(f1);      //Compliant

	std::uint32_t var7 = std::uint32_t{0};//Compliant
	static_cast<void>(G());                               //Compliant
}
void Bar(){
	Base obj = Base{1};
	Base* obj2 = (Base*)(&obj); //Noncompliant
	std::int16_t var1 = 20;
	std::int32_t var3 = (std::int32_t)var1;                   // Noncompliant
	float f = float(var3);                                 // Noncompliant
	std::int32_t var6 = (std::int32_t)f;                   // Noncompliant
	std::int32_t var7 = std::int32_t(f);                   // Noncompliant
}

Check Information

Group: Expressions
Category: Required, Automated

Version History

Introduced in R2019a

expand all