Main Content

CERT C: Rec. ERR07-C

Prefer functions that support error checking over equivalent functions that don't

Since R2026a

Description

Prefer functions that support error checking over equivalent functions that don't1

Polyspace Implementation

The rule checker checks for Use of functions that do not support error checking.

Examples

expand all

Issue

This issue occurs if you use any of the functions: atof(), atoi(), atol(), atoll(), rewind(), setbuf(), and ctime().

Risk

The preceding functions provide limited or no error checking and reporting. For example, the functions atoi(), atol(), and atoll() are not required to set errno when there is an error. If the input string to one of these functions cannot be converted, the behavior of these functions is undefined.

Similarly, there is no mechanism to check functions such as rewind()and setbuf() for failure.

There are other functions with equivalent capabilities that support error checking.

Fix

To fix this issue replace a function that does not support error checking by an equivalent function that does.

Error checking not supportedError checking supported
atof()strtod()
atoi()strtol()
atol()strtol()
atoll()strtoll()
setbuf()setvbuf()
rewind()fseek()
ctime()localtime() or asctime()

Example

In this code, Polyspace® reports violations on the use of the function atoll() and rewind().

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 1024

int main() {
    const char *filename = "numbers.txt";
    FILE *file = fopen(filename, "r");

    if (file == NULL) {
        perror("Error opening file");
        return EXIT_FAILURE;
    }

    char buffer[BUFFER_SIZE];

    // Read the entire line from the file
    if (fgets(buffer, BUFFER_SIZE, file) != NULL) {
        // Tokenize the line using comma as the delimiter
        char *token = strtok(buffer, ",");

        while (token != NULL) {
            // Convert the token to a long long integer using atoll
            long long number = atoll(token); //Noncompliant
            printf("Converted number: %lld\n", number);

            // Get the next token
            token = strtok(NULL, ",");
        }
    }

    // Rewind the file pointer to the beginning of the file
    rewind(file);  //Noncompliant
    printf("File pointer reset to the beginning of the file.\n");

    // Close the file
    fclose(file);

    return EXIT_SUCCESS;
}

Correction

To fix the violation, avoid using atoll() and rewind(). Instead, use strtoll() and fseek(). Use the error reporting of these functions to make your code more robust.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define BUFFER_SIZE 1024

int main() {
	const char *filename = "numbers.txt";
	FILE *file = fopen(filename, "r");

	if(file == NULL) {
		perror("Error opening file");
		return EXIT_FAILURE;
	}

	char buffer[BUFFER_SIZE];

	// Read the entire line from the file
	if(fgets(buffer, BUFFER_SIZE, file) != NULL) {
		// Tokenize the line using comma as the delimiter
		char *token = strtok(buffer, ",");

		while(token != NULL) {
			// Convert the token to a long long integer using strtoll
			char *endptr;
			errno = 0; // Reset errno before calling strtoll
			long long number = strtoll(token, &endptr, 10);

			// Check for conversion errors
			if(endptr == token) {
				fprintf(stderr, "Conversion error: No digits were found in '%s'\n", token);
			} else
				if(errno == ERANGE) {
					fprintf(stderr, "Conversion error: Number out of range in '%s'\n", token);
				} else {
					printf("Converted number: %lld\n", number);
				}

			// Get the next token
			token = strtok(NULL, ",");
		}
	}

	// Reset the file pointer to the beginning of the file using fseek
	if(fseek(file, 0, SEEK_SET) != 0) {
		perror("Error resetting file pointer");
		fclose(file);
		return EXIT_FAILURE;
	}
	printf("File pointer reset to the beginning of the file.\n");

	// Close the file
	fclose(file);

	return EXIT_SUCCESS;
}

Check Information

Group: Rec. 12. Error Handling (ERR)
PQL Name: std.cert.ERR07_C

Version History

Introduced in R2026a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.