MISRA C++:2008 Rule 9-5-1

Объединения не должны использоваться

Описание

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

Объединения не должны использоваться.

Объяснение

Используя объединения, чтобы сохранить значение может привести к неверному истолкованию значения и привести к неопределенному поведению. Например:

union Data{
	int i;
	double d;
};
void bar_int(int);
void bar_double(double);
void foo(void){
	Data var;
	var.d = 3.1416;
	bar_int(var.d);//Undefined Behavior
} 
В вызове bar_int, double данные в объединении неправильно истолкованы как int, который является неопределенным поведением. Компиляторы могут реагировать на это неверное истолкование по-другому в зависимости от их реализации. Чтобы избежать неопределенных поведений, не используйте union.

В некоторых случаях использование объединений может быть необходимым, чтобы увеличить КПД. В таких случаях используйте объединения после документирования соответствующих заданных реализацией поведений компилятора. В предыдущем случае, перед использованием union, консультируйтесь с руководством компилятора, который вы используете и документ, как компилятор реагирует на интерпретацию double как int.

Реализация Polyspace

Polyspace® отмечает объявление union. Вы можете рассмотреть использование union необходимый или приемлемый в вашем коде. В таких случаях выровняйте по ширине нарушение путем аннотирования результата или при помощи комментариев к коду. См.:

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

Если вы ожидаете нарушение правила, но не видите его, относитесь, чтобы Диагностировать, Почему Кодирующие Стандартные Нарушения Не Появляются как ожидалось.

Примеры

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

#include <iostream>

union Pi{ //Noncompliant
	int i;
	double d;
};

void foo(void){

	std::cout << std::endl;

	Pi pi;
	pi.d = 3.1416;// pi holds a double
	std::cout << "pi.d: " << pi.d << std::endl;     
	std::cout << "pi.i: " << pi.i << std::endl;      // Undefined Behavior

	std::cout << std::endl;

	pi.i = 4;     // pi holds an int
	std::cout << "pi.i: " << pi.i << std::endl;
	std::cout << "pi.d: " << pi.d << std::endl;      // Undefined Behavior

	std::cout << std::endl;

}

В этом примере, union Pi содержит double и int. В коде, double неправильно истолкован как int и наоборот при помощи union. Эти неверные истолкования являются неопределенными поведениями и могут привести к ошибкам и зависящему от реализации поведению кода. Polyspace отмечает union объявление.

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

Группа: Классы
Категория: необходимый
Введенный в R2013b