AUTOSAR C++14 Rule A3-3-2

Статические и локальные объекты потока должны быть постоянно инициализированы

Описание

Управляйте определением

Статические и локальные объекты потока должны быть постоянно инициализированы.

Объяснение

Статические и локальные объекты потока инициализируются в начале выполнения кода. Стандарт языка C++ только частично задает порядок инициализации нескольких статических или локальных объектов потока, и порядок может измениться от сборки до сборки. Если вы инициализируете статический или локальный объект потока от другого такого объекта, компилятор может получить доступ к последнему объекту, прежде чем это будет инициализировано. Чтобы избежать доступа перед инициализацией, инициализируйте статические и локальные объекты потока при помощи объектов, которые оценивают к константе во время компиляции. Инициализация с константами происходит перед инициализацией с переменными и часто происходит во время компиляции.

Это правило применяется к глобальным переменным, статическим переменным, статическим переменным члена класса и статическим переменным функционального осциллографа.

Реализация Polyspace

Polyspace® отмечает инициализации статических или локальных объектов потока с помощью инициализаторов и конструкторов, которые не оценивают к константам во время компиляции. К константе - инициализируйте статические или локальные объекты потока, используйте:

  • constexpr конструктор только с аргументами константы

  • Константное выражение

  • Значение

Поскольку объекты строки используют динамическое выделение памяти неизвестного размера, компилятор не может оценить их во время компиляции. Polyspace отмечает инициализацию объектов строки независимо от того, задаете ли вы инициализатор.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

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

#include <cstdint>
#include <limits>
#include <string>
class A{
	//..
public:
	constexpr A(){
		//...
	}
};
class B{
	//..
public:
	B(){
		//...
	}
};
const int global_const_a = 10;              // Compliant
const int global_const_b = global_const_a;  // Compliant 
int global_a = 10;                          // Compliant  
int global_b = global_a;                    // Noncompliant 
static std::string global_name = "Name";    // Noncompliant
static std::string global_id;               // Noncompliant 
char *ptr = "hello world";                  // Compliant
char arr_up[3] = {'U','p','\0'};            // Compliant  
char container[10];                         // Compliant
extern const int global_extern_c;
const int global_const_c = global_extern_c; // Noncompliant 
static A obj1{};							//Compliant
static B obj2{}; 							//Noncompliant
main()
{
	
	//
}  

Polyspace отмечает инициализацию:

  • global_b global_a потому что, ли global_b оценивает к константе, во время компиляции зависит от порядка, в котором инициализируются эти переменные.

  • global_name и global_id потому что компилятор не может оценить конструктора для объектов строки во время компиляции.

  • global_const_c extern переменная global extern_c потому что компилятор не может оценить extern переменные во время компиляции.

  • obj2, который вызывает конструктора B::B(), потому что конструктор не задан как constexpr.

Polyspace не отмечает инициализацию:

  • global_const_b global_const_a потому что компилятор может оценить эти объекты во время компиляции независимо от их порядка инициализации.

  • global_const_a и global_a литералами, потому что компилятор может оценить литералы во время компиляции.

  • Глобальные символьные указатели и массивы литеральными инициализаторами, потому что компилятор может выделить статическое ЗУ во время компиляции.

  • obj1, который вызывает конструктора A::A(), потому что конструктор задан как constexpr.

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

Группа: Фундаментальные понятия
Категория: необходимый, автоматизированный
Введенный в R2020a