You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Some expressions involve operands that are unevaluated. According to the C++ Standard, [expr], paragraph 8 [ISO/IEC 14882-2014]:

In some contexts, unevaluated operands appear. An unevaluated operand is not evaluated. An unevaluated operand is considered a full-expression. [Note: In an unevaluated operand, a non-static class member may be named (5.1) and naming of objects or functions does not, by itself, require that a definition be provided. — end note]

The following expressions do not evaluate their operands: sizeof()typeid()noexcept()decltype(), and declval().

Because an unevaluated operand in an expression is not evaluated, no side effects from that operand will be triggered. Reliance on those side effects will result in unexpected behavior. Do not rely on side effects in unevaluated operands.

Note that unevaluated expression operands are used in situations were the declaration of an object is required, but the definition of the object is not. For instance, in the example below, the function f() is overloaded, which relies on the unevaluated expression operand to select the desired overload, which is then used to determine the result of the sizeof() expression:

int f(int);
double f(double);
 
size_t size = sizeof(f(0));
Such a use is not relying on the side effects of f(), and is conforming to this guideline.

Noncompliant Code Example (sizeof)

In this noncompliant code example, the expression a++ is not evaluated:

#include <iostream>
void f() {
  int a = 14;
  int b = sizeof(a++);
  std::cout << a << ", " << b << std::endl;
}

Consequently, the value of a after b has been initialized is 14.

Compliant Solution (sizeof)

In this compliant solution, the variable a is incremented outside of the sizeof operator:

#include <iostream>
void f() {
  int a = 14;
  int b = sizeof(a);
  ++a;
  std::cout << a << ", " << b << std::endl;
}

Noncompliant Code Example (decltype)

In this noncompliant code example, the expression i++ is not evaluated within the decltype specifier:

#include <iostream>

void f() {
  int i = 0;
  decltype(i++) h = 12;
  std::cout << i;
}

Consequently, the value of i remains 0.

Compliant Solution (decltype)

In this compliant solution, i is incremented outside of the decltype specifier, so that it is evaluated as desired:

#include <iostream>

void f() {
  int i = 0;
  decltype(i) h = 12;
  ++i;
  std::cout << i;
}

Risk Assessment

If expressions that appear to produce side effects are an unevaluated operand, the results may be different than expected. Depending on how this result is used, it can lead to unintended program behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP32-CPP

Low

Unlikely

Low

P3

L3

Automated Detection

Tool

Version

Checker

Description

    

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]Clause 5, "Expressions"
20.2.5, "Function template declval
  • No labels