자동차·항공·의료 등 안전이 중요한 시스템을 위한 C 코딩 가이드라인. MISRA(Motor Industry Software Reliability Association)가 만들었다.
왜 필요한가
C는 미정의 동작(undefined behavior)이 200가지 이상 있는 언어다.
i = i++ + 1; // 미정의
a[i] = i++; // 미정의
int x = INT_MAX + 1; // 미정의 (부호 있는 오버플로)
컴파일러마다 다르게 동작하고, 최적화 수준에 따라 바뀐다. 자동차 제어 소프트웨어에서는 허용할 수 없다.
MISRA는 "C의 안전한 부분집합"을 정의한다.
버전
- MISRA C:2004 — — 오래됨
- MISRA C:2012 — — 현재 주류. 규칙이 더 정밀하고 근거가 명시됨
- MISRA C:2023 — — 최신. C11/C18 지원 추가
- MISRA C++:2008 / AUTOSAR C++14 → MISRA C++:2023 으로 통합
규칙 분류
| 분류 | 뜻 |
|---|---|
| Mandatory | 반드시 준수. 일탈 불가 |
| Required | 준수해야 하지만 문서화된 일탈(deviation) 허용 |
| Advisory | 권장 |
"Required는 어길 수 있다" — 단, 왜 어겼는지 근거를 문서로 남기고 승인받아야 한다. 이 절차가 MISRA의 실질적 가치다.
대표 규칙
// 규칙 8.13 — 가능하면 포인터를 const 로
void f(const char *s);
// 규칙 10.x — 필수 타입 모델. 암묵적 타입 변환 금지
uint8_t a = 200, b = 100;
uint8_t c = (uint8_t)(a + b); // 명시적 캐스팅 필요
// 규칙 14.4 — if/while 조건은 boolean 이어야
if (ptr) { } // ✗
if (ptr != NULL) { } // ✓
// 규칙 15.5 — 함수 끝에 return 하나만 (Advisory)
// 규칙 15.6 — 반복문·조건문에 반드시 중괄호
if (x) y = 1; // ✗
if (x) { y = 1; } // ✓
// 규칙 17.2 — 재귀 금지
// 규칙 21.3 — 동적 메모리 할당 함수 사용 금지
// 규칙 8.4 — 외부 링키지 객체는 선언이 보이는 곳에서 정의
특히 임베디드에 중요한 규칙들
① 재귀 금지 (17.2)
- 스택 사용량을 정적으로 계산할 수 없게 된다
- 스택 오버플로를 사전에 검증할 방법이 사라진다
② 동적 할당 금지 (21.3) 단편화 → 장기 실행 후 실패 할당 시간이 비결정적 → 실시간성 파괴
③ 필수 타입 모델 (10.x) 정수 승격으로 인한 예상치 못한 동작을 막는다 uint8_t 끼리의 연산이 int 로 승격되는 문제 등
④ 중괄호 강제 (15.6)
if (x)
a();
b(); // 들여쓰기와 달리 항상 실행된다 — Apple의 goto fail 버그
실제로 iOS/macOS의 SSL 검증 우회 취약점(goto fail, 2014) 이 이 형태의 실수였다.
도구
정적 분석기: PC-lint, Polyspace, Coverity, Cppcheck(부분), Helix QAC 컴파일러 경고: -Wall -Wextra -Wconversion 로도 상당 부분 커버
도구 없이 수작업 준수는 불가능하다. 규칙이 150개가 넘는다.
현실적인 도입
- ① 전체를 한 번에 적용하려 하지 않는다
- ② Mandatory + 중요한 Required 부터
- ③ 신규 코드에만 적용하고 기존 코드는 점진적으로
- ④ 일탈은 반드시 사유와 함께 문서화
- ⑤ CI에 정적 분석을 넣어 회귀 방지
MISRA를 따른다고 버그가 없어지지 않는다. 논리 오류는 여전히 남는다. "언어 차원의 함정을 제거" 하는 것이 목적이다.
비판과 균형
- 일부 규칙은 지나치게 엄격해 가독성을 해친다는 지적
- (단일 return 강제 등은 오히려 중첩을 깊게 만든다)
- 도구가 비싸다
- 오탐이 많아 일탈 문서 작성 부담이 크다
인증이 필요한 프로젝트가 아니라면 전면 적용은 과할 수 있다. 다만 미정의 동작 관련 규칙과 타입 안전성 규칙은 어떤 프로젝트에도 유익하다.
관련 표준
- ISO 26262 — — 자동차 기능 안전 (ASIL A~D)
- IEC 61508 — — 산업 기능 안전 (SIL 1~4)
- DO-178C — — 항공 소프트웨어
- IEC 62304 — — 의료기기 소프트웨어 이 표준들이 "코딩 표준을 사용할 것"을 요구하고, 그 코딩 표준으로 MISRA가 널리 채택된다.