exponenta event banner

Правило AUTOSAR C++ 14 A3-3-2

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

Описание

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

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

Объяснение

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

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

Внедрение Polyspace

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

  • A 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