exponenta event banner

Правило AUTOSAR C++ 14 A27-0-3

Альтернативные операции ввода и вывода для потока файлов не должны использоваться без промежуточного вызова очистки или позиционирования

Описание

Определение правила

Альтернативные операции ввода и вывода для потока файлов не должны использоваться без промежуточного вызова очистки или позиционирования.

Объяснение

Чередование операций ввода и вывода в потоке без промежуточного сброса или позиционного вызова является неопределенным поведением.

Внедрение Polyspace

Средство проверки проверяет наличие следующих ситуаций:

  • В режиме обновления для потока файлов не выполняется вызов сброса или позиционирования функции между операцией вывода и следующей операцией ввода.

    Чтобы устранить нарушение правила, вызовите fflush() или функция позиционирования файлов, такая как fseek() или fsetpos() между операциями вывода и ввода в потоке обновления.

  • Вызов позиционирования функции между операцией ввода и следующей операцией вывода для потока файлов в режиме обновления не выполняется.

    Чтобы устранить нарушение правила, вызовите функцию позиционирования файла между операциями ввода и вывода в потоке обновления.

Поиск неисправностей

Если вы ожидаете нарушения правила, но не видите его, обратитесь к разделу Нарушения стандартов кодирования не отображаются.

Примеры

развернуть все

#include <stdio.h>
#define SIZE20 20

void initialize_data(char* data, size_t s) {};
const char *temp_filename = "/tmp/demo.txt";

void funcNonCompliant()
{
    char data[SIZE20];
    char append_data[SIZE20];
    FILE *file;

    file = fopen(temp_filename, "a+");
    if (file == NULL)
      {
        /* Handle error. */;
      }

    initialize_data(append_data, SIZE20);

    if (fwrite(append_data, 1, SIZE20, file) != SIZE20)
      {
        (void)fclose(file);
        /* Handle error. */;
      }
	/* Read operation after write without 
	intervening flush. */
    if (fread(data, 1, SIZE20, file) < SIZE20)  //Noncompliant
      {
          (void)fclose(file);
          /* Handle error. */;
      }

    if (fclose(file) == EOF)
      {
        /* Handle error. */;
      }
}
        

void funcCompliant()
{
    char data[SIZE20];
    char append_data[SIZE20];
    FILE *file;

    file = fopen(temp_filename, "a+");
    if (file == NULL)
      {
        /* Handle error. */;
      }

    initialize_data(append_data, SIZE20);

    if (fwrite(append_data, 1, SIZE20, file) != SIZE20)
      {
        (void)fclose(file);
        /* Handle error. */;
      }
	/* Buffer flush after write and before read */
    if (fflush(file) != 0)  
      {
        (void)fclose(file);
        /* Handle error. */;
      }
    if (fread(data, 1, SIZE20, file) < SIZE20) //Compliant
      {
        (void)fclose(file);
        /* Handle error. */;
      }

    if (fclose(file) == EOF)
      {
        /* Handle error. */;
      }
} 

В этом примере в функции funcNonCompliant, файл demo.txt открывается для чтения и добавления. После звонка на fwrite(), звонок на fread() без промежуточной операции очистки является неопределенным поведением и нарушает правило.

Функция funcCompliant показывает альтернативное решение, в котором вызов очистки выполняется после записи данных в файл и перед вызовом fread().

Проверить информацию

Группа: Библиотека ввода/вывода
Категория: Обязательно, Автоматизировано
Представлен в R2020b