MISRA C:2023에서는 Mandatory, Required 규칙 외에도
코드 품질과 유지보수성 향상을 위해 Advisory 규칙들을 정의하고 있다.
Advisory 규칙은 Mandatory/Required처럼 절대적으로 강제되는 수준은 아니지만,
실제 프로젝트에서는 코드 품질 향상 및 장기 유지보수성을 위해 매우 중요하게 관리되는 경우가 많다.
특히 AUTOSAR 및 자동차 ECU 프로젝트에서는 가독성, 유지보수성, 이식성 확보를 위해 Advisory 규칙 위반 역시 Static Analysis Tool을 통해 함께 관리되는 경우가 많다.
이번 글에서는 MISRA C:2023 Advisory 규칙들을 간단한 설명과 함께 정리해보려 한다.

Rule 1.2 - Language extensions should not be used.
Compiler 고유 확장 문법은 사용하지 않는 것이 권장된다.
→ Compiler 의존 코드 및 이식성 저하를 방지하기 위한 규칙이다.
Rule 2.3 - A project should not contain unused type declarations.
사용되지 않는 타입 선언은 존재하지 않는 것이 권장된다.
→ 불필요한 선언 및 유지보수 혼란을 방지하기 위한 규칙이다.
Rule 2.4 - A project should not contain unused tag declarations.
사용되지 않는 tag 선언은 존재하지 않는 것이 권장된다.
→ 불필요한 struct/union/enum tag 정의를 방지하기 위한 규칙이다.
Rule 2.5 - A project should not contain unused macro definitions.
사용되지 않는 매크로 정의는 존재하지 않는 것이 권장된다.
→ Dead Macro 및 유지보수 복잡도 증가를 방지하기 위한 규칙이다.
Rule 2.6 - A function should not contain unused label declarations.
함수 내부에 사용되지 않는 label 선언은 존재하지 않는 것이 권장된다.
→ 사용되지 않는 label로 인한 Dead Code 및 제어 흐름 혼동을 방지하기 위한 규칙이다.
Rule 2.7 - There should be no unused parameters in functions.
함수에는 사용되지 않는 파라미터가 없어야 한다.
→ 인터페이스 혼동 및 불필요한 인자 전달을 방지하기 위한 규칙이다.
Rule 2.8 - A project should not contain unused object definitions
사용되지 않는 객체 정의는 존재하지 않는 것이 권장된다.
→ 불필요한 메모리 사용 및 유지보수 비용 증가를 방지하기 위한 규칙이다.
Rule 4.2 - Trigraphs should not be used.
Trigraph 사용은 권장되지 않는다.
→ 가독성 저하 및 예측 어려운 문자 치환을 방지하기 위한 규칙이다.
Rule 5.9 - Identifiers that define objects or functions with internal linkage should be unique.
Internal linkage 객체 및 함수 이름은 고유한 것이 권장된다.
→ 파일 내부 이름 충돌 및 가독성 저하를 방지하기 위한 규칙이다.
Rule 8.11 - When an array with external linkage is declared, its size should be explicitly specified.
External linkage 배열 선언 시 크기를 명시하는 것이 권장된다.
→ 배열 크기 해석 혼동을 방지하기 위한 규칙이다.
Rule 8.13 - A pointer should point to a const-qualified type whenever possible.
가능한 경우 포인터는 const-qualified 타입을 가리키는 것이 권장된다.
→ 의도하지 않은 데이터 수정 방지를 위한 규칙이다.
Rule 8.16 - The alignment specification of zero should not appear in an object declaration.
객체 선언에서 alignment 값 0 사용은 권장되지 않는다.
→ 의미 없는 alignment 지정 및 구현 의존성 문제를 방지하기 위한 규칙이다.
Rule 8.17 - At most one explicit alignment specifier should appear in an object declaration.
객체 선언에는 하나 이하의 alignment 지정만 사용하는 것이 권장된다.
→ Alignment 설정 충돌 및 해석 혼동을 방지하기 위한 규칙이다.
Rule 8.7 - Functions and objects should not be defined with external linkage if they are referenced in only one translation unit.
하나의 Translation Unit에서만 사용되는 함수 및 객체는 external linkage 사용을 지양해야 한다.
→ 불필요한 외부 노출을 줄이기 위한 규칙이다.
Rule 8.9 - An object should be defined at block scope if its identifier only appears in a single function.
하나의 함수에서만 사용하는 객체는 block scope로 선언하는 것이 권장된다.
→ Scope 최소화 및 전역 변수 남용 방지를 위한 규칙이다.
Rule 10.5 - The value of an expression should not be cast to an inappropriate essential type.
표현식 값은 부적절한 essential type으로 cast 하지 않는 것이 권장된다.
→ 데이터 해석 오류 및 타입 혼동을 방지하기 위한 규칙이다.
Rule 11.4 - A conversion should not be performed between a pointer to object and an integer type.
객체 포인터와 정수 타입 간 변환은 권장되지 않는다.
→ 포인터 값 손실 및 이식성 문제를 방지하기 위한 규칙이다.
Rule 11.5 - A conversion should not be performed from pointer to void into pointer to object.
void 포인터를 객체 포인터로 변환하는 것은 권장되지 않는다.
→ 타입 정보 없는 포인터 변환으로 인한 타입 안정성 저하를 방지하기 위한 규칙이다.
Rule 12.1 - The precedence of operators within expressions should be made explicit.
표현식 내 연산 우선순위는 명확히 드러나는 것이 권장된다.
→ 연산 순서 오해를 방지하기 위한 규칙이다.
Rule 12.3 - The comma operator should not be used.
Comma 연산자 사용은 권장되지 않는다.
→ 가독성 저하 및 복잡한 표현식 사용을 방지하기 위한 규칙이다.
Rule 12.4 - Evaluation of constant expressions should not lead to unsigned integer wrap-around.
상수 표현식 계산 시 unsigned integer wrap-around 발생은 권장되지 않는다.
→ 의도하지 않은 Overflow 계산을 방지하기 위한 규칙이다.
Rule 13.3 - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that caused by the increment or decrement operator.
증감 연산자가 포함된 표현식에는 추가 side-effect가 없는 것이 권장된다.
→ 평가 순서 혼동 및 예측 어려운 결과를 방지하기 위한 규칙이다.
Rule 13.4 - The result of an assignment operator should not be used.
대입 연산 결과값 사용은 권장되지 않는다.
→ 대입과 조건식을 혼합한 복잡한 표현식을 방지하기 위한 규칙이다.
Rule 15.1 - The goto statement should not be used.
goto 문 사용은 권장되지 않는다.
→ 복잡한 제어 흐름 및 Spaghetti Code 발생을 방지하기 위한 규칙이다.
Rule 15.4 - There should be no more than one break or goto statement used to terminate any iteration statement.
반복문 종료를 위한 break/goto는 하나 이하로 사용하는 것이 권장된다.
→ 반복문 제어 흐름 복잡도 증가를 방지하기 위한 규칙이다.
Rule 15.5 - A function should have a single point of exit at the end.
함수는 하나의 종료 지점을 가지는 것이 권장된다.
→ 함수 흐름 단순화 및 유지보수성 향상을 위한 규칙이다.
Rule 17.11 - A function that never returns should be declared with a _Noreturn function specifier
반환되지 않는 함수는 _Noreturn 지정자를 사용하는 것이 권장된다.
→ 함수 동작 의도를 명확히 하기 위한 규칙이다.
Rule 17.12 - A function identifier should only be used with either a preceding &, or with a parenthesised parameter list
함수 식별자는 &, 또는 함수 호출 형태로만 사용하는 것이 권장된다.
→ 함수 이름 오용 및 해석 혼동을 방지하기 위한 규칙이다.
Rule 17.8 - A function parameter should not be modified.
함수 파라미터 수정은 권장되지 않는다.
→ 입력값 변경으로 인한 가독성 저하를 방지하기 위한 규칙이다.
Rule 18.4 - The +, -, += and -= operators should not be applied to an expression of pointer type.
포인터 타입에 대한 산술 연산 사용은 권장되지 않는다.
→ 복잡한 포인터 연산 및 범위 오류를 방지하기 위한 규칙이다.
Rule 18.5 - Declarations should contain no more than two levels of pointer nesting.
포인터 중첩은 2단계를 초과하지 않는 것이 권장된다.
→ 과도한 포인터 복잡도 및 가독성 저하를 방지하기 위한 규칙이다.
Rule 19.2 - The union keyword should not be used.
union 사용은 권장되지 않는다.
→ 메모리 해석 혼동 및 타입 안정성 저하를 방지하기 위한 규칙이다.
Rule 20.1 - #include directives should only be preceded by preprocessor directives or comments.
#include 앞에는 전처리기 지시문 또는 주석만 존재하는 것이 권장된다.
→ 전처리 구조 가독성 향상을 위한 규칙이다.
Rule 20.10 - The # and ## preprocessor operators should not be used.
# 및 ## 전처리기 연산자 사용은 권장되지 않는다.
→ 문자열화(#) 및 토큰 결합(##) 기반의 복잡한 매크로 사용을 제한하기 위한 규칙이다.
Rule 20.5 - #undef should not be used.
#undef 사용은 권장되지 않는다.
→ 매크로 상태 변경으로 인한 유지보수 혼란을 방지하기 위한 규칙이다.
Rule 21.11 - The standard header file <tgmath.h> should not be used.
<tgmath.h> 사용은 권장되지 않는다.
→ 타입 제네릭 매크로 기반 구현 의존성을 줄이기 위한 규칙이다.
Rule 23.1 - A generic selection should only be expanded from a macro
_Generic 선택은 매크로를 통해서만 사용하는 것이 권장된다.
→ _Generic 사용 구조 일관성을 유지하기 위한 규칙이다.
Rule 23.3 - A generic selection should contain at least one non-default association
_Generic selection에는 최소 하나 이상의 non-default association이 존재하는 것이 권장된다.
→ 타입 분기 의미를 명확히 하기 위한 규칙이다.
Rule 23.5 - A generic selection should not depend on implicit pointer type conversion
_Generic selection은 암시적 포인터 변환에 의존하지 않는 것이 권장된다.
→ 타입 선택 오류 가능성을 줄이기 위한 규칙이다.
Rule 23.7 - A generic selection that is expanded from a macro should evaluate its argument only once
매크로 기반 _Generic selection은 인수를 한 번만 평가하는 것이 권장된다.
→ 다중 평가로 인한 side-effect 발생을 방지하기 위한 규칙이다.
정리
MISRA C:2023 Advisory 규칙들은 Mandatory 및 Required 규칙보다 강제 수준은 낮지만,
실제로는 코드 복잡도 감소, 유지보수성 향상, 가독성 확보, 실수 가능성 감소를 목표로 하는 품질 중심 규칙들에 가깝다.
Mandatory 및 Required 규칙들이 Undefined Behavior, Memory Corruption, Data Race 같은 직접적인 위험 요소 차단에 집중한다면, Advisory 규칙들은 장기 프로젝트에서 발생할 수 있는 구조적 문제와 유지보수 비용 증가를 줄이는 역할을 한다.
실제 현업에서는 QAC, Polyspace, Coverity 등의 Static Analysis Tool을 통해 Advisory 규칙도 함께 검사하며,
프로젝트 Coding Rule에 따라 일부 Advisory 항목은 사실상 Required 수준으로 관리되는 경우도 많다.
MISRA C:2023은 단순히 “컴파일 되는 코드”가 아니라,
장기간 유지보수가 가능하고 예측 가능한 안전한 코드를 만드는 것을 목표로 한다는 점에서 의미가 크다.
특히 AUTOSAR 및 차량 ECU 환경처럼 장기 유지보수와 기능 안전이 중요한 프로젝트에서는,
MISRA 규칙 준수 자체가 코드 품질 관리의 핵심 기준으로 사용되는 경우가 많다.
'MISRA-C 2023' 카테고리의 다른 글
| QAC M3CM-1 Mandatory Rule 위반 예시 (0) | 2026.06.04 |
|---|---|
| 공식 MISRA 문서와 QAC에서 보는 MISRA Rule은 왜 다를까? (0) | 2026.06.03 |
| MISRA-C:2023 Required 규칙 정리 모음 (2) (0) | 2026.06.01 |
| MISRA-C:2023 Required 규칙 정리 모음 (1) (0) | 2026.05.31 |
| MISRA-C:2023 Mandatory 규칙 정리 모음 (0) | 2026.05.30 |