GitHub
CERT Secure Coding

FLP37-C. Do not use object representations to compare floating-point values

The object representation for floating-point values is implementation defined. However, an implementation that defines the __STDC_IEC_559__ macro shall conform to the IEC 60559 floating-point standard and uses what is frequently referred to as IEEE 754 floating-point arithmetic [ ISO/IEC 9899:2024 ] . The floating-point object representation used by IEC 60559 is one of the most common floating-point object representations in use today.

All floating-point object representations use specific bit patterns to encode the value of the floating-point number being represented. However, equivalence of floating-point values is not encoded solely by the bit pattern used to represent the value. For instance, if the floating-point format supports negative zero values (as IEC 60559 does), the values -0.0 and 0.0 are equivalent and will compare as equal, but the bit patterns used in the object representation are not identical. Similarly, if two floating-point values are both (the same) NaN, they will not compare as equal, despite the bit patterns being identical, because they are not equivalent.

Do not compare floating-point object representations directly, such as by calling memcmp() or its moral equivalents. Instead, the equality operators ( == and != ) should be used to determine if two floating-point values are equivalent.

Noncompliant Code Example

In this noncompliant code example, memcmp() is used to compare two structures for equality. However, since the structure contains a floating-point object, this code may not behave as the programmer intended.

Non-compliant code
#include <stdbool.h>
#include <string.h>
 
struct S {
  int i;
  float f;
};
 
bool are_equal(const struct S *s1, const struct S *s2) {
  if (!s1 && !s2)
    return true;
  else if (!s1 || !s2)
    return false;
  return 0 == memcmp(s1, s2, sizeof(struct S));
}

Compliant Solution

In this compliant solution, the structure members are compared individually:

Compliant code
#include <stdbool.h>
#include <string.h>
 
struct S {
  int i;
  float f;
};
 
bool are_equal(const struct S *s1, const struct S *s2) {
  if (!s1 && !s2)
    return true;
  else if (!s1 || !s2)
    return false;
  return s1->i == s2->i &&
         s1->f == s2->f;
}

Risk Assessment

Using the object representation of a floating-point value for comparisons can lead to incorrect equality results, which can lead to unexpected behavior.

Rule Severity Likelihood Detectable Repairable Priority Level
FLP37-C Low Unlikely Yes Yes P3 L3

Automated Detection

Tool

Version

Checker

Description

Astrée
25.10
memcmp-with-floatPartially checked
Axivion Bauhaus Suite

7.2.0

CertC-FLP37Fully implemented
Cppcheck Premium

24.11.0

premium-cert-flp37-c
Helix QAC

2025.2

C5026

C++3118


Klocwork

2025.2

MISRA.STDLIB.MEMCMP.PTR_ARG_TYPES
CERT.MEMCMP.FLOAT_MEMBER


LDRA tool suite
9.7.1
618 SEnhanced Enforcement
Parasoft C/C++test

2025.2

CERT_C-FLP37-c

Do not use object representations to compare floating-point values

PC-lint Plus

1.4

2498, 2499

Fully supported

Polyspace Bug Finder

R2025b

CERT C: Rule FLP37-CChecks for memory comparison of floating-point values (rule fully covered)
PVS-Studio

7.42

V1014
RuleChecker

25.10

memcmp-with-floatPartially checked
TrustInSoft Analyzer

1.38


Exhaustively verified.

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

Bibliography

[ ISO/IEC 9899:2024 ]Annex F, "ISO/ IEC 60559 floating-point arithmetic"