MISRA C++:2008 Rule 16-0-6

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

Описание

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

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

Объяснение

Когда вы вызываете подобные функции макросы, компилятор расширяет макрос, заменяя его параметры на лексемы. Затем компилятор заменяет расширенным макросом в код. Этот процесс расширения и замены не более приоритетен по операции во внимание. Подобные функции макросы могут привести к неожиданным результатам, если их параметры не заключены в круглую скобку. Например, рассмотрите этот подобный функции макрос:

#define dustance_from_ten(x) x>10? x-10:10-x
Макрос предназначается, чтобы измерить расстояние номера от десять. Когда вы вызываете макрос с аргументом (a-b), макрос расширяется до:
a-b>10: a-b-10:10-a-b
Выражение 10-a-b эквивалентно 10-(a+b) вместо намеченного расстояния 10-(a-b). Это неожиданное поведение может привести к ошибкам и ошибкам. Чтобы избежать таких неожиданных поведений, заключите параметры подобного функции макроса в круглых скобках.

Исключение к этому правилу - когда параметр используется в качестве операнда # или ##.

Реализация Polyspace

Polyspace® отмечает подобные функции макроопределения, если параметры не заключены в круглую скобку. Polyspace не отмечает незаключенные в скобки параметры, если им предшествуют операторы ., ->, или символы #, ##.

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

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

Примеры

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

#include<iostream>
#include<cmath>
#define abs(x) (x>0) ? x:-x //Noncompliant

double foo(double num1, double num2){
	return log(abs(num1-num2));
}

int main(){
	std::cout<<foo(10,10.5);
}

В этом примере, когда вы вызываете foo(10,10.5), вы можете ожидать, что выходом будет log(0.5) или -0.69. Поскольку параметры abs не заключены в круглые скобки, выход становится log(-20.5) или NaN, который неожидан и может привести к ошибкам. Polyspace отмечает подобное функции макроопределение.

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

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