AUTOSAR C++14 Rule A3-3-2

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

Описание

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

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

Объяснение

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

Это правило применяется к глобальным переменным, статическим переменным, статическим переменным-членам класса и статическим переменным function-scope.

Реализация 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