▶MISRA C:2012156
Dir지침(Directive)Directives15R1표준 C 환경Standard C environment3R2미사용 코드Unused code7R3주석Comments2R4문자 집합Character sets2R5식별자Identifiers8R6타입Types2R7리터럴·상수Literals & constants4R8선언·정의Declarations & definitions14R9초기화Initialization5R10essential type 모델Essential type model8R11포인터 변환Pointer conversions9R12표현식Expressions4R13부작용Side effects6R14제어문 표현식Control-stmt expressions4R15제어 흐름Control flow7R16switch 문Switch statements7R17함수Functions8R18포인터·배열Pointers & arrays8R19중첩 저장Overlapping storage2R20전처리 지시문Preprocessing directives14R21표준 라이브러리Standard libraries12R22자원Resources5
▶MISRA C++:2023179
M0섹션 0Section 08Dir지침(Directive)Directives4M4섹션 4Section 44M5섹션 5Section 511M6섹션 6Section 621M7섹션 7Section 79M8섹션 8Section 824M9섹션 9Section 911M10섹션 10Section 108M11섹션 11Section 115M12섹션 12Section 124M13섹션 13Section 136M14섹션 14Section 141M15섹션 15Section 157M16섹션 16Section 163M17섹션 17Section 171M18섹션 18Section 188M19섹션 19Section 1916M21섹션 21Section 2112M22섹션 22Section 222M23섹션 23Section 231M24섹션 24Section 242M25섹션 25Section 253M26섹션 26Section 261M28섹션 28Section 285M30섹션 30Section 302
▶CERT C303
PRE전처리기Preprocessor16DCL선언·초기화Declarations31POSPOSIXPOSIX20CON동시성Concurrency23EXP표현식Expressions31FLP부동소수Floating Point13ERR오류 처리Error Handling11INT정수Integers23FIO입출력Input/Output33ARR배열Arrays9MEM메모리 관리Memory17STR문자·문자열Strings16ENV환경Environment8SIG시그널Signals7MSC기타Miscellaneous30WINWindowsWindows6APIAPIApplication Programming Interfaces9
▶CERT C++83
DCL선언·초기화Declarations11CTR컨테이너Containers9EXP표현식Expressions14ERR오류 처리Error Handling13INT정수Integers1FIO입출력Input/Output2CON동시성Concurrency7STR문자·문자열Strings4MEM메모리 관리Memory8OOP객체지향OOP9MSC기타Miscellaneous5
▶AUTOSAR C++14396
A0A0 (AUTOSAR)A0 (AUTOSAR-original)10A2A2 (AUTOSAR)A2 (AUTOSAR-original)20A3A3 (AUTOSAR)A3 (AUTOSAR-original)10A4A4 (AUTOSAR)A4 (AUTOSAR-original)3A5A5 (AUTOSAR)A5 (AUTOSAR-original)25A6A6 (AUTOSAR)A6 (AUTOSAR-original)8A7A7 (AUTOSAR)A7 (AUTOSAR-original)19A8A8 (AUTOSAR)A8 (AUTOSAR-original)20M0M0 (MISRA 유래)M0 (MISRA-origin)12M5M5 (MISRA 유래)M5 (MISRA-origin)35A9A9 (AUTOSAR)A9 (AUTOSAR-original)4A10A10 (AUTOSAR)A10 (AUTOSAR-original)9A11A11 (AUTOSAR)A11 (AUTOSAR-original)3A12A12 (AUTOSAR)A12 (AUTOSAR-original)19A13A13 (AUTOSAR)A13 (AUTOSAR-original)12A14A14 (AUTOSAR)A14 (AUTOSAR-original)7A15A15 (AUTOSAR)A15 (AUTOSAR-original)25M6M6 (MISRA 유래)M6 (MISRA-origin)19M7M7 (MISRA 유래)M7 (MISRA-origin)11M8M8 (MISRA 유래)M8 (MISRA-origin)6M9M9 (MISRA 유래)M9 (MISRA-origin)5A16A16 (AUTOSAR)A16 (AUTOSAR-original)6A17A17 (AUTOSAR)A17 (AUTOSAR-original)4A18A18 (AUTOSAR)A18 (AUTOSAR-original)23A20A20 (AUTOSAR)A20 (AUTOSAR-original)7A21A21 (AUTOSAR)A21 (AUTOSAR-original)1A23A23 (AUTOSAR)A23 (AUTOSAR-original)2A25A25 (AUTOSAR)A25 (AUTOSAR-original)2A26A26 (AUTOSAR)A26 (AUTOSAR-original)2A27A27 (AUTOSAR)A27 (AUTOSAR-original)4M10M10 (MISRA 유래)M10 (MISRA-origin)5M12M12 (MISRA 유래)M12 (MISRA-origin)1M15M15 (MISRA 유래)M15 (MISRA-origin)8M16M16 (MISRA 유래)M16 (MISRA-origin)11M17M17 (MISRA 유래)M17 (MISRA-origin)3M18M18 (MISRA 유래)M18 (MISRA-origin)5M19M19 (MISRA 유래)M19 (MISRA-origin)1A1A1 (AUTOSAR)A1 (AUTOSAR-original)6M1M1 (MISRA 유래)M1 (MISRA-origin)1M11M11 (MISRA 유래)M11 (MISRA-origin)1M14M14 (MISRA 유래)M14 (MISRA-origin)2M2M2 (MISRA 유래)M2 (MISRA-origin)5M27M27 (MISRA 유래)M27 (MISRA-origin)1M3M3 (MISRA 유래)M3 (MISRA-origin)9M4M4 (MISRA 유래)M4 (MISRA-origin)4
🛠️ C/C++ 코딩 표준 레퍼런스C/C++ Coding Standards Reference
임베디드·안전필수·보안 C/C++ 5대 코딩 표준의 분류 체계와 규칙을 위반/준수 예제로 비교합니다. 좌측 트리로 표준→섹션을 탐색하고, 🧪 버튼으로 코드를 직접 실행해 보세요.Compare the five major embedded/safety-critical/security C/C++ coding standards rule-by-rule with non-compliant vs compliant examples. Navigate standard→section in the left tree, and run code live with the 🧪 button.
MISRA C:2012
Guidelines for the use of the C language in critical systems
Directive(Dir) + RuleDirective(Dir) + RuleMandatory / Required / AdvisoryMandatory / Required / AdvisoryDecidable / UndecidableDecidable / Undecidable
안전필수 임베디드 C의 사실상 표준. 의무도(Mandatory>Required>Advisory)와 정적분석 결정가능성(Decidable/Undecidable)으로 분류된다.The de-facto standard for safety-critical embedded C. Guidelines are graded by obligation (Mandatory>Required>Advisory) and static-analysis decidability (Decidable/Undecidable).
Dir지침(Directive)Directives
Dir 1.1Required · Undecidable · Dir✓ compilablePDF rule
구현정의(implementation-defined) 동작에 의존하는 부분은 문서화·이해되어야 한다All implementation-defined behaviour relied upon must be documented and understood
❌ 위반 예시Non-compliant example
#include <stdio.h>
/* int 폭과 char 부호 부호성(signedness)을 가정 — 둘 다 구현정의 */
static int read_byte(void){ return 200; } /* 0xC8 을 돌려준다고 가정 */
int main(void){
int flags = ~0; /* int 폭(16/32/64?)을 가정한 전체 비트 마스크 */
char c = (char)read_byte(); /* char 가 signed 면 200 이 음수가 됨 */
if (c > 127) { /* signed char 환경에선 절대 참이 아님 */
printf("high bit set\n");
}
printf("flags=%d\n", flags);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdint.h>
static int read_byte(void){ return 200; }
int main(void){
uint32_t flags = 0xFFFFFFFFu; /* 폭이 고정된 타입 + 명시 상수 */
unsigned char c = (unsigned char)read_byte(); /* 부호 명시 → 항상 0..255 */
if (c > 127u) { /* 의도대로 동작 */
printf("high bit set\n");
}
printf("flags=%u\n", flags);
return 0;
}⚠️ int 폭이나 char 부호성 같은 구현정의 동작에 암묵적으로 의존하면, 컴파일러·타깃이 바뀔 때 마스크가 잘리거나 비교가 항상 거짓이 되는 등 이식 시 결함이 발생한다. stdint.h의 고정폭 타입과 명시적 부호(unsigned char)로 의존을 제거하거나, 불가피하면 가정한 동작을 문서화한다.Implicitly relying on implementation-defined behaviour such as the width of int or the signedness of char causes portability defects when the compiler or target changes — masks get truncated, comparisons become always-false. Remove the dependency with fixed-width types from stdint.h and explicit signedness, or document the assumption when unavoidable.
Dir 2.1Required · Undecidable · Dir✓ compilablePDF rule
모든 소스 파일은 오류 없이 컴파일되어야 한다All source files shall compile without any compilation errors
❌ 위반 예시Non-compliant example
#include <stdio.h>
/* #if 0 으로 가려둔 컴파일 불가 코드가 방치됨 — 되살리면 빌드가 깨진다 */
#if 0
int legacy_calc(void){
return undefined_symbol * missing_factor(); /* 컴파일 안 되는 죽은 코드 */
}
#endif
int main(void){
printf("build ok\n");
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
/* 빌드에서 제외할 코드는 삭제하거나, 남길 경우 항상 컴파일 가능한 상태로 유지 */
static int legacy_calc(void){
return 0; /* 유지한다면 유효하게 — 또는 버전관리 이력으로만 보존 */
}
int main(void){
printf("build ok: %d\n", legacy_calc());
return 0;
}⚠️ #if 0 이나 조건부 컴파일로 가려둔 깨진 코드는 빌드에서 빠져 있어 오류가 드러나지 않다가, 유지보수 중 되살아나는 순간 빌드를 깨뜨린다. 불필요한 코드는 삭제하고(이력은 버전관리에 남는다), 남길 코드는 항상 컴파일 가능한 상태로 둔다.Broken code hidden behind #if 0 or conditional compilation stays out of the build, so its errors go unnoticed until someone re-enables it and breaks the build. Delete dead code (history lives in version control) and keep any retained code in a compilable state.
Dir 3.1Required · Undecidable · Dir✓ compilablePDF rule
모든 코드는 요구사항으로 추적 가능해야 한다All code shall be traceable to documented requirements
❌ 위반 예시Non-compliant example
#include <stdlib.h>
/* 어떤 요구사항에도 근거하지 않은 추적 불가 기능 — 심사·검증에서 누락된다 */
void maintenance_hook(const char *cmd){
system(cmd); /* 문서화되지 않은 임의 명령 실행 경로(백도어성) */
}
int main(void){
/* 정상 흐름에서는 호출되지 않지만 코드에 남아 공격면이 된다 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
/* REQ-LOG-014: 운영 진단 로그를 파일에 기록한다 (요구사항 추적 ID 명시) */
static void write_diag_log(const char *msg){
/* 요구사항에 정의된 기능만, 정의된 방식으로 구현 */
printf("[DIAG] %s\n", msg);
}
int main(void){
write_diag_log("system started");
return 0;
}⚠️ 요구사항에 근거하지 않은 코드는 리뷰·검증·심사 대상에서 누락되기 쉬워 백도어나 불필요 기능의 온상이 된다. 각 기능을 요구사항 ID와 연계해 추적성을 유지하면, 정당화되지 않은 코드(특히 명령 실행·우회 경로)를 식별·제거할 수 있다.Code not grounded in a requirement is easily missed by review, verification, and audit, becoming a haven for backdoors and unnecessary features. Linking each feature to a requirement ID keeps traceability, making unjustified code — especially command-execution or bypass paths — identifiable and removable.
Dir 4.1Required · Undecidable · Dir✓ compilablePDF rule
런타임 실패(0 나눗셈·범위 초과·널 역참조 등) 가능성을 최소화한다Run-time failures shall be minimized
❌ 위반 예시Non-compliant example
#include <stdio.h>
/* 분모 0, 널 포인터, 범위 초과 가능성을 검사하지 않는다 */
static int average(const int *a, int n){
int sum = 0;
for (int i = 0; i < n; i++) { sum += a[i]; }
return sum / n; /* n==0 이면 0 나눗셈(미정의), a==NULL 이면 널 역참조 */
}
int main(void){
int data[3] = {10, 20, 30};
printf("%d\n", average(data, 3));
printf("%d\n", average(data, 0)); /* 0 나눗셈으로 비정상 종료 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <stddef.h>
/* 연산 전에 분모·포인터·개수의 유효성을 확인하고 실패를 신호로 돌려준다 */
static int average(const int *a, int n, int *ok){
if (a == NULL || n <= 0) { *ok = 0; return 0; }
int sum = 0;
for (int i = 0; i < n; i++) { sum += a[i]; }
*ok = 1;
return sum / n;
}
int main(void){
int data[3] = {10, 20, 30};
int ok;
int r = average(data, 3, &ok);
if (ok) printf("%d\n", r);
(void)average(data, 0, &ok);
if (!ok) printf("rejected empty input\n");
return 0;
}⚠️ 0 나눗셈·널 역참조·배열 범위 초과는 모두 미정의 동작으로 비정상 종료나 보안 결함을 일으킨다. 연산 직전에 분모·포인터·인덱스의 유효성을 검사하고, 실패 시 명확한 오류 신호로 분기해 런타임 실패를 설계 단계에서 차단한다.Division by zero, null dereference, and out-of-bounds indexing are all undefined behaviour that can crash the program or open security holes. Validate the divisor, pointer, and index immediately before use and branch on a clear failure signal, eliminating run-time failures by design.
Dir 4.2Advisory · DirPDF rule
어셈블리어 사용은 모두 문서화되어야 한다All usage of assembly language should be documented
❌ 위반 예시Non-compliant example
/* 인라인 어셈블리에 사용 근거·C 연동 방식 설명이 전혀 없다 */
void delay_cycles(void) {
__asm__("nop"); /* 왜 필요한지, 어떻게 연동되는지 문서 없음 */
}✅ 준수 예시Compliant example
/*
* [ASM 사용 근거] 타깃 MCU에서 1사이클 지연이 필요하며 C로는
* 컴파일러 최적화로 제거될 수 있어 NOP 명령을 직접 사용한다.
* [C-ASM 인터페이스] 입력/출력/clobber 없음. ARMv7-M nop 1개.
*/
void delay_cycles(void) {
__asm__ volatile("nop");
}⚠️ 어셈블리는 구현 정의(implementation-defined)이고 이식성이 없으므로, 사용 근거와 C와의 인터페이스 방식을 반드시 문서로 남겨 유지보수·이식 시 위험을 줄인다.Assembly is implementation-defined and non-portable, so document the rationale and the C-to-assembly interface to reduce maintenance and porting risk.
Dir 4.3Required · Decidable · Dir✓ compilablePDF rule
어셈블리 언어는 캡슐화하고 격리한다Assembly language shall be encapsulated and isolated
❌ 위반 예시Non-compliant example
#include <stdio.h>
static void do_work(void){ /* ... */ }
/* C 로직 한가운데 인라인 어셈블리가 산재 — 가독성·이식성·정적분석 저하 */
void busy_delay(void){
int i = 100;
__asm__ __volatile__("nop");
while (i-- > 0) { do_work(); __asm__ __volatile__("nop"); }
}
int main(void){ busy_delay(); printf("done\n"); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
static void do_work(void){ /* ... */ }
/* 어셈블리는 명명된 인라인 함수/매크로로 캡슐화해 한 곳에 격리 */
static inline void cpu_nop(void){ __asm__ __volatile__("nop"); }
void busy_delay(void){
int i = 100;
cpu_nop();
while (i-- > 0) { do_work(); cpu_nop(); } /* C 로직은 어셈블리에서 분리됨 */
}
int main(void){ busy_delay(); printf("done\n"); return 0; }⚠️ C 로직 사이에 인라인 어셈블리가 흩어져 있으면 가독성, 이식성, 정적 분석 가능성이 모두 떨어지고 타깃 이식 시 손대야 할 곳이 산재한다. 어셈블리를 명명된 함수나 매크로로 캡슐화하면 플랫폼 의존 코드가 한 곳에 모여 교체·검증이 쉬워진다.Inline assembly scattered through C logic hurts readability, portability, and static analysis, and spreads the places that must change when porting. Encapsulating assembly in named functions or macros collects platform-dependent code in one place, making it easy to replace and verify.
Dir 4.4Advisory · Undecidable · Dir✓ compilablePDF rule
코드 섹션을 주석 처리(comment-out)로 비활성화하지 않는다Sections of code should not be "commented out"
❌ 위반 예시Non-compliant example
#include <stdio.h>
typedef struct { int v; } Data;
static void validate(Data *d){ (void)d; }
static void notify(Data *d){ (void)d; }
void process(Data *d){
validate(d);
/* transform(d); // 임시로 막아둠 — 의도가 불명확
commit(d); */
notify(d); /* 막아둔 코드가 정말 불필요한지, 잠시인지 알 수 없다 */
}
int main(void){ Data d = {1}; process(&d); printf("ok\n"); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
typedef struct { int v; } Data;
static void validate(Data *d){ (void)d; }
static void notify(Data *d){ (void)d; }
#define FEATURE_TRANSFORM 0 /* 빌드 구성으로 의도를 명시 */
void process(Data *d){
validate(d);
#if FEATURE_TRANSFORM
transform(d);
commit(d);
#endif
notify(d);
}
int main(void){ Data d = {1}; process(&d); printf("ok\n"); return 0; }⚠️ 주석으로 막아둔 코드는 잠시 막은 것인지 폐기한 것인지 의도가 드러나지 않고, 시간이 지나면 노이즈가 된다. 정말 조건부로 필요한 코드는 빌드 구성(조건부 컴파일)으로 의도를 명시하고, 불필요하면 삭제한다(이력은 버전관리에 남는다).Commented-out code does not reveal whether it is temporarily disabled or abandoned, and becomes noise over time. Express genuinely conditional code through build configuration (conditional compilation), and delete the rest — its history remains in version control.
Dir 4.5Advisory · Undecidable · DirPDF example
동일 네임스페이스의 식별자는 철자만 다른 혼동 이름을 피한다Identifiers in the same name space should be typographically unambiguous
❌ 위반 예시Non-compliant example
int32_t id1_abc; /* Non-compliant */ int32_t id2_ABC; /* Non- compliant */ int32_t id3_ab_c; /* Non-compliant */ int32_t id4_1; /* Non-compliant */ int32_t id5_2; /* Non-compliant */ int32_t id6_0; /* Non-compliant */ int32_t id7_8; /* Non-compliant */ int32_t id8_m; /* Non-compliant */
✅ 준수 예시Compliant example
int32_t id9_m; /* Compliant */
⚠️ l/I/1, O/0, rn/m 처럼 글꼴에 따라 구별이 어려운 이름이 같은 네임스페이스에 있으면, 잘못된 변수를 참조·수정하는 결함을 부르고 코드 리뷰에서도 놓치기 쉽다. 한 네임스페이스 안에서는 충분히 구별되는 이름을 사용한다.Names that are hard to tell apart in some fonts (l/I/1, O/0, rn/m) within one name space invite referencing or modifying the wrong variable and are easy to miss in review. Use names that are clearly distinguishable within a name space.
Dir 4.6Advisory · Undecidable · DirPDF example
기본 수치형 대신 크기·부호를 명시한 typedef를 사용한다typedefs that indicate size and signedness should be used in place of the basic numerical types
❌ 위반 예시Non-compliant example
/* Non-compliant - int used to define an object */
✅ 준수 예시Compliant example
/* Compliant - int used to define specific-length type */ /* Compliant - further abstraction does not need specific length */
⚠️ int/long/short의 폭은 구현정의라 같은 코드가 16/32/64비트 타깃에서 다르게 동작해 오버플로우·절단·플래그 손실을 일으킨다. stdint.h의 고정폭 typedef로 폭과 부호를 명시하면 산술·비트 연산이 플랫폼에 무관하게 동작한다.The widths of int/long/short are implementation-defined, so the same code behaves differently on 16/32/64-bit targets, causing overflow, truncation, and lost flags. Fixed-width typedefs from stdint.h make width and signedness explicit so arithmetic and bit operations behave identically across platforms.
Dir 4.7Required · Undecidable · Dir✓ compilablePDF rule
오류 정보를 반환하는 함수의 반환값은 반드시 검사한다If a function returns error information, then that error information shall be tested
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
FILE *f = fopen("/etc/hostname", "r");
char buf[64];
fgets(buf, sizeof buf, f); /* fopen 실패(NULL) 미검사 → 널 역참조 */
printf("%s", buf);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *f = fopen("/etc/hostname", "r");
if (f == NULL) { /* 실패를 즉시 검사하고 분기 */
return 1;
}
char buf[64];
if (fgets(buf, sizeof buf, f) != NULL) {
printf("%s", buf);
}
fclose(f);
return 0;
}⚠️ fopen·malloc·read 처럼 실패를 반환값으로 알리는 함수의 결과를 무시하면, 실패 상태(NULL 등)에서 그대로 진행해 널 역참조나 손상된 데이터 사용으로 이어진다. 반환값을 즉시 검사해 실패 경로를 명확히 처리한다.Ignoring the result of functions that report failure through a return value (fopen, malloc, read) lets execution continue from a failed state (e.g., NULL), leading to null dereference or use of corrupt data. Test the return value immediately and handle the failure path explicitly.
Dir 4.8Advisory · DirPDF rule
구조체/공용체 포인터가 역참조되지 않으면 구현을 숨겨야 한다If a pointer to a structure or union is never dereferenced within a translation unit, then the implementation of the object should be hidden
❌ 위반 예시Non-compliant example
/* sensor.h — 구현 세부가 노출되어 외부에서 내부 멤버를 직접 변경할 수 있다 */
typedef struct {
int32_t raw;
int32_t calibrated; /* 내부 전용인데 외부 접근 가능 */
} Sensor;
void sensor_update(Sensor *s);✅ 준수 예시Compliant example
/* sensor.h — 불완전 타입으로 구현을 숨긴다(opaque type) */ typedef struct Sensor Sensor; /* 정의는 sensor.c 안에만 존재 */ Sensor *sensor_create(void); void sensor_update(Sensor *s); int32_t sensor_value(const Sensor *s); /* 접근은 함수로만 */
⚠️ 포인터를 역참조하지 않는다면 구현 세부가 필요 없으므로, 불완전 타입으로 감춰 의도치 않은 변경을 막고 모듈 경계를 명확히 한다.If the pointer is never dereferenced, the implementation details are unneeded; hide them behind an incomplete (opaque) type to prevent accidental modification and clarify module boundaries.
Dir 4.9Advisory · Decidable · DirPDF example
함수형 매크로보다 함수를 사용한다A function should be used in preference to a function-like macro where they are interchangeable
❌ 위반 예시Non-compliant example
uint16_t y = DIV2 ( 10 ); /* Non-compliant - call permitted */
✅ 준수 예시Compliant example
static uint16_t x = DIV2 ( 10 ); /* Compliant - call not permitted */
⚠️ 함수형 매크로는 인자를 본문에 그대로 펼쳐 i++ 같은 부작용을 여러 번 평가하고 타입 검사도 하지 못해, 미정의 동작과 진단되지 않는 버그를 만든다. inline 함수는 동일한 성능에 인자를 한 번만 평가하고 타입 안전성까지 제공한다.A function-like macro pastes its argument into the body, evaluating side effects like i++ multiple times and skipping type checking, producing undefined behaviour and silent bugs. An inline function gives the same performance while evaluating the argument once and enforcing type safety.
Dir 4.10Required · Decidable · DirPDF rule
헤더 파일은 중복 포함을 방지(include guard)한다Precautions shall be taken in order to prevent the contents of a header file being included more than once
❌ 위반 예시Non-compliant example
/* sensor.h — include guard 없음 */
typedef struct { int id; int raw; } Sensor;
int sensor_init(Sensor *s);
/* 다른 헤더가 sensor.h 를 또 포함하면 Sensor 재정의로 컴파일 오류:
error: redefinition of 'struct Sensor' */✅ 준수 예시Compliant example
/* sensor.h — #ifndef/#define 가드로 1회만 처리 */
#ifndef SENSOR_H
#define SENSOR_H
typedef struct { int id; int raw; } Sensor;
int sensor_init(Sensor *s);
#endif /* SENSOR_H */
/* 또는 컴파일러가 지원하면 파일 첫 줄에 #pragma once */⚠️ include guard가 없는 헤더가 여러 경로로 중복 포함되면 타입·매크로가 재정의되어 컴파일 오류가 난다. #ifndef/#define/#endif 가드(또는 #pragma once)로 헤더 본문이 번역단위당 한 번만 처리되도록 보장한다.A header without an include guard, included via multiple paths, redefines types and macros and fails to compile. An #ifndef/#define/#endif guard (or #pragma once) ensures the header body is processed only once per translation unit.
Dir 4.11Required · Undecidable · Dir✓ compilablePDF rule
라이브러리 함수에 전달하는 인자의 유효성을 검사한다The validity of values passed to library functions shall be checked
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <math.h>
static double rms(double x, double v){
double r = sqrt(x); /* x<0 이면 도메인 오류 → NaN */
double l = log(v); /* v<=0 이면 도메인 오류 → -inf/NaN */
return r + l;
}
int main(void){
printf("%f\n", rms(-1.0, 0.0)); /* NaN 전파 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <math.h>
static int rms(double x, double v, double *out){
if (x < 0.0 || v <= 0.0) { return -1; } /* 정의역(domain) 사전 검사 */
*out = sqrt(x) + log(v);
return 0;
}
int main(void){
double out;
if (rms(4.0, 1.0, &out) == 0) printf("%f\n", out);
if (rms(-1.0, 0.0, &out) != 0) printf("rejected invalid domain\n");
return 0;
}⚠️ sqrt·log·memcpy 같은 라이브러리 함수는 인자가 정의역(domain)이나 길이·중첩 제약을 벗어나면 도메인 오류(NaN)나 미정의 동작을 일으킨다. 호출 전에 값의 범위·길이·별칭 여부를 검사하면 오류가 조용히 전파되는 것을 막는다.Library functions like sqrt, log, and memcpy produce domain errors (NaN) or undefined behaviour when arguments fall outside their domain or length/overlap constraints. Checking ranges, lengths, and aliasing before the call prevents errors from propagating silently.
Dir 4.12Required · Undecidable · Dir✓ compilablePDF rule
동적 메모리 할당을 사용하지 않는다Dynamic memory allocation shall not be used
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static void handle(const char *src, size_t len){
char *buf = malloc(len); /* 단편화·할당 실패·누수 위험(비결정적) */
if (buf == NULL) return;
memcpy(buf, src, len);
printf("%.*s\n", (int)len, buf);
/* free 누락 시 누수 — 안전필수 시스템에서 비결정적 실패 */
free(buf);
}
int main(void){ handle("payload", 7); return 0; }✅ 준수 예시Compliant example
#include <string.h>
#include <stdio.h>
#define MAX_LEN 256
static void handle(const char *src, size_t len){
char buf[MAX_LEN]; /* 정적/자동 저장기간 — 결정적 메모리 */
if (len > sizeof buf) { return; } /* 용량 검사 */
memcpy(buf, src, len);
printf("%.*s\n", (int)len, buf);
}
int main(void){ handle("payload", 7); return 0; }⚠️ 안전필수·실시간 시스템에서 malloc/free는 힙 단편화, 비결정적 할당 시간, 할당 실패, 누수를 야기해 장기 가동 시 예측 불가능한 실패를 만든다. 컴파일 시 크기가 정해지는 정적/자동 버퍼로 대체하면 메모리 사용이 결정적이고 검증 가능해진다.In safety-critical and real-time systems, malloc/free cause heap fragmentation, non-deterministic allocation time, allocation failure, and leaks, producing unpredictable failures over long uptimes. Replacing them with statically/automatically sized buffers makes memory use deterministic and verifiable.
R1표준 C 환경Standard C environment
Rule 1.1Required · Decidable · RulePDF rule
표준 C 구문·제약을 위반하지 않고 구현의 변환 한계를 넘지 않아야 한다The program shall contain no violations of the standard C syntax and constraints, and shall not exceed the implementation's translation limits
❌ 위반 예시Non-compliant example
/* 표준 C 위반: 반환형 생략(암시적 int) + 프로토타입 없는 호출 */
foo(void) { /* C99에서 제거된 암시적 int */
bar(); /* bar 의 선언/프로토타입이 없음 */
} /* 반환형이 있는데 값 미반환 */✅ 준수 예시Compliant example
extern void bar(void); /* 사용 전 프로토타입 선언 */
int foo(void) {
bar();
return 0; /* 표준 구문·제약 준수 */
}⚠️ 선택한 표준(C90/C99)이 정의한 기능만 사용해 구문·제약 위반과 변환 한계 초과를 피해야 정적 분석으로 검증 가능하고 동작이 예측된다.Use only features defined by the chosen Standard (C90/C99) so that the program is statically checkable and behaviour is predictable, avoiding syntax/constraint violations and translation-limit overruns.
Rule 1.2Advisory · Undecidable · RulePDF rule
언어 확장을 사용하지 않아야 한다Language extensions should not be used
❌ 위반 예시Non-compliant example
/* GCC 확장에 의존 — 이식성 저하 */
#define MAX(a,b) ({ typeof(a) _x=(a); typeof(b) _y=(b); _x>_y?_x:_y; })
int arr[] = { [0 ... 3] = 1 }; /* GCC 범위 지정 초기화 확장 */✅ 준수 예시Compliant example
/* 표준 C 기능만 사용 */
static int imax(int a, int b) { return a > b ? a : b; }
int arr[4] = { 1, 1, 1, 1 };⚠️ 언어 확장에 의존하면 이식성이 떨어지고, 확장 동작이 문서로 충분히 보장되지 않아 위험하다. 불가피하게 쓸 경우 근거와 검증 방법을 문서화한다.Relying on language extensions reduces portability and their behaviour may be underspecified; if unavoidable, document the justification and how valid use is assured.
Rule 1.3Required · Undecidable · Rule✓ compilablePDF rule
미정의(undefined) 또는 미명세(unspecified) 동작을 유발하지 않는다There shall be no occurrence of undefined or critical unspecified behaviour
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int i = 5;
i = i++ + ++i; /* 한 시퀀스 포인트 사이에서 i 를 여러 번 수정 — 미정의 */
int a[3] = {0};
int k = 0;
a[k] = k++; /* k 의 읽기/수정 순서 미명세 */
printf("%d %d\n", i, a[0]);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int i = 5;
int next = i + 1; /* 부작용을 분리해 평가 순서를 명확히 */
i = i + next;
int a[3] = {0};
int k = 0;
a[k] = k; /* 인덱스와 대입을 분리 */
k++;
printf("%d %d (k=%d)\n", i, a[0], k);
return 0;
}⚠️ 한 시퀀스 포인트 사이에서 같은 객체를 여러 번 수정하거나, 수정과 별개의 읽기를 섞으면 결과가 미정의·미명세가 되어 컴파일러·최적화 수준마다 달라진다. 부작용(증가·대입)을 별도 문장으로 분리해 평가 순서를 명확히 한다.Modifying the same object multiple times between sequence points, or mixing a modification with an unsequenced read, makes the result undefined or unspecified — varying by compiler and optimization level. Split side effects (increment, assignment) into separate statements to make evaluation order explicit.
R2미사용 코드Unused code
Rule 2.1Required · Undecidable · RulePDF example
도달 불가능한(unreachable) 코드를 두지 않는다A project shall not contain unreachable code
❌ 위반 예시Non-compliant example
*/
error_handler ( );
break;
}
}
return res;
res = c; /* Non-compliant - this statement is✅ 준수 예시Compliant example
#include <stdio.h>
static int scale(int x){
printf("scaling %d\n", x); /* 의도한 순서로 배치 */
return x * 2;
}
int main(void){ printf("%d\n", scale(21)); return 0; }⚠️ return·break·무조건 분기 이후에 놓인 도달 불가 코드는 제어 흐름을 잘못 작성했다는 신호이며, 의도한 부작용(로깅·정리)이 실행되지 않는 결함을 숨긴다. 도달 불가 코드는 제거하거나 흐름을 바로잡는다.Unreachable code after return, break, or an unconditional branch signals mis-written control flow and hides a defect where intended side effects (logging, cleanup) never run. Remove unreachable code or fix the flow.
Rule 2.2Required · Undecidable · RulePDF example
죽은(dead) 코드 — 효과 없는 연산을 두지 않는다There shall be no dead code
❌ 위반 예시Non-compliant example
g ( ); /* Non-compliant - the call could be removed */
✅ 준수 예시Compliant example
/* Compliant - there are no operations in this function */
⚠️ 결과를 사용하지 않는 연산(total + 1; / n == 6;)은 대입을 빠뜨린 오타일 때가 많아 로직 누락 버그를 가린다. 효과 없는 문장은 버그 신호로 보고 의도한 대입·호출로 수정한다.Operations whose result is discarded (total + 1; / n == 6;) are often a missed assignment and mask logic-omission bugs. Treat statements with no effect as bug signals and fix them into the intended assignment or call.
Rule 2.3Advisory · Decidable · RulePDF example
사용되지 않는 타입(typedef) 선언을 두지 않는다A project should not contain unused type declarations
❌ 위반 예시Non-compliant example
int16_t unusedtype ( void )
{
typedef int16_t local_Type; /* Non-compliant */
return 67;
}✅ 준수 예시Compliant example
#include <stdio.h>
typedef int status_t; /* 실제로 쓰이는 타입만 유지 */
static status_t run(void){ return 0; }
int main(void){ printf("%d\n", run()); return 0; }⚠️ 쓰이지 않는 typedef는 코드를 어지럽히고, 리팩터링 과정에서 무언가가 사라졌다는 흔적일 수 있어 오해를 부른다. 미사용 타입 선언은 삭제해 코드와 실제 사용을 일치시킨다.Unused typedefs clutter the code and may be a leftover from refactoring that suggests something was removed, causing confusion. Delete unused type declarations to keep code aligned with actual use.
Rule 2.4Advisory · Decidable · RulePDF example
A project should not contain unused ta g declarationsA project should not contain unused ta g declarations
❌ 위반 예시Non-compliant example
enum state { S_init, S_run, S_sleep }; /* Non-compliant */
typedef struct record_t /* Non-compliant */✅ 준수 예시Compliant example
typedef struct /* Compliant */
⚠️ Rule 2.4 (A project should not contain unused ta g declarations)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 2.4 (A project should not contain unused ta g declarations) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 2.5Advisory · Decidable · RulePDF example
A project should not contain unused ma cro declarationsA project should not contain unused ma cro declarations
❌ 위반 예시Non-compliant example
void use_macro ( void )
{
#def ine SIZE 4
/* Non-compliant - DATA not used */
#define DATA 3
use_int16 ( SIZE );
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 2.5 (A project should not contain unused ma cro declarations)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 2.5 (A project should not contain unused ma cro declarations) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 2.6Advisory · Decidable · RulePDF example
A function should not contain unused label declarationsA function should not contain unused label declarations
❌ 위반 예시Non-compliant example
void unused_label ( void )
{
int16_t x = 6;
label1: /* Non-compliant */
use_int16 ( x );
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 2.6 (A function should not contain unused label declarations)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 2.6 (A function should not contain unused label declarations) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 2.7Advisory · Decidable · RulePDF example
함수의 사용되지 않는 매개변수를 두지 않는다There should be no unused parameters in functions
❌ 위반 예시Non-compliant example
void withunusedpara ( uint1 6_t *para1,
int16_t unusedpara ) /* Non-compliant - unused */
{
*para1 = 42U;
}✅ 준수 예시Compliant example
#include <stdio.h>
static int on_event(int code, void *ctx){
(void)ctx; /* 의도적 미사용임을 명시 — 검토자에게 신호 */
return code * 2;
}
int main(void){ printf("%d\n", on_event(21, NULL)); return 0; }⚠️ 사용되지 않는 매개변수는 인터페이스 설계 오류이거나 빠뜨린 로직을 뜻할 수 있다. 콜백처럼 시그니처가 고정이어서 불가피하면 (void) 캐스트로 의도적 미사용임을 명시해 검토자에게 신호를 준다.An unused parameter may indicate an interface design error or omitted logic. When the signature is fixed (e.g., a callback), make the deliberate non-use explicit with a (void) cast to signal intent to reviewers.
R3주석Comments
Rule 3.1Required · Decidable · RulePDF example
주석 안에 /* 또는 // 문자열을 두지 않는다The character sequences /* and // shall not be used within a comment
❌ 위반 예시Non-compliant example
Perform_Critical_Safety_Function( X ); /* this comment is non-compliant */
✅ 준수 예시Compliant example
/* 이전 구현 - 임시 메모: 중첩 표기를 풀어서 한 줄로 작성 */ x = compute(); /* 주석 시작 문자(슬래시-별표)를 주석 본문에 넣지 않는다 */
⚠️ 주석 본문에 들어간 /* 는 일부 도구·사람에게 중첩 주석으로 오인되고, 먼저 나오는 */ 가 주석을 조기 종료시켜 그 뒤 텍스트가 코드로 해석되며 컴파일 오류나 의도치 않은 동작을 만든다. 주석 안에는 주석 시작 문자를 넣지 않는다.A /* inside a comment body is misread as a nested comment by some tools and people, and the first */ ends the comment early so the following text is parsed as code, causing compile errors or unintended behaviour. Do not place comment-start sequences inside comments.
Rule 3.2Required · Decidable · RulePDF example
Line-splicing shall not be used in // comment sLine-splicing shall not be used in // comment s
❌ 위반 예시Non-compliant example
extern bool_t b;
void f ( void )
{
uint16_t x = 0; // comment \
if ( b )
{
++x; /* This is always executed */
}
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 3.2 (Line-splicing shall not be used in // comment s)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 3.2 (Line-splicing shall not be used in // comment s) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
R4문자 집합Character sets
Rule 4.1Required · Decidable · RulePDF example
8진/16진 이스케이프 시퀀스는 명확히 종료한다Octal and hexadecimal escape sequences shall be terminated
❌ 위반 예시Non-compliant example
const char *s1 = "\x41g"; /* Non-compliant */ int c1 = '\141t'; /* Non-compliant */
✅ 준수 예시Compliant example
const char *s2 = "\x41" "g"; /* Compliant - terminated by end of literal */ const char *s3 = "\x41\x67"; /* Compliant - terminated by another escape */ int c2 = '\141\t'; /* Compliant - terminated by another escape */
⚠️ 16진 이스케이프 \x 는 종료 규칙이 없어 뒤따르는 모든 16진 숫자를 흡수하므로, "\x41B" 가 의도(A 뒤의 B)와 달리 하나의 큰 값으로 해석될 수 있다. 인접 문자열 리터럴로 분리하거나 8진 3자리 표기로 경계를 명확히 한다.The hex escape \x has no terminator and absorbs all following hex digits, so "\x41B" may be read as one large value rather than the intended A followed by B. Make the boundary explicit by splitting into adjacent string literals or using three-digit octal.
Rule 4.2Advisory · Decidable · RulePDF rule
트라이그래프를 사용하지 않아야 한다Trigraphs should not be used
❌ 위반 예시Non-compliant example
/* "??)" 가 트라이그래프로 치환되어 의도와 다르게 해석된다 */ const char *msg = "Enter date (yyyy-mm-dd??)"; /* ??) -> ] 로 치환 */
✅ 준수 예시Compliant example
/* '?' 중 하나를 이스케이프해 트라이그래프 형성을 막는다 */ const char *msg = "Enter date (yyyy-mm-dd?\?)";
⚠️ 트라이그래프(??x)는 전처리 이전에 다른 문자로 치환되어, 두 개의 물음표를 쓴 다른 의도와 혼동되고 예상치 못한 동작을 유발한다.Trigraphs (??x) are replaced before preprocessing and can be confused with other uses of two question marks, producing unexpected behaviour.
R5식별자Identifiers
Rule 5.1Required · Decidable · RulePDF example
외부 식별자는 유효 문자 범위 내에서 고유해야 한다External identifiers shall be distinct
❌ 위반 예시Non-compliant example
/* file1.c */ int32_t abc = 0; /* file2.c */ int32_t ABC = 0;
✅ 준수 예시Compliant example
int32_t engine_exhaust_gas_temp_scaled; /* Compliant */
⚠️ 표준은 외부 연결 식별자의 구분을 최소 31자까지만 보장하므로, 긴 공통 접두사를 공유하는 이름들은 일부 구현에서 동일 심볼로 취급되어 조용히 충돌한다. 외부 식별자는 짧게, 앞부분부터 서로 구별되도록 짓는다.The Standard only guarantees external identifiers are distinguished up to 31 characters, so names sharing a long common prefix can be treated as the same symbol on some implementations and silently collide. Keep external identifiers short and distinct from the start.
Rule 5.2Required · Decidable · RulePDF example
Identifier s declared in the same scope and name space shall be distinctIdentifier s declared in the same scope and name space shall be distinct
❌ 위반 예시Non-compliant example
static int32_t engine_exhaust_gas_temperature_scaled; /* Non-compliant */
✅ 준수 예시Compliant example
int32_t engine_exhaust_gas_temperature_local; /* Compliant */ static int32_t engine_exhaust_gas_temp_scaled; /* Compliant */
⚠️ Rule 5.2 (Identifier s declared in the same scope and name space shall be distinct)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.2 (Identifier s declared in the same scope and name space shall be distinct) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.3Required · Decidable · RulePDF example
내부 범위 식별자가 외부 범위 식별자를 가리지(shadow) 않게 한다An identifier declared in an inner scope shall not hide an identifier declared in an outer scope
❌ 위반 예시Non-compliant example
void fn1 ( void )
{
int16_t i; /* Declare an object "i" */
{
int16_t i; /* Non-compliant - hides previous "i " */
i = 3; /* Could be confusing as to which "i" this refers */
}
}
struct astruct
{
int16_t m;
};
extern void g ( struct astruct *p );
int16_t xyz = 0; /* Declare an object "xyz" */
void fn2 ( struct astruct xyz ) /* Non-compliant - outer "xyz" is✅ 준수 예시Compliant example
#include <stdio.h>
static int g_count = 0; /* 전역은 접두사로 구분 */
static void tick(void){
int local_count = 5; /* 바깥 이름과 다르게 */
local_count++;
g_count++; /* 의도가 명확 */
printf("local=%d\n", local_count);
}
int main(void){ tick(); printf("global=%d\n", g_count); return 0; }⚠️ 안쪽 범위에서 바깥 변수와 같은 이름을 선언하면(shadowing) 어느 객체를 쓰는지 혼동되어, 전역을 갱신하려다 지역만 바꾸는 결함을 만든다. 내부 식별자는 바깥 이름과 다르게(예: 접두사) 지어 가림을 방지한다.Declaring an inner-scope name identical to an outer variable (shadowing) confuses which object is used, causing defects where a global is meant to be updated but only the local changes. Name inner identifiers differently (e.g., with a prefix) to avoid hiding.
Rule 5.4Required · Decidable · RulePDF example
Macro identifiers shall be distinctMacro identifiers shall be distinct
❌ 위반 예시Non-compliant example
#define engine_exhaust_gas_temperature_scaled egt_s /* Non-compliant */
✅ 준수 예시Compliant example
#define engine_exhaust_gas_temp_scaled egt_s /* Compliant */
⚠️ Rule 5.4 (Macro identifiers shall be distinct)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.4 (Macro identifiers shall be distinct) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.5Required · Decidable · RulePDF example
Identifiers shall be distinct from macro namesIdentifiers shall be distinct from macro names
❌ 위반 예시Non-compliant example
#define Sum(x, y) ( ( x ) + ( y ) ) int16_t Sum;
✅ 준수 예시Compliant example
#define Sum(x, y) ( ( x ) + ( y ) ) int16_t x = Sum ( 1, 2 ); /* 1234567890123456789012345678901********* Characters */ #define low_pressure_turbine_temperature_1 lp_tb_temp_1 static int32_t low_pressure_turbine_temperature_2;
⚠️ Rule 5.5 (Identifiers shall be distinct from macro names)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.5 (Identifiers shall be distinct from macro names) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.6Required · Decidable · RulePDF example
typedef 이름은 고유한 식별자여야 한다A typedef name shall be a unique identifier
❌ 위반 예시Non-compliant example
typedef unsigned char u8_t; /* Non-compliant - reuse */ float32_t mass = 0.0f; /* Non-compliant - reuse */ } chain; /* Non-compliant - tag "chain" not
✅ 준수 예시Compliant example
} list; /* Compliant - exception */
⚠️ typedef 이름을 변수·함수 등 다른 식별자로 재사용하면 같은 이름이 문맥에 따라 타입도 되고 객체도 되어 가독성과 정적 분석이 모두 저하된다. typedef에는 _t 같은 구별되는 고유 이름을 부여한다.Reusing a typedef name as another identifier (variable, function) makes the same name mean a type in one context and an object in another, hurting readability and static analysis. Give typedefs a distinct, unique name such as a _t suffix.
Rule 5.7Required · Decidable · RulePDF example
A tag name shall be a unique identifierA tag name shall be a unique identifier
❌ 위반 예시Non-compliant example
union stag a2 = { 0, 0 }; /* Non-compliant - declares different type
}; /* Non-compliant - tag "deer" reused */
struct elk /* Non-compliant - declaration of different type✅ 준수 예시Compliant example
struct stag a1 = { 0, 0 }; /* Compliant - compatible with above */
} coord; /* Compliant by Exception */⚠️ Rule 5.7 (A tag name shall be a unique identifier)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.7 (A tag name shall be a unique identifier) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.8Required · Decidable · RulePDF example
Identifiers that define objects or functions with external linkage shall be uniqueIdentifiers that define objects or functions with external linkage shall be unique
❌ 위반 예시Non-compliant example
/* file1.c */
int32_t count; /* "count" has external linkage */
void foo ( void ) /* "foo" has external linkage */
{
int16_t index; /* "index" has no linkage */
}
/* file2.c */
static void foo ( void ) /* Non-compliant - "foo" is not unique
{ * (it is already defined with external✅ 준수 예시Compliant example
int32_t index; /* Compliant - "index" has no linkage */ }
⚠️ Rule 5.8 (Identifiers that define objects or functions with external linkage shall be unique)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.8 (Identifiers that define objects or functions with external linkage shall be unique) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
R6타입Types
Rule 6.1Required · Decidable · RulePDF example
Bit- fields shall only be declared with an appropriate typeBit- fields shall only be declared with an appropriate type
❌ 위반 예시Non-compliant example
int b2:2; /* Non-compliant - plain int not permitted */ signed long b4:2; /* Non-compliant even if long and int are the
✅ 준수 예시Compliant example
unsigned int b1:2; /* Compliant */ UINT_16 b3:2; /* Compliant - typedef designating unsigned int */
⚠️ Rule 6.1 (Bit- fields shall only be declared with an appropriate type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.1 (Bit- fields shall only be declared with an appropriate type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.2Required · Decidable · RulePDF rule
단일 비트 명명 비트필드는 부호형이 아니어야 한다Single-bit named bit fields shall not be of a signed type
❌ 위반 예시Non-compliant example
struct Flags {
signed int ready : 1; /* 1비트 부호형: 표현 가능 값이 0과 -1 뿐 */
int error : 1; /* int 비트필드 = signed, 동일 문제 */
};✅ 준수 예시Compliant example
struct Flags {
unsigned int ready : 1; /* 0 또는 1 을 명확히 표현 */
unsigned int error : 1;
};⚠️ 단일 비트 부호형 비트필드는 부호 비트 1개·값 비트 0개라 의미 있는 값을 담을 수 없다. 플래그는 unsigned 로 선언해야 의도대로 0/1 을 표현한다.A single-bit signed bit-field has one sign bit and zero value bits, so it cannot hold a meaningful value; declare flags as unsigned to represent 0/1 as intended.
R7리터럴·상수Literals & constants
Rule 7.1Required · Decidable · RulePDF example
8진 상수(선행 0)를 사용하지 않는다Octal constants shall not be used
❌ 위반 예시Non-compliant example
code[ 3 ] = 052; /* Non-Compliant - decimal 42 */ code[ 4 ] = 071; /* Non-Compliant - decimal 57 */
✅ 준수 예시Compliant example
code[ 1 ] = 109; /* Compliant - decimal 109 */ code[ 2 ] = 100; / * Compliant - decimal 100 */
⚠️ 선행 0이 붙은 정수 리터럴은 8진수로 해석되어 010이 8이 되고 0755가 493이 되는 등, 십진으로 오독하기 쉬워 권한 비트·코드 값 설정에서 미묘한 버그를 만든다. 십진 또는 명시적 16진(0x) 표기를 사용한다.An integer literal with a leading 0 is interpreted as octal (010 is 8, 0755 is 493), which is easily misread as decimal and produces subtle bugs in permission bits and code values. Use decimal or explicit hexadecimal (0x) notation.
Rule 7.2Required · Decidable · RulePDF example
unsigned 정수 상수에는 u/U 접미사를 붙인다A "u" or "U" suffix shall be applied to all integer constants of unsigned type
❌ 위반 예시Non-compliant example
int type and a 32-bit long type. It shows the
✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdint.h>
int main(void){
uint16_t mask = 40000u; /* unsigned 의도 명시 */
uint32_t big = 0x80000000u;
printf("%u %u\n", mask, big);
return 0;
}⚠️ 부호 없는 문맥에서 접미사 없는 정수 상수는 부호 있는 int로 먼저 해석되어, 범위를 넘으면 구현정의 변환이나 의도치 않은 부호 확장·오버플로우를 일으킨다. u/U 접미사로 상수의 부호 없음을 명시한다.In an unsigned context, an integer constant without a suffix is first interpreted as signed int, so values out of range undergo implementation-defined conversion or unintended sign extension/overflow. Apply a u/U suffix to make the constant explicitly unsigned.
Rule 7.3Required · Decidable · RulePDF example
정수 리터럴 접미사에 소문자 l을 쓰지 않는다The lowercase character "l" shall not be used in a literal suffix
❌ 위반 예시Non-compliant example
const int64_t a = 0L; const int64_t b = 0l; /* Non-compliant */ const uint64_t c = 0Lu; const uint64_t d = 0lU; /* Non-compliant */ const uint64_t e = 0ULL; const uint64_t f = 0Ull; /* Non-compliant */ const int128_t g = 0LL; const int128_t h = 0ll; /* Non-compliant */ const float128_t m = 1.2L; const float128_t n = 2.4l; /* Non-compliant */
✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
long big = 100000L; /* 대문자 L — 명확 */
long long huge = 5LL;
printf("%ld %lld\n", big, huge);
return 0;
}⚠️ 소문자 l 접미사는 글꼴에 따라 숫자 1과 거의 구분되지 않아 100000l 이 1000001 처럼 오독되는 등 값 자체를 잘못 읽게 만든다. 정수 리터럴 접미사는 항상 대문자 L/LL을 사용한다.A lowercase l suffix is nearly indistinguishable from the digit 1 in many fonts, so 100000l can be misread as 1000001, causing the value itself to be misread. Always use uppercase L/LL for integer literal suffixes.
Rule 7.4Required · Decidable · RulePDF example
문자열 리터럴을 const 가 아닌 포인터에 대입하지 않는다A string literal shall not be assigned to an object unless it has const-qualified type
❌ 위반 예시Non-compliant example
"0123456789"[0] = '*'; /* Non-compliant */ /* Non-compliant - s is not const-qualified */ f1 ( "string" ); /* Non-compliant - parameter s1 is not return ( "MISRA" ); /* Non-compliant - return type is not
✅ 준수 예시Compliant example
/* Compliant - p is const-qualified; additional qualifiers are permitted */ f2 ( "string" ); /* Compliant */ return ( "MISRA" ); /* Compliant */
⚠️ 문자열 리터럴은 읽기 전용 메모리에 놓일 수 있어 수정하면 미정의 동작(흔히 세그폴트)이 된다. 리터럴은 const char *로 받아 컴파일 단계에서 수정을 차단하고, 변경이 필요하면 별도의 수정 가능한 배열을 사용한다.A string literal may reside in read-only memory, so modifying it is undefined behaviour (often a segfault). Receive literals as const char * to block modification at compile time, and use a separate modifiable array when changes are needed.
R8선언·정의Declarations & definitions
Rule 8.1Required · Decidable · RulePDF example
타입은 명시적으로 지정한다(암시적 int 금지)Types shall be explicitly specified
❌ 위반 예시Non-compliant example
extern x; /* Non-compliant - implicit int type */ const y; /* Non-compliant - implicit int type */ extern f ( void ); /* Non-compliant - implicit extern void g ( char c, const k ); /* Non-compliant - implicit
✅ 준수 예시Compliant example
extern int16_t x; /* Compliant - explicit type */ const int16_t y; /* Compliant - explicit type */ extern int16_t f ( void ); /* Compliant */ extern void g ( char c, const int16_t k ); /* Compliant */
⚠️ 타입을 생략한 암시적 int 선언은 의도가 불명확하고 최신 C 표준(C99 이후)에서 제거되어 컴파일러마다 경고·오류로 다르게 처리된다. 모든 객체와 함수에 타입을 명시해 이식성과 가독성을 확보한다.Implicit-int declarations that omit the type are unclear and were removed in modern C (since C99), so compilers treat them inconsistently as warnings or errors. Specify the type on every object and function for portability and readability.
Rule 8.2Required · Decidable · RulePDF example
함수는 매개변수 타입을 명시한 프로토타입 형식으로 선언한다Function types shall be in prototype form with named parameters
❌ 위반 예시Non-compliant example
/* Non-compliant - parameter name not specified */ /* Non-compliant - not in prototype form */ /* Non-compliant - old style identifier and declaration list */ /* Non-compliant - no prototype */ /* Non-compliant - parameter name not specified */
✅ 준수 예시Compliant example
/* Compliant */ /* Compliant - prototype specifies 0 parameters */ /* Compliant */ /* Compliant - prototype specifies 0 parameters */ /* Compliant */
⚠️ () 형태의 빈 매개변수 선언이나 K&R 구형 정의는 인자의 개수·타입 검사를 막아 잘못된 호출을 컴파일러가 잡지 못하게 한다. 모든 함수를 명시적 프로토타입(인자 없음은 void) 형식으로 선언·정의해 호출 검사를 받게 한다.An empty () parameter declaration or old K&R definition disables checking of argument count and type, so the compiler cannot catch wrong calls. Declare and define every function in explicit prototype form (use void for no parameters) so calls are checked.
Rule 8.3Required · Decidable · RulePDF example
동일 객체/함수의 모든 선언은 이름과 타입이 일치해야 한다All declarations of an object or function shall use the same names and type qualifiers
❌ 위반 예시Non-compliant example
void g ( int * ); /* Non-compliant - type qualifiers */
✅ 준수 예시Compliant example
extern void f1 ( int16_t x );
extern void f2 ( int16_t y );
void f ( bool_t b )
{
void ( *fp1 ) ( int16_t z ) = b ? f1 : f2;
}⚠️ 한 객체·함수의 선언과 정의가 파일마다 타입이 다르면, 컴파일러는 단일 파일만 보므로 불일치를 잡지 못하고 잘못된 크기·해석으로 접근해 메모리 손상이 일어난다. 공유 헤더에 단일 선언을 두고 정의 파일이 이를 포함하게 해 일치를 강제한다.When an object/function is declared and defined with different types across files, the compiler sees only one file and cannot catch the mismatch, leading to access with the wrong size/interpretation and memory corruption. Put a single declaration in a shared header that the defining file includes to enforce agreement.
Rule 8.4Required · Decidable · RulePDF example
외부 연결 객체/함수는 정의 전에 호환되는 선언이 보여야 한다A compatible declaration shall be visible when an object or function with external linkage is defined
❌ 위반 예시Non-compliant example
/* Non-compliant - parameter types different */ /* Non-compliant - no declaration of func4 before this definition */
✅ 준수 예시Compliant example
/* Compliant */ /* Compliant - rule does not apply to objects/functions with internal
⚠️ 외부 연결 정의 시 호환 선언이 보이지 않으면, 다른 번역단위가 그 객체·함수를 잘못된 타입으로 선언해 참조해도 컴파일러가 검출하지 못한다. 헤더에 선언을 두고 정의 파일이 포함하면, 정의-선언 불일치가 컴파일 단계에서 잡힌다.If no compatible declaration is visible when an externally linked object/function is defined, the compiler cannot detect another translation unit declaring and referencing it with the wrong type. Putting the declaration in a header that the defining file includes catches definition/declaration mismatches at compile time.
Rule 8.5Required · Decidable · RulePDF rule
외부 객체/함수는 하나의 파일에서 단 한 번만 선언되어야 한다An external object or function shall be declared once in one and only one file
❌ 위반 예시Non-compliant example
/* a.h */ extern int16_t g_count; /* 선언 1 */ /* b.h */ extern int16_t g_count; /* 선언 2 — 두 헤더에 중복 선언 */
✅ 준수 예시Compliant example
/* shared.h — 외부 객체는 단 하나의 헤더에서만 선언 */ extern int16_t g_count; /* shared.c */ #include "shared.h" int16_t g_count = 0; /* 정의는 한 곳 */
⚠️ 선언을 하나의 헤더로 단일화하면 선언과 정의, 그리고 서로 다른 번역 단위 간의 일관성이 보장되어 불일치로 인한 오류를 막는다.Keeping a single declaration in one header ensures consistency between the declaration and the definition, and across translation units, preventing mismatch errors.
Rule 8.6Required · Decidable · RulePDF example
외부 연결 식별자는 정확히 하나의 정의를 가진다An identifier with external linkage shall have exactly one external definition
❌ 위반 예시Non-compliant example
/* file4.c */ int16_t k; /* Tentative definition - becomes external */ /* file5.c */ int16_t k = 0; /* External definition */
✅ 준수 예시Compliant example
/* file3.c */ int16_t j; /* Tentative definition */ int16_t j = 1; /* Compliant - external definition */
⚠️ 헤더에 변수 정의(초기화 포함)를 두면 그 헤더를 포함하는 모든 번역단위에서 같은 심볼이 중복 정의되어 링크 오류나 미정의 동작이 발생한다. 헤더에는 extern 선언만 두고, 초기화 정의는 정확히 하나의 소스 파일에만 둔다.Placing a variable definition (with initializer) in a header causes the same symbol to be defined in every translation unit that includes it, producing link errors or undefined behaviour. Keep only extern declarations in headers and put the defining initialization in exactly one source file.
Rule 8.7Advisory · Decidable · RulePDF rule
단일 번역 단위에서만 참조되는 함수/객체는 외부 링키지로 정의하지 않아야 한다Functions and objects should not be defined with external linkage if they are referenced in only one translation unit
❌ 위반 예시Non-compliant example
/* util.c — 이 파일에서만 쓰는데 외부 링키지(전역)로 노출 */
int helper_state = 0;
void helper(void) { helper_state++; }✅ 준수 예시Compliant example
/* util.c — 내부 링키지로 가시성을 제한 */
static int helper_state = 0;
static void helper(void) { helper_state++; }⚠️ static 으로 가시성을 제한하면 다른 번역 단위에서 의도치 않게 접근/호출되거나 동일 식별자와 충돌할 가능성을 줄인다.Giving internal linkage with static reduces the chance of inadvertent access/calls from other translation units and of clashes with identical identifiers.
Rule 8.8Required · Decidable · RulePDF example
내부 연결 객체/함수에는 static 을 일관되게 사용한다The static storage class specifier shall be used consistently
❌ 위반 예시Non-compliant example
static int32_t x = 0; /* definition: internal linkage */
extern int32_t x; /* Non-compliant */
static int32_t f ( void ); /* declaration: inte rnal linkage */
int32_t f ( void ) /* Non-compliant */
{
return 1;
}
static int32_t g ( void ); /* declaration: internal linkage */
extern int32_t g ( void ) /* Non-compliant */
{
return 1;
}✅ 준수 예시Compliant example
static int helper(int x); /* 선언 */
static int helper(int x){ return x + 1; } /* 정의 — static 일관 적용 */
/* 내부 연결 의도가 모든 선언/정의에서 일치 */⚠️ 같은 식별자의 선언과 정의에서 static 사용이 일치하지 않으면 내부/외부 연결이 모호해져, 컴파일러마다 심볼 가시성이 달라지고 이름 충돌·의도치 않은 노출이 생긴다. 내부 연결 의도면 모든 선언과 정의에 static을 일관되게 붙인다.Inconsistent use of static between an identifier’s declaration and definition makes internal/external linkage ambiguous, so symbol visibility varies by compiler and causes name clashes or unintended exposure. Apply static consistently to all declarations and the definition when internal linkage is intended.
Rule 8.9Advisory · Decidable · RulePDF example
단일 함수에서만 쓰이는 객체는 블록 범위로 선언한다An object should be defined at block scope if its identifier only appears in a single function
❌ 위반 예시Non-compliant example
#include <stdio.h>
static int temp; /* 파일 범위지만 오직 compute() 에서만 사용 */
static int compute(void){
temp = 21 * 2; /* 불필요한 가시성·상태 공유로 오용 위험 */
return temp;
}
int main(void){ printf("%d\n", compute()); return 0; }✅ 준수 예시Compliant example
void )
{
int32_t i;
for ( i = 0; i < N; ++i )
{
}
}⚠️ 한 함수에서만 쓰는 변수를 파일 범위에 두면 다른 코드에서 접근·수정할 수 있는 불필요한 가시성과 함수 호출 간 상태 유지가 생겨 오용과 재진입 결함을 부른다. 사용 지점에 가장 가까운 블록 범위로 선언 범위를 좁힌다.Declaring a variable used by only one function at file scope creates unnecessary visibility (other code can touch it) and state retained across calls, inviting misuse and reentrancy defects. Narrow the declaration to the innermost block scope nearest its use.
Rule 8.10Required · Decidable · RulePDF rule
inline 함수는 static 저장 클래스로 선언되어야 한다An inline function shall be declared with the static storage class
❌ 위반 예시Non-compliant example
/* 외부 링키지 inline — 정의가 없는 TU에서 호출 시 동작 미정의 */
inline int square(int x) { return x * x; }✅ 준수 예시Compliant example
/* static inline — 각 번역 단위에서 안전하게 인라인 */
static inline int square(int x) { return x * x; }⚠️ 외부 링키지 inline 함수가 같은 번역 단위에 정의되지 않으면 동작이 미정의이며, 외부 정의/인라인 정의 중 무엇이 호출될지 달라 실시간 타이밍에 영향을 줄 수 있다.An inline function with external linkage not defined in the same translation unit is undefined behaviour, and it is unspecified whether the external or inline definition is used, which can affect real-time timing.
Rule 8.11Advisory · Decidable · RulePDF example
외부 연결 배열 선언에는 크기를 명시한다When an array with external linkage is declared, its size should be explicitly specified
❌ 위반 예시Non-compliant example
extern int32_t array2[ ]; /* Non-compliant */
✅ 준수 예시Compliant example
extern int32_t array1[ 10 ]; /* Compliant */
⚠️ 크기 없는 외부 배열 선언(extern int a[];)은 다른 번역단위에서 sizeof로 요소 수를 알 수 없게 해 경계 검사·반복을 불가능하게 만든다. 외부 배열 선언에 요소 수를 명시하면 일관성과 경계 검사 가능성이 확보된다.A sizeless external array declaration (extern int a[];) prevents other translation units from learning the element count via sizeof, making bounds checks and iteration impossible. Specifying the element count in the external declaration restores consistency and checkability.
Rule 8.12Required · Decidable · RulePDF example
열거형 내 상수 값은 고유해야 한다Within an enumerator list, the value of an implicitly-specified enumeration constant shall be unique
❌ 위반 예시Non-compliant example
/* Non-compliant - yellow replicates implicit green */
✅ 준수 예시Compliant example
/* Compliant */
⚠️ 명시적 값과 암시적(앞 값+1) 지정이 섞이면 두 열거 상수가 우연히 같은 값을 가질 수 있고, 이 경우 switch 분기나 값-기반 테이블 인덱싱이 의도와 다르게 동작한다. 각 열거 상수의 값이 고유하도록 명시한다.Mixing explicit values with implicit (previous+1) ones can give two enumerators the same value, causing switch branches or value-based table indexing to behave unexpectedly. Ensure each enumerator has a unique value, specifying them explicitly.
Rule 8.13Advisory · Undecidable · RulePDF example
A pointer should point to a const-qualified type whenever possibleA pointer should point to a const-qualified type whenever possible
❌ 위반 예시Non-compliant example
{
return *p;
}
The code would be compliant if the function were de fi ned with:
uint16_t g ( const uint16_t *p )
void h ( const uint16_t *p )
{
*p = 0;
}
#include <string.h>
char last_char ( char * const s )
{
return s[ strlen ( s ) - 1u ];
}
The code would be compliant if the function were de fi ned with:
char last_char ( const char * const s )
{
return a[ 0 ];
}
The code would be compliant if the function were de fi ned with:
uint16_t first ( const uint16_t a[ 5 ] )✅ 준수 예시Compliant example
{
return *p;
}
The code would be compliant if the function were de fi ned with:
uint16_t g ( const uint16_t *p )⚠️ Rule 8.13 (A pointer should point to a const-qualified type whenever possible)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.13 (A pointer should point to a const-qualified type whenever possible) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.14Required · Decidable · RulePDF example
restrict 한정자를 사용하지 않는다The restrict type qualifier shall not be used
❌ 위반 예시Non-compliant example
void user_copy ( void * restrict p, void * restrict q, size_t n )
{
}✅ 준수 예시Compliant example
#include <string.h>
void f ( void )
{
/* memcpy has restrict-qualified parameters */
memcpy ( p, q, n );
}⚠️ restrict 는 두 포인터가 같은 메모리를 가리키지 않는다는 약속을 컴파일러에 주어 최적화를 허용하지만, 호출자가 이 약속을 어기면 컴파일러가 진단하지 못하는 미정의 동작이 발생한다. 안전필수 코드에서는 restrict 사용을 피해 이런 함정을 제거한다.restrict promises the compiler that two pointers never alias, enabling optimizations, but if the caller breaks that promise the result is undefined behaviour the compiler cannot diagnose. Avoid restrict in safety-critical code to remove this trap.
R9초기화Initialization
Rule 9.1Mandatory · Undecidable · RulePDF example
값이 설정되기 전의 객체를 읽지 않는다(미초기화 사용 금지)The value of an object with automatic storage duration shall not be read before it has been set
❌ 위반 예시Non-compliant example
{
goto L1;
uint16_t x = 10u;
x = x + 1u; /* Non-compliant - x has not been assigned a value */
}✅ 준수 예시Compliant example
#include <stdio.h>
static int total(const int *a, int n){
int sum = 0; /* 사용 전 명시적 초기화 */
for (int i = 0; i < n; i++) { sum += a[i]; }
return sum;
}
int main(void){ int d[3] = {1,2,3}; printf("%d\n", total(d, 3)); return 0; }⚠️ 자동 저장기간(지역) 객체는 자동으로 0이 되지 않으므로, 초기화 전에 읽으면 스택에 남은 불확정 값을 사용하게 되어 미정의 동작과 재현 어려운 버그를 만든다. 모든 객체를 사용 전에 명시적으로 초기화한다.Objects with automatic (local) storage are not zeroed automatically, so reading them before initialization uses indeterminate leftover stack values — undefined behaviour and hard-to-reproduce bugs. Initialize every object explicitly before use.
Rule 9.2Required · Decidable · RulePDF example
집합체/공용체 초기화는 중괄호로 구조를 맞춘다The initializer for an aggregate or union shall be enclosed in braces
❌ 위반 예시Non-compliant example
int16_t z3[ 2 ][ 2 ] = { { 0 }, [ 1 ][ 0 ] = 0, 1 }; /* Non-compliant */✅ 준수 예시Compliant example
int16_t z1[ 2 ][ 2 ] = { { 0 }, [ 1 ][ 1 ] = 1 }; /* Compliant */
}; /* Compliant */
int16_t z4[ 2 ][ 2 ] = { [ 0 ][ 1 ] = 0, { 0, 1 } }; /* Compliant */
float32_t a[ 3 ][ 2 ] = { 0 }; /* Compliant */
float32_t a[ 3 ][ 2 ] = { { 0 }, { 0 }, { 0 } }; /* Compliant */
}; /* Compliant */
} u = { 0 }; /* Compliant */
{ .len = 0u } /* Compliant - buf initialized implicitly */
}; /* Compliant - s[] fully initialized */⚠️ 중첩 집합체를 평탄한 목록으로 초기화하면 어떤 값이 어느 차원·필드로 가는지 코드만 보고는 알 수 없어 유지보수 중 잘못된 매핑이 끼어든다. 차원·구조에 맞춰 중괄호를 명시하면 초기값과 구조의 대응이 분명해진다.Initializing a nested aggregate with a flat list hides which value maps to which dimension or field, letting wrong mappings slip in during maintenance. Matching braces to the dimensions/structure makes the correspondence between values and structure explicit.
Rule 9.3Required · Decidable · RulePDF example
배열은 부분 초기화하지 않는다(모든 요소를 의도적으로 초기화)Arrays shall not be partially initialized
❌ 위반 예시Non-compliant example
/* Non-compliant - y[ 2 ] is implicitly initialized */
✅ 준수 예시Compliant example
float32_t arr[ 3 ][ 2 ] =
{
{ 0.0f, 0.0f },
{ PI / 4.0f, -PI / 4.0f },
{ 0 } /* initializes all elements of array subobject arr[ 2 ] */
};
char h[ 10 ] = "Hello"; /* Compliant by Exception 3 */⚠️ 배열을 일부만 초기화하면 나머지 요소가 0으로 채워지는 것이 의도된 설계인지 빠뜨린 실수인지 코드만으로 알 수 없어 검토·유지보수에서 오해를 부른다. 모든 요소를 명시하거나 전체 0 초기화처럼 의도가 분명한 관용표현을 쓴다.Partially initializing an array leaves it unclear whether the zero-filled remainder is intended or an omission, causing misunderstanding in review and maintenance. Specify all elements, or use an unambiguous idiom such as full zero-initialization.
Rule 9.4Required · Decidable · RulePDF example
집합체 초기화에서 같은 요소를 중복 초기화하지 않는다An element of an object shall not be initialized more than once
❌ 위반 예시Non-compliant example
uint16_t *p;
void f ( void )
{
uint16_t a[ 2 ] = { [ 0 ] = *p++, [ 0 ] = 1 };
}
struct mystruct
{
int32_t a;
int32_t b;
int32_t c;
int32_t d;
};
/*
*/
struct mystruct s1 = { 100, -1, 42, 999 };
/*
*/
struct mystruct s2 = { .a = 100, .b = -1, .c = 42, .d = 999 };
/*
*/
struct mystruct s3 = { .a = 100, .b = -1, .a = 42, .d = 999 };✅ 준수 예시Compliant example
*/
int16_t a1[ 5 ] = { -5, -4, -3, -2, -1 };⚠️ 지정 초기자(designated initializer)에서 같은 요소를 두 번 지정하면 앞의 값이 진단 없이 덮어써져, 둘 중 어느 것이 의도인지 모호한 채로 버그가 숨는다. 각 요소는 정확히 한 번만 초기화한다.Specifying the same element twice in a designated initializer silently overwrites the earlier value, hiding a bug with ambiguous intent. Initialize each element exactly once.
Rule 9.5Required · Decidable · RulePDF example
지정 초기자로 배열을 초기화할 때는 크기를 명시한다Where designated initializers are used to initialize an array, the size shall be specified explicitly
❌ 위반 예시Non-compliant example
/* Non-compliant - probably unint entional to have single element */
✅ 준수 예시Compliant example
/* Compliant */
⚠️ 지정 초기자만으로 배열 크기를 암묵 결정하면, 가장 큰 인덱스에 따라 크기가 정해져 의도한 용량과 달라지고 이후 경계 가정이 깨진다. 배열 크기를 명시해 용량을 코드에 분명히 드러낸다.Letting designated initializers implicitly determine the array size makes the size depend on the largest index, diverging from the intended capacity and breaking later bounds assumptions. Specify the array size explicitly so the capacity is clear in the code.
R10essential type 모델Essential type model
Rule 10.1Required · Decidable · RulePDF example
피연산자는 부적절한 essential type으로 사용하지 않는다Operands shall not be of an inappropriate essential type
❌ 위반 예시Non-compliant example
ena += a1 /* Rationale 5 - enum type used in arithmetic operation */
✅ 준수 예시Compliant example
/* Compliant as K1 from anonymous
⚠️ essential type 범주(불리언·문자·부호 있는/없는 정수·부동소수·열거)에 맞지 않는 연산은 암묵 변환을 거치며 의도와 다른 결과를 낸다. 불리언 문맥에는 명시적 비교를, 시프트·비트 연산에는 부호 없는 정수를 사용해 변환을 통제한다.Operations that do not match an operand’s essential type category (boolean, character, signed/unsigned integer, floating, enum) go through implicit conversions and produce unintended results. Use explicit comparisons in boolean contexts and unsigned integers for shift/bitwise operations to control conversions.
Rule 10.2Required · Decidable · Rule✓ compilablePDF rule
문자형(char) 값은 덧셈/뺄셈 외 산술에 사용하지 않는다Expressions of essentially character type shall not be used inappropriately in addition and subtraction operations
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
char a = 'A';
char b = a * 2; /* plain char 에 곱셈 — 부호·폭이 구현정의라 결과가 흔들림 */
printf("%d\n", (int)b);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
char a = 'A';
int code = (int)a; /* 산술이 필요하면 명시적으로 정수형으로 변환 */
int b = code * 2;
printf("%d\n", b);
return 0;
}⚠️ plain char 는 signed/unsigned 여부가 구현정의이므로 곱셈·시프트 같은 산술에 쓰면 같은 코드가 플랫폼마다 다른 값을 낸다. 문자에서 수치 계산이 필요하면 먼저 명시적으로 정수형으로 변환해 의미와 폭·부호를 고정한다.Because plain char has implementation-defined signedness, using it in arithmetic such as multiplication or shifting makes the same code yield different values across platforms. When a numeric computation on a character is needed, first convert it explicitly to an integer type to fix meaning, width, and signedness.
Rule 10.3Required · Decidable · RulePDF example
표현식 값을 더 좁거나 다른 essential type 범주로 대입하지 않는다The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category
❌ 위반 예시Non-compliant example
uint8_t u8a = 1.0f; /* unsigned and floating */
bool_t bla = 0; /* boolean and signed */
cha = 7; /* character and signed */
u8a = 'a'; /* unsigned and character */
u8b = 1 - 2; /* unsigned and signed */
u8c += 'a'; /* u8c = u8c + 'a' assigns character to unsigned */
use_uint32 ( s32a ); /* signed and unsigned */
s8a = K2; /* Constant value does not fit */
u16a = u32a; /* uint32_t to uint16_t */
use_uint16 ( u32a ); /* uint32_t to uint16_t */
uint8_t foo1 ( uint16_t x )
{
return x; /* uint16_t to uint8_t */
}✅ 준수 예시Compliant example
uint8_t u8a = 0; /* By exception */ bool_t flag = ( bool_t ) 0; bool_t set = true; /* true is essentially Boolean */ bool_t get = ( u8b > u8c ); ena = A1; s8a = K1; /* Constant value fits */ u8a = 2; /* By exception */ u8a = 2 * 24; /* By exception */ cha += 1; /* cha = cha + 1 assigns character to character */ pu8a = pu8b; /* Same essential type */ u8a = u8b + u8c + u8d; /* Same essential type */ u8a = ( uint8_t ) s8a; /* Cast gives same essential type */ u32a = u16a; /* Assignment to a wider essential type */ u32a = 2U + 125U; /* Assignment to a wider essential type */ use_uint16 ( u8a ); /* Assignment to a wider essential type */ use_uint16 ( u8a + u16b ); /* Assignment to same essential type */
⚠️ 넓은 타입의 값을 더 좁은 타입에 암묵적으로 대입하면 상위 비트가 조용히 잘리거나 부호가 바뀌어 의도와 다른 값이 저장된다. 대입 전 범위를 검사하고, 좁히는 변환은 명시적 캐스트로 의도를 드러낸다.Implicitly assigning a wide value to a narrower type silently truncates high bits or flips the sign, storing an unintended value. Check the range before assigning and make the narrowing explicit with a cast to show intent.
Rule 10.4Required · Decidable · RulePDF example
산술 연산의 두 피연산자는 같은 essential type 범주여야 한다Both operands of an operator in which the usual arithmetic conversions are performed shall have the same essential type category
❌ 위반 예시Non-compliant example
s8a += u8a /* signed and unsigned */ ena == enb /* enum<enuma> and enum<enumb> */ u8a += cha /* unsigned and char */
✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int u = 1;
int s = -2;
if (u + s > 0) { /* 부호 범주를 통일 → -1, 직관대로 거짓 */
printf("positive\n");
} else {
printf("not positive\n");
}
return 0;
}⚠️ 부호 있는 타입과 없는 타입을 한 연산에 섞으면 일반 산술 변환으로 음수가 거대한 양수로 바뀌어, u + s > 0 같은 비교가 직관과 정반대로 동작한다. 피연산자의 부호 범주를 통일해 변환에 의한 함정을 제거한다.Mixing signed and unsigned types in one operation triggers the usual arithmetic conversions that turn a negative into a huge positive, so comparisons like u + s > 0 behave opposite to intuition. Unify the signedness category of the operands to remove this conversion trap.
Rule 10.5Advisory · Decidable · RulePDF example
The value of an expression should not be cast to an inappropriate essential ty peThe value of an expression should not be cast to an inappropriate essential ty pe
❌ 위반 예시Non-compliant example
/* Non-compliant */ ( int32_t ) ena
✅ 준수 예시Compliant example
/* Compliant - C99 'false' is essentially Boolean */ ( int32_t ) 3U
⚠️ Rule 10.5 (The value of an expression should not be cast to an inappropriate essential ty pe)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 10.5 (The value of an expression should not be cast to an inappropriate essential ty pe) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 10.6Required · Decidable · RulePDF example
복합 표현식 결과를 더 넓은 essential type에 대입하지 않는다The value of a composite expression shall not be assigned to an object with wider essential type
❌ 위반 예시Non-compliant example
u32a = u16a + u16b; /* Implicit conversion on assignment */ use_uint32 ( u16a + u16b ); /* Implicit conversion of fn argument */
✅ 준수 예시Compliant example
u16c = u16a + u16b; /* Same essential type */ u32a = ( uint32_t ) u16a + u16b; /* Cast causes addition in uint32_t */
⚠️ 좁은 타입끼리 계산한 복합 표현식을 더 넓은 타입에 대입하면, 계산이 좁은(또는 int 로 승격된) 폭에서 일어난 뒤 확장되어 오버플로우·래핑이 결과에 숨는다. 연산 전에 피연산자를 목표 폭으로 명시적으로 넓혀 손실을 방지한다.Assigning a composite expression computed in narrow types to a wider type lets the computation happen at the narrow (or int-promoted) width before widening, hiding overflow/wraparound in the result. Widen the operands to the target width explicitly before the operation to avoid loss.
Rule 10.7Required · Decidable · RulePDF example
If a composite expression is used as one operand of an operator in which the usual arithmetic conversions are performed then the other operand shall not have wider essential typeIf a composite expression is used as one operand of an operator in which the usual arithmetic conversions are performed then the other operand shall not have wider essential type
❌ 위반 예시Non-compliant example
u32a += ( u16a + u16b ) /* Implicit conversion of ( u16a + u16b ) */
✅ 준수 예시Compliant example
u32a += ( u32b + u16b ) /* No composite conversion */
⚠️ Rule 10.7 (If a composite expression is used as one operand of an operator in which the usual arithmetic conversions are performed then the other operand shall not have wider essential type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 10.7 (If a composite expression is used as one operand of an operator in which the usual arithmetic conversions are performed then the other operand shall not have wider essential type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 10.8Required · Decidable · RulePDF example
복합 표현식 값을 다른/넓은 essential type으로 캐스트하지 않는다The value of a composite expression shall not be cast to a different or wider essential type
❌ 위반 예시Non-compliant example
/* Non -compliant - different essential
✅ 준수 예시Compliant example
/* Compliant */ ( uint16_t ) ( s32a + s32b )
⚠️ 좁은 폭에서 평가된 복합 표현식을 사후에 넓은 타입으로 캐스트해도, 이미 손실(래핑·절단)된 비트는 되살아나지 않는다. 캐스트는 표현식 전체가 아니라 피연산자 단계에서 적용해 계산 자체가 넓은 폭에서 일어나게 한다.Casting a composite expression to a wider type after it was evaluated at narrow width cannot recover bits already lost to wraparound or truncation. Apply the cast to the operands, not the whole expression, so the computation itself happens at the wider width.
R11포인터 변환Pointer conversions
Rule 11.1Required · Decidable · RulePDF example
함수 포인터를 호환되지 않는 타입으로 변환하지 않는다Conversions shall not be performed between a pointer to a function and any other type
❌ 위반 예시Non-compliant example
fp32 fp2 = ( fp32 ) fp1; /* Non-compliant - function
✅ 준수 예시Compliant example
extern void f ( int16_t n ); f ( 1 ); /* Compliant - exception 3 - implicit conversion fp16 fp5 = f; /* Compliant - exception 3 */
⚠️ 함수 포인터와 객체 포인터(또는 다른 시그니처의 함수 포인터)는 호출 규약·내부 표현이 달라, 변환 후 호출하면 미정의 동작과 충돌을 일으킨다. 호환되는 동일 시그니처의 함수만 대입한다.Function pointers and object pointers (or function pointers with a different signature) have different calling conventions and representations, so calling through a converted pointer causes undefined behaviour and crashes. Only assign functions of a compatible, identical signature.
Rule 11.2Required · Decidable · RulePDF rule
불완전 타입 포인터와 다른 타입 간 변환을 수행하지 않아야 한다Conversions shall not be performed between a pointer to an incomplete type and any other type
❌ 위반 예시Non-compliant example
struct Opaque; /* 불완전 타입 */
void use(struct Opaque *p) {
unsigned char *raw = (unsigned char *)p; /* 불완전 타입 포인터를 변환 */
raw[0] = 0; /* 정렬/표현 미정의 동작 위험 */
}✅ 준수 예시Compliant example
struct Opaque;
extern void opaque_reset(struct Opaque *p); /* 변환 없이 전용 API로만 다룬다 */
void use(struct Opaque *p) {
opaque_reset(p);
}⚠️ 불완전 타입 포인터를 다른 타입으로 변환하면 정렬이 맞지 않거나 부동소수 변환 시 항상 미정의 동작이 된다. 변환 없이 전용 API로만 다뤄야 한다.(void* 는 Rule 11.5 적용)Converting a pointer to an incomplete type may produce a misaligned pointer (and is always undefined with floating types); handle it only through dedicated APIs without conversion. (void* is covered by Rule 11.5.)
Rule 11.3Required · Decidable · RulePDF example
서로 다른 객체 타입을 가리키는 포인터 간 캐스트를 하지 않는다A cast shall not be performed between a pointer to object type and a pointer to a different object type
❌ 위반 예시Non-compliant example
int * const * pcpi; const int * const * pcpci; pcpci = ( const int * const * ) pcpi;
✅ 준수 예시Compliant example
const short *p; const volatile short *q; q = ( const volatile short * ) p; /* Compliant */
⚠️ 다른 객체 타입으로 포인터를 캐스트해 접근하면 정렬되지 않은 접근과 엄격 별칭(strict aliasing) 규칙 위반으로 미정의 동작이 되어, 최적화 시 예측 불가한 결과가 나온다. 표현을 재해석할 때는 memcpy로 바이트 단위 복사를 사용한다.Accessing through a pointer cast to a different object type causes misaligned access and strict-aliasing violations — undefined behaviour that yields unpredictable results under optimization. Use memcpy for a byte-wise copy when reinterpreting a representation.
Rule 11.4Advisory · Decidable · RulePDF example
정수와 객체 포인터 사이를 변환하지 않는다A conversion should not be performed between a pointer to object and an integer type
❌ 위반 예시Non-compliant example
uint8_t *PORTA = ( uint8_t * ) 0x0002; /* Non-compliant */
uint16_t *p;
int32_t addr = ( in t32_t ) &p; /* Non-compliant */
uint8_t *q = ( uint8_t * ) addr; /* Non-compliant */
bool_t b = ( bool_t ) p; /* Non-compliant */
enum etag { A, B } e = ( enum etag ) p; /* Non-compliant */✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdint.h>
static volatile uint8_t device_register; /* 실제 객체로 모델링 */
static volatile uint8_t *reg_access(void){ return &device_register; }
int main(void){
volatile uint8_t *reg = reg_access(); /* 포인터 타입을 유지하는 접근자 */
*reg = 1u;
printf("%u\n", (unsigned)device_register);
return 0;
}⚠️ 정수와 포인터를 직접 변환하면 표현 차이로 잘못된 주소 접근이 생기고, 어떤 주소를 다루는지 코드만으로 검증하기 어려워진다. 메모리맵 레지스터처럼 불가피한 경우는 의미를 캡슐화한 접근자 한 곳에 가두고, 그 외에는 포인터 타입을 그대로 유지한다.Directly converting between integers and pointers risks wrong-address access due to representation differences and makes it hard to verify which address is handled. When unavoidable (e.g., memory-mapped registers), confine it to a single encapsulated accessor and otherwise keep values in pointer types.
Rule 11.5Advisory · Decidable · RulePDF example
A conversion should not be performed from pointer to void into pointer to objectA conversion should not be performed from pointer to void into pointer to object
❌ 위반 예시Non-compliant example
p16 = p; /* Non-compliant */ p32 = ( uint32_t * ) p; /* Non-compliant */
✅ 준수 예시Compliant example
p = p32; /* Compliant - pointer to uint32_t into p = ( void * ) p16; /* Compliant */
⚠️ Rule 11.5 (A conversion should not be performed from pointer to void into pointer to object)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 11.5 (A conversion should not be performed from pointer to void into pointer to object) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 11.6Required · Decidable · RulePDF example
void 포인터와 정수 사이를 변환하지 않는다A cast shall not be performed between pointer to void and an arithmetic type
❌ 위반 예시Non-compliant example
void * p; uint32_t u; /* Non-compliant - implementation-defined */ p = ( void * ) 0x1234u; /* Non-compliant - undefined */ p = ( void * ) 1024.0f; /* Non-compliant - implementation-defined */ u = ( uint32_t ) p;
✅ 준수 예시Compliant example
#include <stdio.h>
static int ctx = 7;
static void use_ctx(void *p){ printf("%d\n", *(int *)p); }
int main(void){
void *p = &ctx;
use_ctx(p); /* 포인터를 포인터 타입 그대로 보관·전달 */
return 0;
}⚠️ void* 를 정수로 바꿔 저장했다 복원하면, 정수 폭이 포인터를 온전히 담지 못하는 플랫폼에서 주소가 손상될 수 있다. 포인터는 포인터 타입 그대로 유지·전달하고, 정수 왕복을 피한다.Storing a void* as an integer and restoring it can corrupt the address on platforms where the integer width cannot hold the full pointer. Keep and pass pointers in pointer types and avoid round-tripping through integers.
Rule 11.7Required · Decidable · RulePDF example
A cast shall not b e performed between pointer to object and a non- integer arithmetic typeA cast shall not b e performed between pointer to object and a non- integer arithmetic type
❌ 위반 예시Non-compliant example
int16_t * p; float32_t f; f = ( float32_t ) p; /* Non-compliant */ p = ( int16_t * ) f; /* Non-compliant */
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 11.7 (A cast shall not b e performed between pointer to object and a non- integer arithmetic type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 11.7 (A cast shall not b e performed between pointer to object and a non- integer arithmetic type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 11.8Required · Decidable · RulePDF example
캐스트로 포인터가 가리키는 대상의 const/volatile 한정자를 제거하지 않는다A cast shall not remove any const or volatile qualification from the type pointed to by a pointer
❌ 위반 예시Non-compliant example
pi = (uint16_t *)pci; /* Non-compliant */ pi = (uint16_t *)pvi; /* Non-compliant */ ppi = (uint16_t * *)pcpi; /* Non-compliant */
✅ 준수 예시Compliant example
pi = cpi; /* Compliant - no conversion
⚠️ 캐스트로 const/volatile 를 떼어내고 대상을 수정하면, 읽기 전용 메모리 수정이나 컴파일러의 잘못된 최적화로 미정의 동작이 된다. 한정자는 보존하고, 변경이 필요하면 한정자 없는 복사본을 만들어 다룬다.Casting away const/volatile and then modifying the target causes undefined behaviour through writes to read-only memory or incorrect compiler optimizations. Preserve the qualifiers and, when modification is needed, work on an unqualified copy.
Rule 11.9Required · Decidable · RulePDF example
널 포인터 상수로는 매크로 NULL을 사용한다(정수 0 직접 사용 금지)The macro NULL shall be the only permitted form of integer null pointer constant
❌ 위반 예시Non-compliant example
int32_t *p1 = 0; /* Non-compliant */ if ( p1 == MY_NULL_1 ) /* Non-compliant */
✅ 준수 예시Compliant example
int32_t *p2 = ( void * ) 0; /* Compliant */ if ( p2 == MY_NULL_2 ) /* Compliant */ /* Could also be stdio.h, stdlib.h and others */ #include <stddef.h> extern void f ( uint8_t *p ); /* Compliant for any conforming definition of NULL, such as:
⚠️ 정수 0 을 널 포인터로 직접 쓰면 포인터 문맥인지 정수 문맥인지 코드만으로 구분되지 않아 가독성과 의도가 흐려진다. 널 포인터 상수는 일관되게 NULL 매크로로 표기해 포인터임을 분명히 한다.Using the integer 0 directly as a null pointer makes it unclear whether the context is pointer or integer, blurring readability and intent. Consistently write null pointer constants as the NULL macro to make the pointer nature explicit.
R12표현식Expressions
Rule 12.1Advisory · Decidable · RulePDF example
연산자 우선순위는 괄호로 명시한다The precedence of operators within expressions should be made explicit
❌ 위반 예시Non-compliant example
sizeof x + y; /* Non-compliant - write either sizeof ( x ) + y /* Non-compliant
✅ 준수 예시Compliant example
a[ i ]->n; /* Compliant - no need to write ( a[ i ] )->n */ *p++; /* Compliant - no need to write *( p++ ) */ /* Compliant - no need to write f ( ( a + b ), c ) */ /* Compliant */ /* Compliant /* Compliant /* Compliant x = a, b; /* Compliant - parsed as ( x = a ), b */
⚠️ 시프트·비트·산술 연산이 섞인 표현식은 우선순위를 사람이 오해하기 쉬워, 작성자의 의도와 컴파일러의 해석이 어긋난다. 괄호로 평가 순서를 분명히 하면 의도가 코드에 드러나고 검토 오류가 줄어든다.Expressions mixing shift, bitwise, and arithmetic operators are easy for humans to misread on precedence, so the author’s intent and the compiler’s interpretation diverge. Parentheses make the evaluation order explicit, surfacing intent and reducing review errors.
Rule 12.2Required · Undecidable · RulePDF example
시프트 횟수는 0 이상이며 피연산자 비트폭 미만이어야 한다The right operand of a shift shall lie in the range zero to one less than the width of the left operand
❌ 위반 예시Non-compliant example
u8a = u8a << 8; /* Non-compliant */ 1u << 10u; /* Non-compliant */
✅ 준수 예시Compliant example
u8a = u8a << 7; /* Compliant */ u16a = ( uint16_t ) u8a << 9; /* Compliant */ ( uint16_t ) 1u << 10u; /* Compliant */ 1UL << 10u; /* Compliant */
⚠️ 피연산자의 비트폭 이상으로, 또는 음수로 시프트하면 결과가 미정의가 되어 0·원값·쓰레기 등 플랫폼마다 다르게 동작한다. 시프트량을 0..(폭-1) 범위로 검증한 뒤에만 시프트한다.Shifting by the operand width or more, or by a negative amount, is undefined behaviour that yields 0, the original, or garbage depending on the platform. Validate the shift amount to the range 0..(width-1) before shifting.
Rule 12.3Advisory · Decidable · RulePDF example
쉼표 연산자를 사용하지 않는다The comma operator should not be used
❌ 위반 예시Non-compliant example
for ( i = 0, p = &a[ 0 ]; i < N; ++i, ++p )
{
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int n = 4;
int j = n;
for (int i = 0; i < j; i++) { /* 부작용을 문장으로 분리 — 흐름이 명확 */
printf("%d-%d ", i, j);
j--;
}
printf("\n");
return 0;
}⚠️ 쉼표 연산자는 한 표현식에 여러 부작용을 압축해 평가 순서와 의도를 가려, 가독성과 정적 분석을 모두 떨어뜨린다. 부작용을 독립된 문장으로 분리하면 제어 흐름이 분명해진다.The comma operator packs multiple side effects into one expression, obscuring evaluation order and intent and hurting both readability and static analysis. Splitting side effects into separate statements makes the control flow clear.
Rule 12.4Advisory · Decidable · RulePDF example
Evaluation of constant expressions should not lead to unsigned integer wrap-aroundEvaluation of constant expressions should not lead to unsigned integer wrap-around
❌ 위반 예시Non-compliant example
uint16_t y = b ? 0u : ( 0u - 1u ); /* Non-compliant */
✅ 준수 예시Compliant example
uint16_t y = c + 1u; /* Compliant */ uint16_t x = ( 0u == 0u ) ? 0u : ( 0u - 1u ); /* Compliant */
⚠️ Rule 12.4 (Evaluation of constant expressions should not lead to unsigned integer wrap-around)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 12.4 (Evaluation of constant expressions should not lead to unsigned integer wrap-around) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
R13부작용Side effects
Rule 13.1Required · Undecidable · RulePDF example
초기자 목록에는 영속적 부작용을 두지 않는다Initializer lists shall not contain persistent side effects
❌ 위반 예시Non-compliant example
/* Non-compliant - volatile access is persistent side effect */ /* Non-compliant - two side effects */
✅ 준수 예시Compliant example
/* Compliant - no side effects */
⚠️ 초기자 목록 요소들의 평가 순서는 표준이 정하지 않으므로, 요소에 영속적 부작용(전역 갱신·입출력)이 있으면 결과가 비결정적이 된다. 부작용은 초기자 밖에서 정해진 순서로 처리하고 초기자에는 그 결과값만 넣는다.The Standard does not fix the evaluation order of initializer-list elements, so persistent side effects (global updates, I/O) in them make the result non-deterministic. Perform side effects outside the initializer in a defined order and place only their resulting values in the initializer.
Rule 13.2Required · Undecidable · Rule✓ compilablePDF rule
표현식의 값과 부작용은 모든 평가 순서에서 동일해야 한다The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int arr[4] = {0};
int i = 1;
arr[i] = i++; /* i 의 인덱스 사용과 증가 순서가 미명세 */
printf("%d %d\n", arr[1], arr[2]);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int arr[4] = {0};
int i = 1;
arr[i] = i; /* 사용과 수정을 분리 — 순서에 무관하게 결정적 */
i++;
printf("%d %d\n", arr[1], arr[2]);
return 0;
}⚠️ 한 표현식에서 같은 객체를 읽으면서 동시에 수정하면(arr[i] = i++) 컴파일러가 허용하는 평가 순서에 따라 결과가 달라져 이식·최적화 시 버그가 된다. 읽기와 수정을 별도 문장으로 분리해 모든 순서에서 같은 결과가 나오게 한다.Reading and modifying the same object in one expression (arr[i] = i++) makes the result depend on the compiler’s permitted evaluation order, becoming a bug across ports and optimizations. Split the read and the modification into separate statements so the result is the same under every order.
Rule 13.3Advisory · Undecidable · RulePDF example
증감 연산자(++/--)를 다른 부작용과 한 표현식에 섞지 않는다A full expression containing an increment or decrement operator should have no other potential side effects
❌ 위반 예시Non-compliant example
u8a = ( 1u == 1u ) ? 0u : u8b++;
if ( u8a++ == ( ( 1u == 1u ) ? 0u : f ( ) ) )
{
}✅ 준수 예시Compliant example
x++;
a[ i ]++;
b.x++;
c->x++;
++( *p );
*p++;
( *p )++;
if ( ( f ( ) + --u8a ) == 0u )
{
}
g ( u8b++ );⚠️ ++/-- 를 다른 부작용(함수 호출·대입)과 한 표현식에 결합하면, 어떤 부작용이 먼저 일어나는지 평가 순서에 의존해 결과가 모호해진다. 증감을 독립 문장으로 분리하면 순서가 명확해지고 결과가 결정적이 된다.Combining ++/-- with other side effects (function calls, assignments) in one expression makes the result depend on which side effect happens first. Splitting the increment/decrement into its own statement makes the order clear and the result deterministic.
Rule 13.4Advisory · Decidable · RulePDF example
대입 연산자의 결과값을 사용하지 않는다The result of an assignment operator should not be used
❌ 위반 예시Non-compliant example
a[ x ] = a[ x = y ]; /* Non-compliant - the value of x = y /* Non-compliant even though bool_var = true isn't evaluated */ /* Non-compliant - value of x = f() is used */ /* Non-compliant - value of b += c is used */ /* Non-compliant - values of c = 0 and b = c = 0 are used */
✅ 준수 예시Compliant example
x = y; /* Compliant */
⚠️ 대입의 결과값을 조건·표현식에 사용하면 의도한 비교(==)를 실수로 대입(=)한 흔한 버그와 시각적으로 구분되지 않아 검토에서 놓치기 쉽다. 대입과 검사를 분리하면 의도가 분명해지고 오타 버그가 드러난다.Using the value of an assignment in a condition is visually indistinguishable from the common bug of writing assignment (=) instead of comparison (==), so it is easily missed in review. Separating the assignment from the test makes intent clear and surfaces typo bugs.
Rule 13.5Required · Undecidable · RulePDF example
&&/|| 의 우변에는 영속적 부작용을 두지 않는다The right hand operand of a logical && or || operator shall not contain persistent side effects
❌ 위반 예시Non-compliant example
/* Non-compliant - h ( ) has a persistent side effect */ /* Non-compliant - access to volatile v is persistent */ /* Non-compliant if fp points to a function with persistent side effects */
✅ 준수 예시Compliant example
/* Compliant - f ( ) has no persistent side effects */
⚠️ &&/|| 는 단락 평가(short-circuit)라 좌변 결과에 따라 우변이 아예 실행되지 않을 수 있어, 우변에 둔 부작용(대입·호출)이 조건부로 누락되어 상태가 일관되지 않게 된다. 부작용은 논리 연산 밖으로 빼 항상 정해진 대로 수행한다.&& and || short-circuit, so the right operand may not run at all depending on the left, causing side effects (assignments, calls) placed there to be conditionally skipped and leaving inconsistent state. Move side effects outside the logical operator so they always run as intended.
Rule 13.6Mandatory · Decidable · RulePDF example
sizeof 피연산자에는 부작용이 있는 표현식을 두지 않는다The operand of the sizeof operator shall not contain any expression which has potential side effects
❌ 위반 예시Non-compliant example
s = sizeof ( j++ ); /* Non-compliant */ s = sizeof ( int32_t[ n++ ] ); /* Non-compliant */ s = sizeof ( void ( *[ n ] ) ( int32_t a[ v ] ) ); /* Non-compliant */
✅ 준수 예시Compliant example
s = sizeof ( j ); /* Compliant */ s = sizeof ( i ); /* Compliant - exception */ s = sizeof ( int32_t ); /* Compliant */ s = sizeof ( int32_t[ n ] ); /* Compliant */
⚠️ sizeof 의 피연산자는 (가변길이 배열 제외) 평가되지 않으므로, 그 안에 둔 i++ 같은 부작용은 실제로 일어나지 않아 의도한 증가가 조용히 사라진다. sizeof 안에는 부작용 없는 표현식만 두고 부작용은 별도 문장으로 분리한다.The operand of sizeof is not evaluated (except for VLAs), so a side effect like i++ inside it never happens and the intended increment silently disappears. Put only side-effect-free expressions inside sizeof and perform side effects in separate statements.
R14제어문 표현식Control-stmt expressions
Rule 14.1Required · Undecidable · RulePDF example
반복 카운터로 부동소수형을 사용하지 않는다A loop counter shall not have essentially floating type
❌ 위반 예시Non-compliant example
float32_t f = 0.0f;
while ( f < 1.0f )
{
f += 0.001f;
}✅ 준수 예시Compliant example
float32_t f;
for ( uint32_t counter = 0u; counter < 1000u; ++counter )
{
f = ( float32_t ) counter * 0.001f;
}
float32_t f;
uint32_t u32a;
f = read_float32 ( );
{
u32a = read_u32 ( );
/* f does not change in the loop so cannot be a loop counter */
} while ( ( ( float32_t ) u32a - f ) > 10.0f );⚠️ 0.1 처럼 이진 부동소수로 정확히 표현되지 않는 값을 카운터 증분으로 쓰면 표현 오차가 누적되어 x != 1.0f 같은 종료 조건을 정확히 만족하지 못하고 무한 루프가 된다. 정수 카운터로 반복하고 필요한 실수값은 카운터에서 파생한다.Using an increment like 0.1 that cannot be represented exactly in binary floating point accumulates rounding error, so termination tests like x != 1.0f are never met and the loop runs forever. Iterate with an integer counter and derive any floating value from it.
Rule 14.2Required · Undecidable · RulePDF example
for 루프는 잘 정의된 형태(초기화·조건·증감 일관)여야 한다A for loop shall be well-formed
❌ 위반 예시Non-compliant example
} i = i + 3; /* Non-compliant - altering the loop
✅ 준수 예시Compliant example
bool_t flag = false;
for ( int16_t i = 0; ( i < 5 ) && !flag; i++ )
{
if ( C )
{
flag = true; /* Compliant - allows early termination⚠️ for 헤더의 증감부가 카운터와 무관한 작업을 하고 카운터 제어가 본문으로 흩어지면, 루프의 반복 횟수와 종료 조건을 한눈에 이해·검증하기 어렵다. 헤더(초기화·조건·증감)는 카운터 제어만, 본문은 작업만 담당하게 분리한다.When a for header’s update does work unrelated to the counter and counter control leaks into the body, the loop’s iteration count and termination become hard to understand and verify at a glance. Keep the header (init, condition, update) for counter control only and the body for the work.
Rule 14.3Required · Undecidable · RulePDF example
제어 표현식이 항상 참/거짓으로 불변(invariant)이면 안 된다Controlling expressions shall not be invariant
❌ 위반 예시Non-compliant example
s8a = ( u16a < 0u ) ? 0 : 1; /* Non-compliant - u16a always >= 0 */
/* Non-compliant - always true */
/* Non-compliant - always false */
/* Non-compliant - always true */
/* Non-compliant - always false */
/* Non-compliant - always true */
/* Non-compliant - s8a not volatile */✅ 준수 예시Compliant example
/* Compliant by exception 1 */ /* Compliant by exception 2 */
⚠️ 항상 참이거나 항상 거짓으로 평가되는 제어식(부호 없는 값의 >= 0 등)은 의도한 비교를 잘못 작성했다는 신호이며, 죽은 분기나 의도치 않은 무한 실행을 만든다. 조건이 실제로 양쪽으로 분기되도록 비교를 바로잡는다.A controlling expression that always evaluates true or false (such as unsigned >= 0) signals a mis-written comparison and creates a dead branch or unintended always-execution. Fix the comparison so the condition genuinely branches both ways.
Rule 14.4Required · Decidable · RulePDF example
if/while 의 제어 표현식은 본질적으로 불리언이어야 한다The controlling expression of an if statement or iteration statement shall have essentially Boolean type
❌ 위반 예시Non-compliant example
while ( p ) /* Non-compliant - p is a pointer */ if ( i ) /* Non-compliant */
✅ 준수 예시Compliant example
whil e ( q != NULL ) /* Compliant */ while ( true ) /* Compliant */ while ( flag ) /* Compliant */ if ( i != 0 ) /* Compliant */
⚠️ 포인터나 정수를 그대로 조건에 쓰면 "0 이 아님" 이라는 비교가 암묵화되어 의도가 모호해지고, 비교 대상을 잘못 가정하는 결함을 부른다. p != NULL, n != 0 처럼 명시적 비교로 본질적 불리언 표현식을 만든다.Using a pointer or integer directly as a condition hides the implicit "not zero" comparison, obscuring intent and inviting wrong assumptions about what is tested. Build an essentially Boolean expression with explicit comparisons such as p != NULL or n != 0.
R15제어 흐름Control flow
Rule 15.1Advisory · Decidable · Rule✓ compilablePDF rule
goto 문을 사용하지 않는다The goto statement should not be used
❌ 위반 예시Non-compliant example
#include <stdio.h>
static int work(void){ return 0; }
static void cleanup(void){ printf("cleanup\n"); }
int main(void){
int err = 0;
if (err) { goto fail; } /* 비선형 제어 흐름 — 분석·검증 곤란 */
(void)work();
fail:
cleanup();
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
static int work(void){ return 0; }
static void cleanup(void){ printf("cleanup\n"); }
int main(void){
int err = 0;
if (!err) { /* 구조적 제어문으로 같은 의도를 표현 */
(void)work();
}
cleanup();
return 0;
}⚠️ goto 는 제어 흐름을 비선형으로 만들어 어디서 어디로 점프하는지 추적·검증을 어렵게 하고, 자원 해제·초기화 순서를 무너뜨리기 쉽다. if/while 같은 구조적 제어문이나 함수 분리로 같은 의도를 표현한다.goto makes control flow nonlinear, making it hard to trace and verify where execution jumps and easy to break resource-release or initialization order. Express the same intent with structured control statements (if/while) or by factoring into functions.
Rule 15.2Required · Decidable · RulePDF example
The goto statement shall jump to a label declared later in the same functionThe goto statement shall jump to a label declared later in the same function
❌ 위반 예시Non-compliant example
goto L1; /* Non-compliant */
✅ 준수 예시Compliant example
goto L2; /* Compliant */
⚠️ Rule 15.2 (The goto statement shall jump to a label declared later in the same function)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 15.2 (The goto statement shall jump to a label declared later in the same function) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 15.3Required · Decidable · RulePDF rule
goto가 참조하는 라벨은 같은 블록이나 goto를 감싸는 블록에 선언되어야 한다Any label referenced by a goto statement shall be declared in the same block, or in any block enclosing the goto statement
❌ 위반 예시Non-compliant example
void f(int a) {
if (a > 0) {
goto inner; /* 바깥에서 안쪽(중첩) 블록 라벨로 점프 */
}
{
inner: /* goto 를 감싸지 않는 별도 블록 */
a = 0;
}
}✅ 준수 예시Compliant example
void f(int a) {
if (a > 0) {
goto done; /* goto 를 감싸는 상위 블록의 라벨로만 점프 */
}
a = 1;
done:
(void)a;
}⚠️ 중첩 블록으로 뛰어드는 goto 는 코드 구조를 무너뜨리고 가독성을 크게 해친다. 점프 대상은 같은 블록이나 goto 를 감싸는 블록의 라벨로 제한한다.A goto jumping into a nested block destroys structure and harms readability; restrict targets to labels in the same block or a block enclosing the goto.
Rule 15.4Advisory · Decidable · RulePDF example
There should be no more than one break or goto statement used to terminate any iteration statementThere should be no more than one break or goto statement used to terminate any iteration statement
❌ 위반 예시Non-compliant example
for ( x = 0; x < LIMIT; ++x )
{
if ( BreakNow ( x ) )
{
break;
}
else if ( GotoNow ( x ) )
{
goto EXIT;
}
{
KeepGoing ( x );
}
}
while ( x != 0u )
{
x = calc_new_x ( );
if ( x == 1u )
{
break;
}
while ( y != 0u )
{
y = calc_new_y ( );
if ( y == 1u )
{
goto L1;
}
}
}✅ 준수 예시Compliant example
for ( x = 0; x < LIMIT; ++x )
{
if ( ExitNow ( x ) )
{
break;
}
for ( y = 0; y < x; ++y )
{
if ( Exit Now ( LIMIT - y ) )
{
break;
}
}
}⚠️ Rule 15.4 (There should be no more than one break or goto statement used to terminate any iteration statement)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 15.4 (There should be no more than one break or goto statement used to terminate any iteration statement) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 15.5Advisory · Decidable · RulePDF example
함수는 끝에 단일 종료점(return)을 둔다A function should have a single point of exit at the end
❌ 위반 예시Non-compliant example
bool_t f ( uint16_t n, char *p )
{
if ( n > MAX )
{
return false;
}
if ( p == NULL )
{
return false;
}
return true;
}✅ 준수 예시Compliant example
#include <stdio.h>
static int classify(int x){
int r;
if (x < 0) { r = -1; } /* 결과를 모아 마지막에 한 번 반환 */
else if (x == 0) { r = 0; }
else { r = x * 2; }
return r;
}
int main(void){ printf("%d\n", classify(5)); return 0; }⚠️ 함수 곳곳에 중간 return 이 흩어지면 모든 경로에서 자원 해제·로깅 같은 공통 후처리를 빠뜨리기 쉽고 흐름 추적이 어렵다. 결과를 변수에 모아 마지막에 한 번만 반환하면 공통 종료 처리를 한곳에서 보장할 수 있다.Scattered mid-function returns make it easy to skip common cleanup such as resource release or logging on some paths and hard to trace flow. Collecting the result in a variable and returning once at the end lets common exit handling be guaranteed in one place.
Rule 15.6Required · Decidable · RulePDF example
반복/선택문의 본문은 복합문(중괄호)으로 감싼다The body of an iteration statement or a selection statement shall be a compound statement
❌ 위반 예시Non-compliant example
while ( data_available ) process_data ( ); /* Non-compliant */ service_watchdog ( );
✅ 준수 예시Compliant example
while ( !data_available )
{
}⚠️ 중괄호 없는 단일 문 본문은 나중에 문장을 추가할 때 들여쓰기만 맞춘 채 본문 범위 밖에 놓이는 결함(예: Apple "goto fail" 버그)을 부른다. if/while/for 본문은 항상 중괄호로 감싸 범위를 코드로 고정한다.A braceless single-statement body invites the defect where a later-added statement is indented but falls outside the body (e.g., Apple’s "goto fail" bug). Always wrap if/while/for bodies in braces to fix the scope in code.
Rule 15.7Required · Decidable · RulePDF example
if-else if 사슬은 마지막에 else 로 마무리한다All if ... else if constructs shall be terminated with an else statement
❌ 위반 예시Non-compliant example
if ( flag_1 )
{
action_1 ( );
}
else if ( flag_2 )
{
action_2 ( );
}
/* Non-compliant */✅ 준수 예시Compliant example
{
; /* No action required - ; is optional */
}⚠️ else 로 닫지 않은 if-else if 사슬은 예상하지 못한 입력을 아무 처리 없이 지나쳐, 오류 상황이 조용히 무시되고 디버깅을 어렵게 한다. 마지막 else 로 나머지 모든 경우를 명시적으로 처리(또는 의도적 무시를 기록)한다.An if-else if chain not closed with else lets unexpected inputs pass with no handling, silently ignoring error cases and hampering debugging. Terminate with a final else that explicitly handles all remaining cases (or records a deliberate no-op).
R16switch 문Switch statements
Rule 16.1Required · Decidable · Rule✓ compilablePDF rule
switch 문은 잘 정의된 구문 형태를 따른다All switch statements shall be well-formed
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int s = 1;
switch (s) {
int local; /* case 밖 선언 — 초기화가 실행되지 않음 */
case 1: local = 1; printf("%d\n", local); break;
default: break;
}
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int s = 1;
switch (s) {
case 1: {
int local = 1; /* 모든 코드를 절(case) 안에, 블록으로 한정 */
printf("%d\n", local);
break;
}
default:
break;
}
return 0;
}⚠️ switch 본문에서 case/default 절 밖에 놓인 선언·문장은 실행되지 않거나 점프를 건너뛰어 초기화가 누락되는 등 모호한 동작을 만든다. 모든 코드를 절 안에 두고 지역 변수는 블록으로 감싸 구조를 정형화한다.Declarations or statements placed outside case/default clauses in a switch body are not executed or are skipped by the jump, causing missed initialization and ambiguous behaviour. Put all code inside clauses and scope locals in a block to keep the structure well-formed.
Rule 16.2Required · Decidable · RulePDF rule
switch 라벨은 가장 가까운 복합문이 switch 본문일 때만 사용해야 한다A switch label shall only be used when the most closely-enclosing compound statement is the body of a switch statement
❌ 위반 예시Non-compliant example
switch (x) {
case 1:
if (flag) {
case 2: /* if 블록 안의 case — switch 본문 최상위가 아님 */
x = 1;
}
break;
default:
break;
}✅ 준수 예시Compliant example
switch (x) {
case 1:
if (flag) { x = 1; }
break;
case 2: /* 모든 라벨이 switch 본문 최상위에 위치 */
x = 1;
break;
default:
break;
}⚠️ 표준은 case/default 라벨을 switch 본문 안 어디에나 둘 수 있게 하지만, 이는 비구조적 코드(Duff’s device 류)를 만든다. 라벨은 switch 본문 복합문의 최상위에만 두어야 한다.The Standard allows case/default labels anywhere inside the switch body, enabling unstructured code; place labels only at the outermost level of the switch body compound statement.
Rule 16.3Required · Decidable · RulePDF example
switch 의 각 절은 무조건 break(또는 종료)로 끝낸다An unconditional break statement shall terminate every switch-clause
❌ 위반 예시Non-compliant example
a = b; /* Non-compliant - break omitted */
✅ 준수 예시Compliant example
break; /* Compliant - unconditional break */ case 1: /* Compliant - empty fall through allows a group */
⚠️ break 누락으로 인한 fall-through 는 의도치 않게 다음 절까지 실행되어, 한 명령이 두 동작을 수행하는 흔하고 찾기 어려운 버그를 만든다. 각 switch 절을 break/return 으로 명확히 종료하고, 의도적 fall-through 는 주석으로 표시한다.A missing break causes fall-through that unintentionally runs into the next clause, producing a common and elusive bug where one command performs two actions. Terminate every switch clause explicitly with break/return and mark intentional fall-through with a comment.
Rule 16.4Required · Decidable · RulePDF example
모든 switch 문은 default 절을 가진다Every switch statement shall have a default label
❌ 위반 예시Non-compliant example
break;
/* Non-compliant - default label is required */
}
int16_t x;
switch ( x )
{✅ 준수 예시Compliant example
break;
default: /* Compliant - default label is present */
errorflag = 1; /* should be non-empty if possible */
break;
}
enum Colours
{ RED, GREEN, BLUE } colour;
switch ( colour )
{⚠️ default 절이 없는 switch 는 case 에 없는 값(손상된 상태·미래 확장값)을 아무 처리 없이 지나쳐 오류를 숨긴다. 모든 switch 에 default 를 두어 정의되지 않은 입력을 반드시 감지·처리한다.A switch without a default clause passes over values not covered by any case (corrupt states, future values) with no handling, hiding errors. Give every switch a default so undefined inputs are always detected and handled.
Rule 16.5Required · Decidable · RulePDF example
default 레이블은 switch 본문의 처음 또는 마지막에 둔다A default label shall appear as either the first or the last switch label
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int x = 2;
switch (x) {
case 1: printf("one\n"); break;
default: printf("other\n"); break; /* 절들 사이에 위치 — 가독성 저하 */
case 2: printf("two\n"); break;
}
return 0;
}✅ 준수 예시Compliant example
switch ( x )
{
default: /* Compliant - default is the first label */⚠️ default 레이블이 case 절들 사이에 끼면 코드를 읽을 때 분기 구조를 한눈에 파악하기 어렵고 fall-through 의도를 오해하기 쉽다. default 를 본문의 처음 또는 마지막에 일관되게 배치해 가독성을 높인다.A default label wedged between case clauses makes the branch structure hard to grasp at a glance and easy to misread for fall-through intent. Place default consistently at the first or last position of the body for readability.
Rule 16.6Required · Decidable · RulePDF example
switch 문은 두 개 이상의 절을 가진다Every switch statement shall have at least two switch-clauses
❌ 위반 예시Non-compliant example
switch ( x )
{
default: /* Non-compliant - switch is redundant */
x = 0;
break;
}
switch ( y )
{✅ 준수 예시Compliant example
z = 2;
break;
default: /* Compliant */
z = 0;
break;
}⚠️ 절이 하나뿐인 switch 는 단일 분기를 표현하는 데 if 로 충분한 일을 과한 구문으로 부풀려 가독성을 떨어뜨린다. 분기가 둘 이상일 때만 switch 를 쓰고, 단일 분기는 if 로 표현한다.A switch with only one clause inflates a single branch — which an if expresses adequately — into an over-heavy construct, hurting readability. Use switch only when there are two or more branches and express a single branch with if.
Rule 16.7Required · Decidable · RulePDF example
switch 의 제어 표현식은 본질적 불리언 타입이 아니어야 한다A switch-expression shall not have essentially Boolean type
❌ 위반 예시Non-compliant example
switch ( x == 0 ) /* Non-compliant - essentially Boolean */
{ /* In this case an "if-else" would be more logical */✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdbool.h>
static bool check(void){ return true; }
int main(void){
bool ok = check();
if (ok) { /* 불리언 분기는 if-else 로 */
printf("ok\n");
} else {
printf("ng\n");
}
return 0;
}⚠️ 값이 참/거짓 둘뿐인 불리언에 switch 를 쓰면 case true/false 같은 부자연스러운 구조가 되어 가독성이 낮고 의도가 흐려진다. 불리언 분기는 if-else 로 표현하고 switch 는 다중 값 분기에만 쓴다.Using switch on a Boolean — which has only true/false — produces awkward case true/false structures that read poorly and obscure intent. Express Boolean branching with if-else and reserve switch for multi-value dispatch.
R17함수Functions
Rule 17.1Required · Decidable · RulePDF example
<stdarg.h> 의 가변인자 기능을 사용하지 않는다The features of <stdarg.h> shall not be used
❌ 위반 예시Non-compliant example
#include <stdarg.h>
void h ( va_list ap ) /* Non-compliant */
{
double y;
y = va_arg ( ap, double ); /* Non-compliant */
}
void f ( uint16_t n, ... )
{
uint32_t x;
va_list ap; /* Non-compliant */
va_start ( ap, n ); /* Non-compliant */
x = va_arg ( ap, uint32_t ); /* Non-compliant */
h ( ap );
/* undefined - ap is indeterminate because va_arg used in h ( ) */
x = va_arg ( ap, uint32_t ); /* Non-compliant */
/* undefined - returns without using va_end ( ) */
}
void g ( void )
{
/* undefined - uint32_t:double type mismatch when f uses va_arg ( ) */
f ( 1, 2.0, 3.0 );
}✅ 준수 예시Compliant example
#include <stdio.h>
static int sum(const int *a, int n){ /* 명시적 배열 + 개수 — 타입 안전 */
int s = 0;
for (int i = 0; i < n; i++) { s += a[i]; }
return s;
}
int main(void){
int a[3] = {1, 2, 3};
printf("%d\n", sum(a, 3));
return 0;
}⚠️ va_arg 가변인자는 전달된 인자의 타입·개수를 컴파일러가 검사하지 못해, 기대와 다른 타입을 추출하면 진단 없는 미정의 동작이 된다. 배열과 길이를 함께 넘기는 타입 안전한 인터페이스로 대체한다.va_arg variadic arguments are not type- or count-checked by the compiler, so extracting a type that differs from what was passed is undiagnosed undefined behaviour. Replace them with a type-safe interface that passes an array together with its length.
Rule 17.2Required · Undecidable · Rule✓ compilablePDF rule
함수는 직접 또는 간접 재귀를 사용하지 않는다Functions shall not call themselves, either directly or indirectly
❌ 위반 예시Non-compliant example
#include <stdio.h>
static unsigned fact(unsigned n){
return (n <= 1u) ? 1u : n * fact(n - 1u); /* 재귀 — 최대 스택 사용량 불확정 */
}
int main(void){ printf("%u\n", fact(5u)); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
static unsigned fact(unsigned n){
unsigned r = 1u;
for (unsigned i = 2u; i <= n; i++) { r *= i; } /* 반복 — 스택 사용 결정적 */
return r;
}
int main(void){ printf("%u\n", fact(5u)); return 0; }⚠️ 재귀는 입력에 따라 호출 깊이가 달라져 최대 스택 사용량을 정적으로 보장하기 어렵고, 안전필수 시스템에서 깊은 재귀가 스택 오버플로우로 이어진다. 동일 로직을 반복문으로 변환해 스택 사용을 결정적으로 만든다.Recursion makes call depth depend on input, so the maximum stack usage cannot be statically guaranteed, and deep recursion in safety-critical systems leads to stack overflow. Convert the same logic into a loop to make stack usage deterministic.
Rule 17.3Mandatory · Decidable · RulePDF example
함수는 암시적 선언 없이 호출해야 한다A function shall not be declared implicitly
❌ 위반 예시Non-compliant example
void func ( void )
{
/* Non-compliant - return type and both argument type s incorrect */
double sq1 = power ( 1, 2.0 );
}✅ 준수 예시Compliant example
#include <stdio.h>
static int compute(int x){ return x * 2; } /* 호출 전에 선언/정의가 보임 */
int main(void){
int r = compute(3);
printf("%d\n", r);
return 0;
}⚠️ 프로토타입 없이 함수를 호출하면 컴파일러가 인자·반환 타입을 임의로 가정해, 실제 정의와 다르면 잘못된 호출 규약으로 스택·레지스터를 오염시킨다. 호출 지점에서 항상 선언(헤더 포함)이 보이도록 한다.Calling a function without a visible prototype makes the compiler assume argument and return types, so a mismatch with the real definition corrupts the stack/registers via a wrong calling convention. Ensure a declaration (via a header) is always visible at the call site.
Rule 17.4Mandatory · Decidable · RulePDF example
비void 함수는 모든 경로에서 값을 반환해야 한다All exit paths from a function with non-void return type shall have an explicit return statement with an expression
❌ 위반 예시Non-compliant example
*/
}
uint16_t lookup ( uint16_t v )
{
if ( ( v < V_MIN ) || ( v > V_MAX ) )
{
/* Non-compliant - n o value returned. Constraint in C99 */
return;
}
return table[ v ];
}✅ 준수 예시Compliant example
#include <stdio.h>
static int classify(int x){
if (x > 0) return 1;
if (x < 0) return -1;
return 0; /* 모든 경로에서 명시적 반환 */
}
int main(void){ printf("%d\n", classify(0)); return 0; }⚠️ 반환값을 명시하지 않고 끝나는 비void 함수의 반환값은 불확정이라, 호출부가 스택·레지스터에 남은 쓰레기값을 결과로 사용하게 된다. 모든 종료 경로에서 명시적 return 문으로 값을 반환한다.A non-void function that ends without an explicit return has an indeterminate return value, so the caller uses leftover garbage from the stack/registers as the result. Return a value with an explicit return statement on every exit path.
Rule 17.5Advisory · Undecidable · RulePDF rule
배열 타입 매개변수에 대응하는 인자는 적절한 원소 수를 가져야 한다The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements
❌ 위반 예시Non-compliant example
/* 매개변수가 최소 4개 원소 배열을 기대한다고 선언 */
void sum4(int a[4]);
void caller(void) {
int two[2] = { 1, 2 };
sum4(two); /* 원소 2개뿐 — 범위 밖 접근 위험 */
}✅ 준수 예시Compliant example
void sum4(int a[4]);
void caller(void) {
int four[4] = { 1, 2, 3, 4 };
sum4(four); /* 선언된 최소 원소 수를 충족 */
}⚠️ 크기를 명시한 배열 매개변수는 함수가 기대하는 최소 원소 수를 인터페이스로 드러낸다. 그보다 작은 배열을 넘기면 범위 밖 접근 위험이 생긴다.A sized array parameter documents the minimum number of elements the function expects; passing a smaller array risks out-of-bounds access.
Rule 17.6Mandatory · Decidable · RulePDF example
배열 매개변수 선언에 static 키워드를 쓰지 않는다The declaration of an array parameter shall not contain the static keyword between the [ ]
❌ 위반 예시Non-compliant example
/* Non-compliant - uses static in array declarator */
uint16_t total ( uint16_t n, uint16_t a[ static 20 ] )
{
uint16_t i;
uint16_t sum = 0U;
/* Undefined behaviour if a has fewer than 20 elements */
for ( i = 0U; i < n; ++i )
{
sum = sum + a[ i ];
}
return sum;
}
extern uint16_t v1[ 10 ];
extern uint16_t v2[ 20 ];
void g ( void )
{
uint16_t x;
x = total ( 10U, v1 ); /* Undefined - v1 has 10 elements but needs✅ 준수 예시Compliant example
#include <stdio.h>
#include <stddef.h>
static int first(const int *a, size_t n){ /* 포인터 + 길이로 명시적 계약 */
return (n > 0u) ? a[0] : -1;
}
int main(void){
int a[10] = {7};
printf("%d\n", first(a, 10));
return 0;
}⚠️ 배열 매개변수의 [static N] 은 호출부가 최소 N개 요소를 보장한다고 약속하지만, 약속이 깨져도 컴파일러가 진단하지 못해 경계 밖 접근이 미정의 동작으로 숨는다. 포인터와 길이를 함께 전달해 길이를 실행시간에 검사 가능한 명시적 계약으로 만든다.An array parameter’s [static N] promises the caller provides at least N elements, but a broken promise goes undiagnosed and hides out-of-bounds access as undefined behaviour. Pass a pointer with a length to make the length an explicit, run-time-checkable contract.
Rule 17.7Required · Decidable · RulePDF example
비void 함수의 반환값은 사용한다The value returned by a function having non-void return type shall be used
❌ 위반 예시Non-compliant example
func ( para2 ); /* Non-compliant - value discarded */
✅ 준수 예시Compliant example
( void ) func ( para2 ); /* Compliant */ x = func ( para2 ); /* Compliant */
⚠️ 의미 있는 반환값(오류 코드·필요 길이·실제 처리량)을 무시하면 실패나 절단을 감지하지 못한 채 잘못된 데이터로 진행한다. 반환값을 검사해 분기하고, 정말 불필요할 때만 (void) 캐스트로 의도를 명시한다.Ignoring a meaningful return value (error code, required length, bytes processed) lets execution continue with bad data without detecting failure or truncation. Test the return value and branch on it, casting to (void) only when it is genuinely unneeded to signal intent.
Rule 17.8Advisory · Decidable · RulePDF example
함수 매개변수를 함수 안에서 수정하지 않는다A function parameter should not be modified
❌ 위반 예시Non-compliant example
para = glob; /* Non-compliant */ p = q; /* Non-compliant */
✅ 준수 예시Compliant example
*p = *q; /* Compliant */
⚠️ 매개변수를 함수 안에서 수정하면, 디버깅·로깅 시 "이 함수가 받은 원래 인자값" 과 현재 값의 대응이 흐려져 추적이 어려워진다. 매개변수는 입력으로만 읽고, 변경이 필요하면 지역 복사본을 두어 원래 입력을 보존한다.Modifying a parameter inside a function blurs the correspondence between the original argument the function received and its current value, complicating debugging and logging. Read parameters as inputs only and use a local copy when modification is needed so the original input is preserved.
R18포인터·배열Pointers & arrays
Rule 18.1Required · Undecidable · RulePDF example
포인터 산술 결과는 같은 배열의 범위 안을 가리켜야 한다A pointer resulting from arithmetic on a pointer operand shall address an element of the same array
❌ 위반 예시Non-compliant example
int32_t *p = &a1[ 3 ]; /* Compliant/non-compliant depending on int32_t *p3 = &c[ 11 ]; /* Non-compliant - undefined, points to data = *p2; /* Non-compliant - undefined, dereference c[ -1 ] = 0; /* Non-compliant - undefined, array data = c[ 10 ]; /* Non-compliant - undefined, dereference data = d[ 2 ][ 3 ]; /* Non-compliant - undefined, internal p[ 0 ] = 1; /* Non-compliant - undefined, dereference of address one p[ 1 ] = 2; /* Non-compliant - undefined */ p = p + 3; /* Non-compliant - undefined, p points more than one
✅ 준수 예시Compliant example
return *( a2 + 9 ); /* Compliant */ int32_t *p1 = &c[ 0 ]; /* Compliant */ int32_t *p2 = &c[ 10 ]; /* Compliant - points to one beyond */ p1++; /* Compliant */ data = *( &data + 0 ); /* Compliant - C treats data as an d[ 3 ][ 1 ] = 0; /* Compliant */ data = *( *( d + 3 ) + 1 ); /* Compliant */ p1 = d[ 1 ]; /* Compliant */ data = p1[ 1 ]; /* Compliant - p1 addresses an array ++p; /* Compliant - p points one beyond s.x */ p = &s.a[ 0 ]; /* Compliant - p points into s.a */ p = p + 8; /* Compliant - p still points into s.a */
⚠️ 배열 경계를 벗어난 포인터를 만들어 역참조하면 인접 메모리를 침범하는 미정의 동작이 되어, 데이터 손상이나 보안 결함으로 이어진다. 인덱스를 사용 전에 [0, 길이) 범위로 검증해 항상 같은 배열 안을 가리키는 포인터만 생성한다.Forming and dereferencing a pointer past an array’s bounds is undefined behaviour that intrudes on adjacent memory, leading to corruption or security defects. Validate the index against [0, length) before use so only pointers within the same array are created.
Rule 18.2Required · Undecidable · RulePDF example
포인터 뺄셈은 같은 배열의 원소들 사이에서만 한다Subtraction between pointers shall only be applied to pointers that address elements of the same array
❌ 위반 예시Non-compliant example
diff = p1 - p2; /* Non-compliant */ diff = ptr - p1; /* Non-compliant */
✅ 준수 예시Compliant example
diff = p1 - a1; /* Compliant */ diff = p2 - a2; /* Compliant */
⚠️ 서로 다른 객체의 주소 차이는 표준이 정의하지 않으므로(같은 배열의 원소가 아니므로) 결과가 미정의가 되어 이식·최적화 시 의미 없는 값이 나온다. 포인터 뺄셈은 동일 배열의 원소들 사이에서만 수행한다.The difference between addresses of distinct objects is undefined (they are not elements of one array), yielding meaningless values across ports and optimizations. Perform pointer subtraction only between elements of the same array.
Rule 18.3Required · Undecidable · RulePDF example
관계 연산(<,>)은 같은 객체를 가리키는 포인터끼리만 한다The relational operators >, >=, < and <= shall not be applied to pointers to different objects
❌ 위반 예시Non-compliant example
if ( p1 < a2 ) /* Non-compliant */ if ( &limits_1.lwb > &limits_2.upb ) /* Non-Compliant */
✅ 준수 예시Compliant example
if ( p1 < a1 ) /* Compliant */ if ( &limits_1.lwb <= &limits_1.upb ) /* Compliant */
⚠️ 서로 다른 객체를 가리키는 포인터의 대소 비교 결과는 표준이 보장하지 않아 미정의이며, 메모리 배치 가정에 의존한 코드는 플랫폼마다 다르게 동작한다. 같은 배열 내 포인터끼리 비교하거나 인덱스로 비교한다.Relational comparison of pointers to different objects is undefined, so code relying on memory-layout assumptions behaves differently across platforms. Compare pointers within the same array, or compare indices instead.
Rule 18.4Advisory · Decidable · RulePDF example
포인터에 +, -, +=, -= 산술을 적용하지 않는다(배열 첨자 사용)The +, -, += and -= operators should not be applied to an expression of pointer type
❌ 위반 예시Non-compliant example
*( ptr + 5 ) = 0U; /* Non-compliant */ p1 = p1 + 5; /* Non-compliant */ p2 = p2 + 3; /* Non-compliant */
✅ 준수 예시Compliant example
index = index + 1U; /* Compliant - rule only applies to pointers */
a[ index ] = 0U; /* Compliant */
ptr = &a[ 5 ]; /* Compliant */
ptr++; /* Compliant - increment operator not + */
ptr[ 5 ] = 0U; /* Compliant */
sum += row[ j ]; /* Compliant */
p1++; /* Compliant */
p1[ 5 ] = 0U; /* Compliant */
p2++; /* Compliant */
p2[ 3 ] = 0U; /* Compliant */⚠️ p + n 같은 포인터 산술은 어느 배열의 몇 번째인지 한눈에 드러나지 않아 경계 오류를 숨기고 정적 분석을 어렵게 한다. 동일한 접근을 배열 첨자 p[n] 표기로 쓰면 의도가 명확해지고 도구의 경계 검사도 쉬워진다.Pointer arithmetic like p + n does not make clear which array element is meant, hiding bounds errors and hampering static analysis. Writing the same access with subscript notation p[n] clarifies intent and eases tool-based bounds checking.
Rule 18.5Advisory · Decidable · RulePDF example
포인터의 중첩 수준은 2단계를 넘지 않는다Declarations should contain no more than two levels of pointer nesting
❌ 위반 예시Non-compliant example
void function ( int8_t ** arrPar[ ] ) /* Non-compliant */ int8_t *** obj3; /* Non-compliant */ INTPTR * const * const obj5; /* Non-compliant */ int8_t *** s3; /* Non-compliant */ struct s *** ps3; /* Non-compliant */ int8_t ** ( ***pfunc3 )( void ); /* Non-compliant */ int8_t *** ( **pfunc4 )( void ); /* Non-compliant */ and is non-compliant;
✅ 준수 예시Compliant example
int8_t ** obj2; /* Compliant */ INTPTR * obj4; /* Compliant */ int8_t ** arr[ 10 ]; /* Compliant */ int8_t ** ( *parr )[ 10 ]; /* Compliant */ int8_t * ( **pparr )[ 10 ]; /* Compliant */ int8_t * s1; /* Compliant */ int8_t ** s2; /* Compliant */ struct s * ps1; /* Compliant */ struct s ** ps2; /* Compliant */ int8_t ** ( *pfunc1 )( void ); /* Compliant */ int8_t ** ( **pfunc2 )( void ); /* Compliant */
⚠️ 3단계 이상의 포인터 중첩(int***)은 각 단계가 무엇을 가리키는지 추적하기 어려워 오용과 검증 실패를 부른다. 간접 단계를 구조체로 캡슐화해 의미를 부여하면 중첩을 2단계 이하로 낮출 수 있다.Three or more levels of pointer nesting (int***) make it hard to track what each level points to, inviting misuse and verification failure. Encapsulating indirection in a struct gives it meaning and reduces nesting to two levels or fewer.
Rule 18.6Required · Undecidable · RulePDF example
자동 저장기간 객체의 주소를 그 수명 밖으로 내보내지 않는다The address of an object with automatic storage shall not be copied to another object that persists after the first object has ceased to exist
❌ 위반 예시Non-compliant example
int8_t *func ( void )
{
int8_t local_auto;
return &local_auto; /* Non-compliant - &local_ auto is indeterminate✅ 준수 예시Compliant example
#include <stdio.h>
static void make(int *out){
*out = 42; /* 호출자가 소유한 저장소에 기록 */
}
int main(void){
int value;
make(&value); /* 수명이 보장된 객체를 전달 */
printf("%d\n", value);
return 0;
}⚠️ 지역 변수는 함수가 반환되면 수명이 끝나 그 주소가 무효가 되므로, 주소를 반환·보관해 역참조하면 사라진 스택 프레임을 가리키는 미정의 동작이 된다. 결과는 호출자가 소유한 저장소나 정적 저장기간 객체에 기록한다.A local variable’s lifetime ends when the function returns, so its address becomes invalid; returning or retaining it and dereferencing it points at a vanished stack frame — undefined behaviour. Write results into caller-owned storage or an object with static storage duration.
Rule 18.7Required · Decidable · RulePDF example
유연 배열 멤버(flexible array member)를 선언하지 않는다Flexible array members shall not be declared
❌ 위반 예시Non-compliant example
#include <stdlib.h>
struct s
{
uint16_t len;
uint32_t data[ ]; /* Non-compliant - flexible array member */
} str;
struct s *copy ( struct s *s1 )
{
struct s *s2;
/* Omit malloc ( ) return check for brevity */
s2 = malloc ( sizeof ( struct s ) + ( s1->len * sizeof ( uint32_t ) ) );
*s2 = *s1; /* Only copies s1->len */
return s2;
}✅ 준수 예시Compliant example
#include <stdio.h>
#define MAX_DATA 256
struct Packet { int len; char data[MAX_DATA]; }; /* 최대 크기 고정 배열 */
int main(void){
struct Packet p = { 0, {0} };
printf("%zu\n", sizeof p); /* 크기가 정적으로 결정 — 경계 검사 가능 */
return 0;
}⚠️ 유연 배열 멤버는 실제 크기가 런타임 할당에 따라 정해져 sizeof 로 알 수 없으므로, 정적 경계 검사와 메모리 사용량 분석을 어렵게 한다. 최대 크기를 갖는 고정 배열로 대체하면 크기가 컴파일 시 결정되어 검증이 쉬워진다.A flexible array member’s actual size is set by run-time allocation and is unknown via sizeof, hampering static bounds checking and memory-usage analysis. Replacing it with a fixed array of maximum size makes the size compile-time determined and easy to verify.
Rule 18.8Required · Decidable · RulePDF example
가변 길이 배열(VLA)을 사용하지 않는다Variable-length array types shall not be used
❌ 위반 예시Non-compliant example
void f ( int16_t n )
{
uint16_t vla[ n ]; /* Non-compliant - Undefined if n <= 0 */
}
void g ( void )
{
f ( 0 ); /* Undefined */
f ( -1 ); /* Undefined */
f ( 10 ); /* Defined */
}✅ 준수 예시Compliant example
#include <stdio.h>
#define MAX_N 128
static int sum_first(int n){
int buf[MAX_N]; /* 컴파일 시 고정 크기 — 스택 사용량 결정적 */
if (n > MAX_N) { return -1; }
int s = 0;
for (int i = 0; i < n; i++) { buf[i] = i; s += buf[i]; }
return s;
}
int main(void){ printf("%d\n", sum_first(5)); return 0; }⚠️ 가변 길이 배열은 크기가 런타임 값에 의존해 최대 스택 사용량을 정적으로 알 수 없으므로, 큰 입력에서 스택 오버플로우 위험이 있다. 컴파일 시 크기가 고정된 배열을 쓰고 입력을 그 한계와 비교해 결정적인 메모리 사용을 보장한다.A variable-length array’s size depends on a run-time value, so maximum stack usage cannot be known statically, risking stack overflow on large inputs. Use a compile-time fixed-size array and compare the input against its limit to guarantee deterministic memory use.
R19중첩 저장Overlapping storage
Rule 19.1Mandato · Undecidable · RulePDF example
An object shall not b e assigned or copied to an overlapping objectAn object shall not b e assigned or copied to an overlapping object
❌ 위반 예시Non-compliant example
a.j = a.i; /* Non-compliant */ memcpy ( &a[ 5 ], &a[ 4 ], 2u * sizeof ( a[ 0 ] ) ); /* Non-compliant */
✅ 준수 예시Compliant example
a = b; /* Compliant - exception 1 */ *p = *q; /* Compliant - exception 1 */
⚠️ Rule 19.1 (An object shall not b e assigned or copied to an overlapping object)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.1 (An object shall not b e assigned or copied to an overlapping object) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.2Advisory · Decidable · RulePDF example
union 키워드 사용을 피한다The union keyword should not be used
❌ 위반 예시Non-compliant example
{
uint32_t ul;
uint16_t us;
} tmp;
tmp.us = s;
return tmp.ul;✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main(void){
uint32_t u = 0x40490FDBu;
float pi;
memcpy(&pi, &u, sizeof pi); /* 명시적 바이트 재해석 — 의도가 분명 */
printf("%f\n", pi);
return 0;
}⚠️ union 의 한 멤버에 쓴 뒤 다른 멤버를 읽는 타입 퍼닝은 표현이 다른 타입을 재해석하는 것이라 구현정의 동작이 되고, 코드만으로 의도를 파악하기 어렵다. memcpy 로 바이트 단위 재해석을 명시하면 동작이 정의되고 의도가 드러난다.Writing one union member and reading another (type punning) reinterprets a differently represented type, which is implementation-defined and whose intent is unclear from the code. Using memcpy to spell out the byte-wise reinterpretation makes the behaviour defined and the intent explicit.
R20전처리 지시문Preprocessing directives
Rule 20.1Advisory · Decidable · RulePDF example
#include 지시문 앞에는 전처리기 지시문/주석만 둔다#include directives should only be preceded by preprocessor directives or comments
❌ 위반 예시Non-compliant example
#include "f.h" /* Non-compliant */ #include "f3.h" /* Non-compliant */
✅ 준수 예시Compliant example
#include "f1.h" /* Compliant */ #include "f2.h" /* Compliant */
⚠️ 코드 중간에 등장하는 #include 는 그 위치까지의 선언·매크로 상태에 따라 포함 결과가 달라지는 순서 의존 결함을 만들고, 의존 관계를 한눈에 파악하기 어렵게 한다. 모든 #include 를 파일 상단에 모아 포함 순서를 단순하고 예측 가능하게 한다.An #include in the middle of code creates order-dependent defects, since what it pulls in can depend on the declarations and macros seen so far, and it obscures dependencies. Collecting all #includes at the top of the file makes inclusion order simple and predictable.
Rule 20.2Required · Decidable · RulePDF example
The ', " or \ characters and the /* or // character sequences shall not occur in a header file nameThe ', " or \ characters and the /* or // character sequences shall not occur in a header file name
❌ 위반 예시Non-compliant example
#include "fi'le.h" /* Non-compliant */
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 20.2 (The ', " or \ characters and the /* or // character sequences shall not occur in a header file name)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 20.2 (The ', " or \ characters and the /* or // character sequences shall not occur in a header file name) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 20.3Required · Decidable · RulePDF example
#include 뒤에는 <헤더> 또는 "헤더" 형태만 온다The #include directive shall be followed by either a <filename> or "filename" sequence
❌ 위반 예시Non-compliant example
#include another.h /* Non-compliant */ #include FILENAME /* Non-compliant */ #include BASE EXT /* Non-compliant - strings are concatenated
✅ 준수 예시Compliant example
#include "filename.h" /* Compliant */ #include <filename.h> /* Compliant */ #include HEADER /* Compliant */ #include "./include/cpu.h" /* Compliant - filename may include a path */
⚠️ 매크로 확장으로 헤더명을 생성하면 확장 결과가 올바른 <...> 또는 "..." 형식이 된다는 보장이 없어, 컴파일러·이식 환경마다 다르게 해석되는 위험이 있다. #include 에는 헤더명을 직접 적어 형식을 고정한다.Generating a header name via macro expansion does not guarantee the result is a valid <...> or "..." form, risking different interpretations across compilers and ports. Write the header name directly in #include to fix the form.
Rule 20.4Required · Decidable · RulePDF example
키워드와 같은 이름의 매크로를 정의하지 않는다A macro shall not be defined with the same name as a keyword
❌ 위반 예시Non-compliant example
#define while( E ) for ( ; ( E ) ; ) /* Non-compliant - redefined while */
✅ 준수 예시Compliant example
#define unless( E ) if ( ! ( E ) ) /* Compliant */
S1; S2; } while ( false ) /* Compliant */
#define compound( S ) { S; } /* Compliant */
/* Remove inline if compiling for C90 */
#define inline⚠️ 키워드를 매크로로 재정의하면 그 키워드를 쓰는 모든 코드의 의미가 조용히 바뀌어(while 이 if 가 되는 등) 추적 불가능한 전역 혼란을 일으킨다. 키워드 이름의 매크로 정의를 금지하고, 별칭이 필요하면 typedef 등 정상 수단을 쓴다.Redefining a keyword as a macro silently changes the meaning of all code using that keyword (e.g., while becomes if), causing untraceable global chaos. Never define a macro with a keyword name; use proper means such as typedef when an alias is needed.
Rule 20.5Advisory · Decidable · RulePDF example
#undef 를 사용하지 않는다#undef should not be used
❌ 위반 예시Non-compliant example
#define QUALIFIER volatile
#undef QUALIFIER /* Non-compliant */
void f ( QUALIFIER int32_t p )
{
while ( p != 0 )
{
; /* Wait... */
}
}✅ 준수 예시Compliant example
#include <stdio.h>
#define LIMIT_LOW 100 /* 서로 다른 값은 서로 다른 이름으로 */
#define LIMIT_HIGH 200
int main(void){ printf("%d %d\n", LIMIT_LOW, LIMIT_HIGH); return 0; }⚠️ #undef 후 재정의는 같은 매크로 이름이 소스 위치에 따라 다른 값을 갖게 만들어, 어느 코드가 어떤 값을 보는지 추적하기 어렵고 리뷰 오류를 부른다. 서로 다른 의미·값은 서로 다른 매크로 이름으로 정의해 수명과 의미를 명확히 한다.Redefining after #undef makes the same macro name hold different values depending on source position, making it hard to trace which value a given piece of code sees and inviting review errors. Define distinct meanings/values under distinct macro names to keep lifetime and meaning clear.
Rule 20.6Required · Decidable · RulePDF example
Tokens that look like a preprocessing directive shall not occur within a macro argumentTokens that look like a preprocessing directive shall not occur within a macro argument
❌ 위반 예시Non-compliant example
#ifdef SW /* Non-compliant */
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 20.6 (Tokens that look like a preprocessing directive shall not occur within a macro argument)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 20.6 (Tokens that look like a preprocessing directive shall not occur within a macro argument) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 20.7Required · Decidable · RulePDF example
함수형 매크로의 매개변수는 괄호로 감싼다Expressions resulting from the expansion of macro parameters shall be enclosed in parentheses
❌ 위반 예시Non-compliant example
#include <stdio.h>
#define SCALE(x) x * 2 /* 매개변수·전체 식을 괄호로 감싸지 않음 */
int main(void){
int a = 1, b = 2;
int r = SCALE(a + b); /* a + b * 2 = 5 로 전개됨 (의도는 6) */
printf("%d\n", r);
return 0;
}✅ 준수 예시Compliant example
#define M1( x, y ) ( x * y ) r = M1 ( 1 + 2, 3 + 4 ); r = ( 1 + 2 * 3 + 4 ); r = M1 ( ( 1 + 2 ), ( 3 + 4 ) ); /* Compliant */ #define M2( x, y ) ( ( x ) * ( y ) ) r = M2 ( 1 + 2, 3 + 4 ); /* Compliant */ #define M3( x ) a ## x = ( x ) int16_t M3 ( 0 ); #define GET_MEMBER( S, M ) ( S ).M v = GET_MEMBER ( s1, minval );
⚠️ 함수형 매크로에서 매개변수와 전체 식을 괄호로 감싸지 않으면, 전개 시 호출부 표현식과 매크로 본문의 연산자 우선순위가 섞여 SCALE(a+b) 가 a + b*2 처럼 의도와 다른 식이 된다. 각 매개변수와 결과 전체를 괄호로 보호한다.Without parenthesizing the parameters and the whole expression in a function-like macro, expansion mixes the caller’s expression with the macro body’s operator precedence, turning SCALE(a+b) into a + b*2. Protect each parameter and the entire result with parentheses.
Rule 20.8Required · Decidable · RulePDF example
#if/#elif 의 제어 표현식은 0 또는 1로 평가되어야 한다The controlling expression of a #if or #elif preprocessing directive shall evaluate to 0 or 1
❌ 위반 예시Non-compliant example
#if 10 /* Non-compliant */
✅ 준수 예시Compliant example
#if FALSE /* Compliant */ #if ! defined ( X ) /* Compliant */ #if A > B /* Compliant assuming A and B are numeric */
⚠️ 정의되지 않았거나 불리언이 아닌 매크로를 #if 에 직접 쓰면 전처리기가 그 토큰을 0 으로 치환하거나 임의 정수로 해석해, 의도하지 않은 분기가 선택된다. defined() 로 존재를 확인하고 명시적 비교로 결과를 0/1 로 보장한다.Using an undefined or non-Boolean macro directly in #if makes the preprocessor substitute 0 or interpret an arbitrary integer, selecting an unintended branch. Confirm existence with defined() and use explicit comparison to guarantee a 0/1 result.
Rule 20.9Required · Decidable · RulePDF example
#if/#elif 에 쓰는 식별자는 정의 여부를 defined 로 먼저 확인한다All identifiers used in the controlling expression of #if or #elif shall be defined before evaluation
❌ 위반 예시Non-compliant example
#if M == 0 /* Non-compliant */
✅ 준수 예시Compliant example
#if defined ( M ) /* Compliant - M is not evaluated */ #if M == 0 /* Compliant - M is known to be defined */ /* Compliant - B is only evaluated in ( B == 0 ) if it is defined */
⚠️ 정의되지 않은 식별자는 #if 평가 시 0 으로 치환되므로, MODE 가 없을 때 MODE == 2 가 조용히 거짓이 되어 의도와 다른 분기가 선택되고 오타·구성 누락을 숨긴다. defined() 로 존재를 먼저 확인한 뒤 값을 비교한다.An undefined identifier is replaced by 0 during #if evaluation, so when MODE is absent, MODE == 2 silently becomes false, selecting the wrong branch and hiding typos or missing configuration. Confirm existence with defined() before comparing the value.
Rule 20.10Advisory · Decidable · Rule✓ compilablePDF rule
전처리기 연산자 # 와 ## 사용을 피한다The # and ## preprocessor operators should not be used
❌ 위반 예시Non-compliant example
#include <stdio.h>
#define MAKE(name) int var_##name = 0 /* ## 토큰 결합 — 디버깅·검색이 어려움 */
int main(void){
MAKE(abc);
return var_abc;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int var_abc = 0; /* 명시적 선언 — 도구로 검색·디버깅이 쉬움 */
return var_abc;
}⚠️ #(문자열화)와 ##(토큰 결합)은 전처리 후에야 실제 식별자가 만들어져, 소스에서 그 이름을 검색·디버깅하기 어렵고 평가 순서도 까다로워 미묘한 버그를 숨긴다. 가능하면 명시적 코드로 대체해 추적성을 확보한다.# (stringize) and ## (token paste) form the real identifier only after preprocessing, making the name hard to search and debug and their evaluation order tricky, hiding subtle bugs. Replace them with explicit code where possible for traceability.
Rule 20.11Required · Decidable · RulePDF example
A macro parameter immediately following a # operator shall not immediately be followed by a ## operatorA macro parameter immediately following a # operator shall not immediately be followed by a ## operator
❌ 위반 예시Non-compliant example
#define C( x, y ) #x ## y /* Non-compliant */
✅ 준수 예시Compliant example
#define A( x ) #x /* Compliant */ #define B( x, y ) x ## y /* Compliant */
⚠️ Rule 20.11 (A macro parameter immediately following a # operator shall not immediately be followed by a ## operator)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 20.11 (A macro parameter immediately following a # operator shall not immediately be followed by a ## operator) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 20.12Required · Decidable · RulePDF example
# 또는 ## 의 피연산자가 되는 매크로 매개변수를 일관되게 사용한다A macro parameter used as an operand to the # or ## operators shall only be used as such
❌ 위반 예시Non-compliant example
#define AA 0xffff
#define BB( x ) ( x ) + wow ## x /* Non-compliant */
void f ( void )
{
int32_t wowAA = 0;
/* Expands as wowAA = ( 0xffff ) + wowAA; */
wowAA = BB ( AA );
}✅ 준수 예시Compliant example
int32_t speed; int32_t speed_scale; int32_t scaled_speed; #define SCALE( X ) ( ( X ) * X ## _scale ) /* expands to scaled_speed = ( ( speed ) * speed_scale ); */ scaled_speed = SCALE ( speed );
⚠️ 한 매크로 매개변수를 ## 의 피연산자(토큰 결합)와 일반 확장에 동시에 쓰면, 전처리기가 인자를 먼저 확장할지 결합할지에 따라 결과가 달라져 전개 결과가 모호해진다. 매개변수는 한 가지 용도로만 일관되게 사용한다.Using one macro parameter both as an operand of ## (token paste) and in ordinary expansion makes the result depend on whether the preprocessor expands or pastes the argument first, making expansion ambiguous. Use a parameter for only one purpose, consistently.
Rule 20.13Required · Decidable · RulePDF example
# 으로 시작하는 줄은 올바른 전처리기 지시문이어야 한다A line whose first token is # shall be a valid preprocessing directive
❌ 위반 예시Non-compliant example
#define AAA 2
int32_t foo ( void )
{
int32_t x = 0;
#ifndef AAA
x = 1;
#else1 /* Non-compliant */
x = AAA;
#endif
return x;
}✅ 준수 예시Compliant example
/* #start is not a token in a comment */
⚠️ # 으로 시작하지만 include/define/if 같은 표준 지시문 철자가 아닌 줄은, 일부 컴파일러가 무시하거나 확장 지시문으로 해석하는 등 미정의·비이식 동작을 만든다. # 으로 시작하는 줄은 반드시 표준 전처리기 지시문 형태를 따른다.A line starting with # that is not a standard directive spelling (include/define/if, …) is ignored by some compilers and treated as an extension directive by others — undefined, non-portable behaviour. Lines beginning with # must follow a standard preprocessing-directive form.
Rule 20.14Required · Decidable · RulePDF example
#else/#endif 는 대응하는 #if 와 같은 파일에 둔다All #else, #elif and #endif preprocessor directives shall reside in the same file as the #if to which they relate
❌ 위반 예시Non-compliant example
#if 1 /* Non-compliant */
✅ 준수 예시Compliant example
#ifdef A /* Compliant */ #if 1 /* Compliant */
⚠️ 조건부 컴파일 지시문(#if/#else/#endif)이 파일 경계를 가로질러 매칭되면, 헤더 포함 순서에 따라 어떤 #if 와 짝지어지는지 달라져 빌드 구성이 깨지기 쉽다. #if 와 그 #else/#endif 를 같은 파일 안에서 짝지어 구조를 자기완결적으로 만든다.When conditional-compilation directives (#if/#else/#endif) match across file boundaries, which #if they pair with depends on header inclusion order, easily breaking the build configuration. Pair an #if with its #else/#endif within the same file so each block is self-contained.
R21표준 라이브러리Standard libraries
Rule 21.1Required · Undecidable · Rule✓ compilablePDF rule
예약 식별자/매크로 이름을 #define 하거나 #undef 하지 않는다#define and #undef shall not be used on a reserved identifier or reserved macro name
❌ 위반 예시Non-compliant example
#include <stdio.h>
#define _MAX 100 /* 밑줄+대문자로 시작 — 구현이 예약한 이름 영역 */
int main(void){ printf("%d\n", _MAX); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
#define APP_MAX 100 /* 비예약(애플리케이션) 이름 */
int main(void){ printf("%d\n", APP_MAX); return 0; }⚠️ 밑줄로 시작하는 이름이나 표준이 예약한 매크로를 재정의·해제하면 구현 내부 헤더·매크로와 충돌해 진단 없는 미정의 동작이 된다. 애플리케이션 고유의 비예약 이름(예: APP_ 접두사)만 정의한다.Defining or undefining a leading-underscore name or a Standard-reserved macro collides with the implementation’s internal headers and macros, causing undiagnosed undefined behaviour. Define only application-specific, non-reserved names (e.g., an APP_ prefix).
Rule 21.2Required · Undecidable · RulePDF example
예약된 식별자/함수 이름을 선언하거나 정의하지 않는다A reserved identifier or reserved macro name shall not be declared
❌ 위반 예시Non-compliant example
*/ #include <stddef.h> extern void *memcpy ( void *restrict s1, const void *restrict s2, size_t n ); extern double sqrt ( double x ); #define sqrt( x ) ( _BUILTIN_sqrt ( x ) ) #define _BUILTIN_sqrt( x ) ( x ) /* Non-compliant */ #include <math.h> float64_t x = sqrt ( ( float64_t ) 2.0 ); /* sqrt may not behave as
✅ 준수 예시Compliant example
/* 고유한 사용자 이름을 사용 */
size_t copy_block(int x) {
return (size_t)x;
}⚠️ memcpy·strlen 같은 표준 라이브러리 이름이나 구현 예약 이름을 사용자가 선언·정의하면, 표준 헤더의 선언·내장 함수와 충돌해 링크 오류나 미정의 동작이 발생한다. 예약 영역과 겹치지 않는 고유한 사용자 이름을 사용한다.Declaring or defining a Standard library name like memcpy or strlen, or any reserved identifier, collides with declarations in standard headers and built-ins, causing link errors or undefined behaviour. Use unique, application-specific names that do not overlap the reserved space.
Rule 21.3Required · Undecidable · Rule✓ compilablePDF rule
<stdlib.h> 의 동적 메모리 함수(malloc/calloc/realloc/free)를 쓰지 않는다The memory allocation and deallocation functions of <stdlib.h> shall not be used
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
static int process(int *buf, int n){ int s = 0; for (int i=0;i<n;i++){ buf[i]=i; s+=buf[i]; } return s; }
int main(void){
int n = 4;
int *buf = malloc((size_t)n * sizeof(int)); /* 동적 할당 — 단편화·실패·누수·이중해제 위험 */
if (buf == NULL) { return 1; }
int s = process(buf, n);
free(buf);
printf("%d\n", s);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#define MAX_N 256
static int process(int *buf, int n){ int s = 0; for (int i=0;i<n;i++){ buf[i]=i; s+=buf[i]; } return s; }
int main(void){
int n = 4;
int buf[MAX_N]; /* 정적/자동 저장소 — 결정적 메모리 */
if (n > MAX_N) { return 1; }
printf("%d\n", process(buf, n));
return 0;
}⚠️ 동적 할당은 힙 단편화, 비결정적 할당 시간, 할당 실패, 누수·이중해제 위험을 동반해 안전필수 시스템의 장기 가동 신뢰성을 떨어뜨린다. 컴파일 시 크기가 정해지는 정적/자동 저장소로 대체해 메모리 사용을 결정적이고 검증 가능하게 만든다.Dynamic allocation brings heap fragmentation, non-deterministic allocation time, allocation failure, and leak/double-free risks that undermine long-uptime reliability in safety-critical systems. Replace it with statically/automatically sized storage to make memory use deterministic and verifiable.
Rule 21.4Required · Decidable · Rule✓ compilablePDF rule
<setjmp.h> 를 사용하지 않는다The standard header file <setjmp.h> shall not be used
❌ 위반 예시Non-compliant example
#include <setjmp.h>
#include <stdio.h>
static jmp_buf env;
static void recover(void){ printf("recovered\n"); }
int main(void){
if (setjmp(env) != 0) { recover(); return 0; } /* 비국소 점프 — 자원 해제 건너뜀 */
/* ... longjmp(env, 1) 로 이 지점으로 되돌아올 수 있음 ... */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
enum { OK = 0, ERR_IO = 1 };
static int do_work(void){ return OK; }
static void recover(void){ printf("recovered\n"); }
int main(void){
int rc = do_work(); /* 반환값으로 오류를 전파 — 흐름이 명시적 */
if (rc != OK) { recover(); }
return 0;
}⚠️ setjmp/longjmp 의 비국소 점프는 중간 스택 프레임의 자원 해제·소멸 처리를 건너뛰고 제어 흐름을 코드만으로 추적할 수 없게 만들어 누수와 일관성 깨짐을 부른다. 오류는 반환값(또는 상태 코드)으로 명시적으로 전파한다.The non-local jump of setjmp/longjmp skips resource release in intermediate stack frames and makes control flow untraceable from the code, causing leaks and inconsistency. Propagate errors explicitly through return values or status codes.
Rule 21.5Required · Decidable · Rule✓ compilablePDF rule
<signal.h> 의 시그널 기능을 사용하지 않는다The standard header file <signal.h> shall not be used
❌ 위반 예시Non-compliant example
#include <signal.h>
#include <stdio.h>
static void handler(int s){ (void)s; } /* 시그널 핸들러 — 비동기·구현정의 동작 */
int main(void){
signal(SIGINT, handler); /* 시그널 처리는 안전필수 환경에서 예측 불가 */
printf("running\n");
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
static int stop_requested(void){ return 1; } /* 상태 플래그를 협조적으로 검사 */
static void step(void){ /* 한 단계 처리 */ }
int main(void){
while (!stop_requested()) { /* 협조적 폴링 — 결정적이고 추적 가능 */
step();
}
printf("stopped\n");
return 0;
}⚠️ 시그널은 임의 시점에 비동기로 끼어들고 핸들러에서 할 수 있는 일이 구현정의·제한적이라, 안전필수 환경에서 경쟁·재진입·예측 불가 동작을 만든다. 종료·이벤트 요청은 상태 플래그를 협조적으로 폴링하는 결정적 메커니즘으로 처리한다.Signals interrupt asynchronously at arbitrary points and what a handler may do is implementation-defined and limited, producing races, reentrancy, and unpredictable behaviour in safety-critical environments. Handle shutdown/event requests with a deterministic mechanism that cooperatively polls a status flag.
Rule 21.6Required · Decidable · Rule✓ compilablePDF rule
표준 라이브러리 입출력 함수(<stdio.h>)를 사용하지 않는다The Standard Library input/output functions shall not be used
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int t = 25;
printf("temp=%d\n", t); /* 포맷 I/O — 포맷 문자열·버퍼·예외 동작 위험 */
return 0;
}✅ 준수 예시Compliant example
static void uart_write_str(const char *s){ (void)s; /* 검증된 전용 출력 */ }
static void uart_write_int(const char *label, int v){ (void)label; (void)v; }
int main(void){
int t = 25;
uart_write_int("temp=", t); /* 검증된 전용 입출력 계층 */
uart_write_str("\n");
return 0;
}⚠️ stdio 의 포맷 입출력은 포맷 문자열 취약점, 가려진 버퍼링, 구현정의 예외 동작 등 안전필수 시스템에 부적합한 위험을 동반한다. 동작이 검증된 전용 I/O 계층(예: UART 드라이버)을 사용해 입출력 경로를 통제한다.stdio formatted I/O carries risks unsuitable for safety-critical systems — format-string vulnerabilities, hidden buffering, implementation-defined exceptional behaviour. Use a validated dedicated I/O layer (e.g., a UART driver) to keep I/O paths controlled.
Rule 21.7Required · Decidable · Rule✓ compilablePDF rule
atoi/atol/atoll/atof 변환 함수를 사용하지 않는다The Standard Library functions atof, atoi, atol and atoll shall not be used
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
int n = atoi("99999999999abc"); /* 변환 실패·범위 초과를 알 수 없음 */
printf("%d\n", n);
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
int main(void){
const char *text = "12345";
char *end;
errno = 0;
long v = strtol(text, &end, 10);
if (end == text || *end != '\0' || errno == ERANGE || v < INT_MIN || v > INT_MAX) {
printf("conversion error\n"); /* 오류를 명확히 검출 */
return 1;
}
printf("%d\n", (int)v);
return 0;
}⚠️ atoi 계열은 변환 실패와 정상적인 0, 범위 초과를 전혀 구분하지 못해 잘못된 값을 조용히 반환하고, 이후 계산에 오류가 전파된다. end 포인터·errno 로 변환 결과를 검사할 수 있는 strtol 계열을 사용한다.The atoi family cannot distinguish a failed conversion, a legitimate 0, or out-of-range input, silently returning a wrong value that propagates into later computation. Use the strtol family, whose end pointer and errno let you verify the conversion.
Rule 21.8Required · Decidable · Rule✓ compilablePDF rule
<stdlib.h> 의 system/abort/exit/getenv 를 사용하지 않는다The library functions abort, exit, getenv and system of <stdlib.h> shall not be used
❌ 위반 예시Non-compliant example
#include <stdlib.h>
int main(void){
char *home = getenv("HOME"); /* 신뢰할 수 없는 환경 의존 */
(void)home;
system("rm -f /tmp/lock"); /* 셸을 거침 — 인젝션·환경 의존 위험 */
return 0;
}✅ 준수 예시Compliant example
static void remove_lock_file(void){ /* 셸 없이 내부 API 로 파일 제거 */ }
int main(void){
remove_lock_file(); /* 외부 셸 호출·환경 변수 의존 없이 처리 */
return 0;
}⚠️ system 은 셸을 거쳐 명령 인젝션 위험이 있고, getenv 는 신뢰할 수 없는 외부 환경에 의존하며, abort/exit 는 등록된 정리 루틴이나 자원 해제를 건너뛸 수 있다. 동일 기능을 내부 API와 정상 반환 경로로 대체한다.system runs through a shell with command-injection risk, getenv depends on an untrusted external environment, and abort/exit can skip registered cleanup or resource release. Replace these with internal APIs and normal return paths.
Rule 21.9Required · Decidable · Rule✓ compilablePDF rule
<stdlib.h> 의 bsearch/qsort 를 사용하지 않는다The library functions bsearch and qsort of <stdlib.h> shall not be used
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
static int cmp(const void *a, const void *b){ return (*(const int *)a) - (*(const int *)b); }
int main(void){
int a[5] = {3, 1, 4, 1, 5};
qsort(a, 5, sizeof(int), cmp); /* 콜백 의존·구현별 동작 차이 — 결정성 저하 */
printf("%d\n", a[0]);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
static void insertion_sort(int *a, int n){
for (int i = 1; i < n; i++) {
int key = a[i], j = i - 1;
while (j >= 0 && a[j] > key) { a[j + 1] = a[j]; j--; }
a[j + 1] = key;
}
}
int main(void){
int a[5] = {3, 1, 4, 1, 5};
insertion_sort(a, 5); /* 검증된 자체 알고리즘 — 결정적 동작 */
printf("%d\n", a[0]);
return 0;
}⚠️ qsort/bsearch 는 함수 포인터 콜백에 의존하고 정렬 안정성·동작이 구현마다 달라, 결과의 결정성과 정적 검증성을 떨어뜨린다. 동작이 검증된 자체 정렬·탐색 루틴으로 대체해 모든 입력에서 동일하고 예측 가능한 결과를 보장한다.qsort/bsearch rely on function-pointer callbacks and have implementation-varying stability and behaviour, reducing determinism and static verifiability. Replace them with validated in-house sort/search routines that guarantee identical, predictable results for all inputs.
Rule 21.10Required · Decidable · Rule✓ compilablePDF rule
<time.h> 의 날짜/시간 함수를 사용하지 않는다The Standard Library time and date functions shall not be used
❌ 위반 예시Non-compliant example
#include <time.h>
#include <stdio.h>
int main(void){
time_t now = time(NULL); /* 구현정의 동작·환경(시스템 클록) 의존 */
printf("%ld\n", (long)now);
return 0;
}✅ 준수 예시Compliant example
#include <stdint.h>
#include <stdio.h>
static uint32_t rtc_get_ticks(void){ return 1000u; } /* 하드웨어 타이머 추상화 */
int main(void){
uint32_t ticks = rtc_get_ticks(); /* 결정적·검증 가능한 시간 소스 */
printf("%u\n", ticks);
return 0;
}⚠️ 표준 시간 함수(time/localtime/strftime 등)는 구현정의 동작과 시스템 클록·로캘 같은 환경 의존성이 커, 안전필수 시스템에서 동작을 재현·검증하기 어렵다. 하드웨어 타이머를 감싼 추상화 계층을 사용해 시간 소스를 결정적으로 통제한다.Standard time functions (time/localtime/strftime, …) have implementation-defined behaviour and depend on the system clock and locale, making them hard to reproduce and verify in safety-critical systems. Use a hardware-timer abstraction layer to keep the time source deterministic and controlled.
Rule 21.11Required · Decidable · RulePDF example
<tgmath.h> 타입-제네릭 수학 매크로를 사용하지 않는다The standard header file <tgmath.h> shall not be used
❌ 위반 예시Non-compliant example
f1 = sqrt ( f2 ); /* Non-compliant - generic sqrt used */
✅ 준수 예시Compliant example
f1 = sqrtf ( f2 ); /* Compliant - float version of sqrt used */
⚠️ tgmath 의 타입-제네릭 매크로는 인자 타입에 따라 sqrtf/sqrt/sqrtl 중 하나를 자동 선택해, 실제로 어떤 정밀도의 함수가 호출되는지 코드만으로 알 수 없어 의도 파악과 정적 분석을 어렵게 한다. <math.h> 의 타입별 함수를 명시적으로 호출한다.tgmath’s type-generic macros auto-select among sqrtf/sqrt/sqrtl based on argument type, so which precision is actually called is not evident from the code, hampering intent and static analysis. Call the type-specific functions from <math.h> explicitly.
Rule 21.12Advisory · Decidable · RulePDF example
The exception handling features of <fenv.h> should not be usedThe exception handling features of <fenv.h> should not be used
❌ 위반 예시Non-compliant example
#include <fenv.h>
void f ( float32_t x, float32_t y )
{
float32_t z;
feclearexcept ( FE_DIVBYZERO ); /* Non-compliant */
z = x / y;
if ( fetestexcept ( FE_DIVBYZERO ) ) /* Non-compliant */
{
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 21.12 (The exception handling features of <fenv.h> should not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 21.12 (The exception handling features of <fenv.h> should not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
R22자원Resources
Rule 22.1Required · Undecidable · RulePDF example
획득한 자원은 모두 해제되어야 한다All resources obtained dynamically by means of Standard Library functions shall be explicitly released
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main ( void )
{
FILE *fp;
fp = fopen ( "tmp-1", "w" );
fprintf ( fp, "*" );
/* File "tmp-1" should be closed here, but stream 'leaks'. */
fp = fopen ( "tmp-2", "w" );
fprintf ( fp, "!" );
fclose ( fp );
return ( 0 );
}✅ 준수 예시Compliant example
#include <stdio.h>
static int read_fail(FILE *f){ (void)f; return 1; }
int main(void){
FILE *f = fopen("/etc/hostname", "r");
if (f == NULL) { return 1; }
int rc = read_fail(f) ? -1 : 0;
fclose(f); /* 모든 종료 경로에서 해제 */
return rc;
}⚠️ 정상 경로에서만 해제하고 오류·조기 반환 경로에서 fclose/free 를 빠뜨리면, 반복 호출 시 파일 핸들·메모리가 누수되어 결국 자원 고갈로 이어진다. 자원 해제를 단일 종료 지점에 모으거나 모든 경로에서 해제를 보장한다.Releasing only on the normal path and skipping fclose/free on error or early-return paths leaks handles and memory across repeated calls, eventually exhausting resources. Consolidate release at a single exit point or guarantee release on every path.
Rule 22.2Mandatory · Undecidable · RulePDF example
동적으로 할당된 메모리만 해제하며, 같은 메모리를 두 번 해제하지 않는다A block of memory shall only be freed if it was allocated by means of a Standard Library function
❌ 위반 예시Non-compliant example
#include <stdlib.h>
v oid fn ( void )
{
int32_t a;
/* Non-compliant - a does not point to allocated storage */
free ( &a );
}
void g ( void )
{
char *p = ( char * ) malloc ( 512 );
char *q = p;
free ( p );
/* Non-compliant - allocated block freed a second time */
free ( q );
/* Non-compliant - allocated block may be freed a third time */
p = ( char * ) realloc ( p, 1024 );
}✅ 준수 예시Compliant example
#include <stdlib.h>
int main(void){
int x = 5;
(void)x; /* 자동/정적 객체는 free 하지 않는다(스코프 종료 시 자동 회수) */
/* 동적 메모리를 쓴다면 할당된 포인터를 정확히 한 번만 free 하고 NULL 로 무효화 */
return 0;
}⚠️ malloc 계열로 할당하지 않은 메모리(자동·정적 객체)나 이미 해제된 포인터를 free 하면 힙 메타데이터가 손상되어 미정의 동작·크래시가 발생한다. free 대상은 살아 있는 동적 할당 포인터로 한정하고, 해제 후에는 포인터를 NULL 로 무효화해 이중 해제를 막는다.Freeing memory not obtained from the malloc family (automatic/static objects) or an already-freed pointer corrupts heap metadata, causing undefined behaviour or crashes. Restrict free to live dynamically allocated pointers and null out the pointer after freeing to prevent double free.
Rule 22.3Required · Undecidable · RulePDF example
같은 파일을 동시에 읽기/쓰기 스트림으로 중복 개방하지 않는다The same file shall not be open for read and write access at the same time on different streams
❌ 위반 예시Non-compliant example
#include <stdio.h>
void fn ( void )
{
FILE *fw = fopen ( "tmp", "r+" ); /* "r+" opens for read/write */
FILE *fr = fopen ( "tmp", "r" ); /* Non-compliant */
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *f = fopen("data.bin", "w+"); /* 단일 핸들로 읽기/쓰기 일원화 */
if (f == NULL) { return 1; }
fclose(f);
return 0;
}⚠️ 같은 파일을 여러 스트림으로 동시에 열면 각 스트림이 독립 버퍼를 가져, 한쪽의 쓰기가 다른 쪽 버퍼에 반영되지 않아 데이터 손상·불일치가 발생한다. 한 파일은 단일 핸들로 접근을 일원화해 일관성을 보장한다.Opening the same file on multiple streams gives each its own buffer, so a write on one is not reflected in the other’s buffer, causing corruption and inconsistency. Consolidate access to a file through a single handle to guarantee consistency.
Rule 22.5Manda · RulePDF example
A pointer to a FILE object shall not be dereferencedA pointer to a FILE object shall not be dereferenced
❌ 위반 예시Non-compliant example
f3 = *pf2; /* Non-compliant */ pf1->pos = 0; /* Non-compliant */
✅ 준수 예시Compliant example
pf2 = pf1; /* Compliant */
⚠️ Rule 22.5 (A pointer to a FILE object shall not be dereferenced)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 22.5 (A pointer to a FILE object shall not be dereferenced) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 22.6Mandatory · Undecidable · RulePDF example
닫힌 FILE 포인터를 사용하지 않는다The value of a pointer to a FILE shall not be used after the associated stream has been closed
❌ 위반 예시Non-compliant example
#include <stdio.h>
void fn ( void )
{
FILE *fp;
void *p;
fp = fopen ( "tm p", "w" );
if ( fp == NULL )
{
error_action ( );
}
fclose ( fp );
fprintf ( fp, "?" ); /* Non-compl iant */
p = fp; /* Non-compliant */
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *f = fopen("/dev/null", "w");
if (f == NULL) { return 1; }
fprintf(f, "x"); /* 닫기 전에 모든 사용을 완료 */
fclose(f);
f = NULL; /* 닫은 뒤 포인터를 무효화 */
return 0;
}⚠️ fclose 이후 FILE 포인터는 더 이상 유효한 스트림을 가리키지 않으므로, 그 포인터로 입출력을 하면 해제된 자원을 사용하는 미정의 동작이 된다. 모든 사용을 닫기 전에 끝내고, 닫은 뒤에는 포인터를 NULL 로 무효화해 재사용을 차단한다.After fclose, a FILE pointer no longer refers to a valid stream, so doing I/O through it uses a released resource — undefined behaviour. Complete all use before closing and null out the pointer afterward to prevent reuse.
MISRA C++:2023
Guidelines for the use of C++17 in critical systems
Mandatory / Required / AdvisoryMandatory / Required / AdvisoryDecidable / UndecidableDecidable / UndecidableRule 섹션.그룹.번호Rule section.group.number
AUTOSAR C++14 가이드라인을 흡수해 C++17 기준으로 재편한 최신 표준. 룰 번호는 "Rule 섹션.그룹.번호"(예: Rule 8.2.2).The latest standard, absorbing AUTOSAR C++14 and re-based on C++17. Rule numbers use the form "Rule section.group.number" (e.g. Rule 8.2.2).
M0섹션 0Section 0
Rule 0.0.1Required · DecidablePDF example
함수에 도달 불가능한 코드를 두지 않는다A function shall not contain unreachable statements
❌ 위반 예시Non-compliant example
res = c; // Non-compliant - not reachable from entry block
bool result; // Non-compliant - not reachable from entry block
++i; // Non-compliant - not reachable from entry block
++i; // Non-compliant - no edge to this block
catch ( DerivedException & d ) { } // Non-compliant - will be caught above
catch ( int32_t ) { } // Non-compliant - f5 is not potentially-throwing
catch ( ... ) { } // Non-compliant - f5 is not potentially-throwing
++i; // Non-compliant - no edge to this block
return 0; // Non-compliant✅ 준수 예시Compliant example
if ( false && f0() ) { } // Compliant - statement is considered to be reachable
++i; // Compliant - reachable via 'break'
++i; // Compliant
catch ( int32_t ) { } // Compliant - all catch-handlers are reachable
catch ( int16_t ) { } // Compliant - all catch-handlers are reachable
++i; // Compliant
return i * 2; // Compliant
catch( int32_t ) { } // Compliant - all catch-handlers are reachable
return 0; // Compliant - even if f8 throws a type⚠️ return·throw·무조건 분기 이후에 놓인 도달 불가 코드는 제어 흐름을 잘못 작성했다는 신호이며, 의도한 로깅·정리 같은 부작용이 실행되지 않는 결함을 숨긴다. 도달 불가 코드는 제거하거나 흐름을 바로잡는다.Unreachable code after return, throw, or an unconditional branch signals mis-written control flow and hides a defect where intended side effects such as logging or cleanup never run. Remove unreachable code or fix the flow.
Rule 0.0.2Advisory · UndecidablePDF example
Controlling expressions should not be invariantControlling expressions should not be invariant
❌ 위반 예시Non-compliant example
s8a = ( u16a < 0u ) ? 0 : 1; // Non-compliant - u16a always >= 0
if ( u16a <= 0xffffu ) { } // Non-compliant - always true
if ( 2 > 3 ) { } // Non-compliant - always false
if ( ( s8a < 10 ) && ( s8a > 20 ) ) { } // Non-compliant - always false
if ( ( s8a < 10 ) || ( s8a > 5 ) ) { } // Non-compliant - always true
( s8a > 20 ) || // Non-compliant - left operand of ||
if ( N == 4u ) // Non-compliant - compiler is permitted
if ( s8a > 5 ) { } // Non-compliant - s8a always > 5
for ( s8a = 0; s8a < 130; ++s8a ) { } // Non-compliant - always true
// Non-compliant - the sum of six, consecutive, non-negative integers is always✅ 준수 예시Compliant example
if ( M == 4u ) // Compliant - compiler assumes M may
while ( true ) { /* Do something */ } // Compliant by exception #1
do { } while ( false ); // Compliant by exception #2⚠️ Rule 0.0.2 (Controlling expressions should not be invariant)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 0.0.2 (Controlling expressions should not be invariant) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 0.1.1Advisory · DecidablePDF example
계산된 값이 사용되지 않게 두지 않는다(useless value)A value should not be unnecessarily computed (a computed value should be used)
❌ 위반 예시Non-compliant example
auto j = i; // Non-compliant - j is not observed after being written
i++; // Non-compliant - i is not observed after being written
m = 10; // Non-compliant - when looping, overwrites incremented value
++k; // Non-compliant - k is never observed
i = 0; // Non-compliant - value passed is overwritten
p.x = 3; // Non-compliant - overwrite the value 2 that is never read
v[ 0 ] = 3; // Non-compliant - overwrite the value 2 that is never read
char c = f( 1 ); // Non-compliant - assigned value never read
callee( i ); // Non-compliant - i written and not subsequently observed✅ 준수 예시Compliant example
j++; // Compliant - writes object i that is observed in the return
for ( int32_t i = 0; i < 10; ++i ) // Compliant - i is observed in i < 10
++j; // Compliant - observation above is sufficient for final write
++m; // Compliant - observed in the return
int32_t j ) // Compliant by exception - j is never observed
int32_t k = 4; // Compliant - value is observed in one feasible path
Point p {}; // Compliant - p and its subobjects are observed in the return
p.z = 4; // Compliant - p.z is observed in the return
std::vector< int32_t > v( 4, 0 ); // Compliant - v and its elements are observed
v[ 2 ] = 4; // Compliant - v[ 2 ] is observed in the return⚠️ 읽히기 전에 덮어써지는 계산 결과는 죽은 계산이며, 흔히 대입을 빠뜨렸거나 조건 분기를 잘못 작성했다는 신호다. 사용되지 않는 계산은 제거하거나, 누락된 로직을 채워 그 값을 실제로 사용하도록 고친다.A computed result overwritten before it is read is dead computation and usually signals a missed assignment or a wrong branch. Remove the unused computation, or fix the missing logic so the value is actually used.
Rule 0.1.2Advisory · DecidablePDF example
사용되지 않는 변수/멤버를 두지 않는다A named object that is not used should not be declared
❌ 위반 예시Non-compliant example
func(); // Non-compliant - implicitly discarded s.operator=( q ); // Non-compliant f(); // Non-compliant - using function call syntax a(); // Non-compliant - using function call syntax
✅ 준수 예시Compliant example
( void )func(); // Compliant - void cast is a use auto b = func(); // Compliant - used as initializer
⚠️ 사용되지 않는 객체는 빠뜨린 로직(읽어 놓고 쓰지 않음)을 의심하게 만들고 코드를 어지럽혀 가독성을 떨어뜨린다. 미사용 변수·멤버는 제거하되, 부작용 있는 초기화였다면 그 의도까지 검토해 정리한다.An unused object suggests omitted logic (read but never used) and clutters the code, hurting readability. Remove unused variables and members, and when the initializer had side effects, review that intent while cleaning up.
Rule 0.2.1Advisory · DecidablePDF example
Variables with limited visibility should be used at least onceVariables with limited visibility should be used at least once
❌ 위반 예시Non-compliant example
C c; // Non-compliant - unused const int16_t y = 21; // Non-compliant - would be compliant by exception #2 int16_t local_1 = 42; // Non-compliant - local_1 is never read
✅ 준수 예시Compliant example
bool b = a > 0; // Compliant (by exception #1 if NDEBUG is defined)
const int16_t x = 19; // Compliant - x is read in initializedButNotUsed
int16_t local_2; // Compliant
std::ifstream fs { "cfg.ini" }; // Compliant - user-provided constructor⚠️ Rule 0.2.1 (Variables with limited visibility should be used at least once)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 0.2.1 (Variables with limited visibility should be used at least once) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 0.2.2Required · DecidablePDF example
한 객체에 같은 값을 중복으로 대입하지 않는다(중복 부작용)A function or object should not be assigned a value that is never used before being overwritten
❌ 위반 예시Non-compliant example
int16_t f( int16_t a, int16_t b ) override // Non-compliant - 'b' unused
void f1(int32_t i, // Non-Compliant
int32_t n ) // Non-compliant
int32_t f2( int32_t i, // Non-compliant for f2< false >✅ 준수 예시Compliant example
int16_t f( int16_t a, // Compliant - 'a' is used
int16_t f( int16_t a, int16_t b ) override // Compliant
int16_t f( int16_t a, // Compliant
int32_t j ) // Compliant - explicitly cast to void
auto l = []( int32_t m, // Compliant⚠️ 같은 객체에 사용되지 않은 값을 연달아 대입하면 첫 결과(그리고 그 함수의 부작용)가 무의미하게 버려져, 의도를 알 수 없고 부작용이 중복 수행되어 성능·정확성 문제를 만든다. 필요한 대입만 남기고 중복을 제거한다.Assigning successive unused values to the same object discards the first result (and its function’s side effects) pointlessly, obscuring intent and duplicating side effects with performance and correctness costs. Keep only the needed assignment and remove the duplication.
Rule 0.2.3Advisory · DecidablePDF example
Types with limited visibility should be used at least onceTypes with limited visibility should be used at least once
❌ 위반 예시Non-compliant example
using T1 = int16_t; // Non-compliant
struct A2 { A2 f(); }; // Non-compliant
template< typename > struct C1 {}; // Non-compliant
static union // Non-compliant✅ 준수 예시Compliant example
using T2 [[maybe_unused]] = int32_t; // Compliant by exception #1
struct A1 { A1 f(); }; // Compliant
template< typename T > // Compliant by exception #2
struct res { int32_t i; }; // Compliant
return bar< struct P >(); // Compliant - P is used
template<> struct C1< int32_t > // Compliant by exception #3
template< typename > struct C2 {}; // Compliant - C2< float > used
template<> struct C2< int32_t >; // Compliant by exception #3
static union // Compliant
[]( auto ){}; // Compliant - closure type is always used⚠️ Rule 0.2.3 (Types with limited visibility should be used at least once)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 0.2.3 (Types with limited visibility should be used at least once) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 0.2.4Advisory · DecidablePDF example
Functions with limited visibility should be used at least onceFunctions with limited visibility should be used at least once
❌ 위반 예시Non-compliant example
void m4() { } // Non-compliant - not used
static void f1() { } // Non-compliant - not used
void f2() { } // Non-compliant - not used
static void swap( C2 &, C2 & ); // Non-compliant✅ 준수 예시Compliant example
void m3() { } // Compliant - called
void m5() { } // Compliant - used by a friend
static void f3() { } // Compliant - address taken in f4()
static void swap( C1 &, C1 & ); // Compliant - overload set for call in f5
void swap( T &, T & ); // Compliant - overload set for call in f5⚠️ Rule 0.2.4 (Functions with limited visibility should be used at least once)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 0.2.4 (Functions with limited visibility should be used at least once) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Dir지침(Directive)Directives
Dir 0.3.1AdvisoryPDF rule
부동소수점 연산을 적절히 사용해야 한다Floating-point arithmetic should be used appropriately
❌ 위반 예시Non-compliant example
bool isNan(double d) {
return d == std::numeric_limits<double>::quiet_NaN(); // NaN==x 는 항상 false
}
bool equal(double a, double b) {
return a == b; // 부동소수 정확 비교 — 반올림 오차로 실패
}✅ 준수 예시Compliant example
#include <cmath>
#include <algorithm>
bool isNan(double d) { return std::isnan(d); }
bool equal(double a, double b) {
return std::abs(a - b) <= 1e-9 * std::max(std::abs(a), std::abs(b));
}⚠️ 부동소수의 안전한 사용은 높은 수치해석 지식을 요구한다. NaN/무한대/정밀도 손실/상쇄 오차 등을 고려하지 않은 == 비교나 quiet_NaN 비교는 잘못된 결과를 낳는다.Safe floating-point use needs strong numerical-analysis knowledge; naive == comparisons or comparing against quiet_NaN ignore NaN/infinity/precision-loss/cancellation and give wrong results.
Dir 0.3.2RequiredPDF rule
함수 호출은 함수의 전제조건을 위반하지 않아야 한다A function call shall not violate the function's preconditions
❌ 위반 예시Non-compliant example
int first(const std::vector<int>& v) {
return v.front(); // 전제조건(비어있지 않음) 위반 시 미정의 동작
}
int caller() {
std::vector<int> empty;
return first(empty); // 빈 벡터로 호출 → 전제조건 위반
}✅ 준수 예시Compliant example
#include <optional>
std::optional<int> first(const std::vector<int>& v) {
if (v.empty()) return std::nullopt; // 전제조건을 호출 전에 보장
return v.front();
}⚠️ 함수의 암시적·명시적 전제조건(비어있지 않은 컨테이너, 0이 아닌 제수 등)을 위반하면 예기치 못한 결과나 미정의 동작이 발생한다. 호출 전에 전제조건을 보장해야 한다.Violating a function's implicit or explicit preconditions (non-empty container, non-zero divisor, …) causes unexpected results or undefined behaviour; guarantee preconditions before calling.
Dir 5.7.2AdvisoryPDF example
Sections of code should not be "commented out"Sections of code should not be "commented out"
❌ 위반 예시Non-compliant example
// Bug 42 - this call used to be:
// calculate ( z , y + 1 );
calculate ( x , y - 1 );
enum E
{
#if 0 // Non-compliant
E_0 // - this is considered to be commented out code
#else✅ 준수 예시Compliant example
// You should not call lock/unlock directly, but through RAII:
// ```
// void f( Data & d, MyMutex & m )
// {
// std::scoped_lock lock { m };
// d.doSomething();
// } // m is automatically unlocked
// ```
struct MyMutex
{
void lock();
void unlock();
};⚠️ Dir 5.7.2 (Sections of code should not be "commented out")은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Dir 5.7.2 (Sections of code should not be "commented out") was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Dir 15.8.1Required · UndecidablePDF example
복사/이동 대입 연산자는 자기 대입을 안전하게 처리한다User-provided copy/move assignment operators shall handle self-assignment safely
❌ 위반 예시Non-compliant example
Vector & Vector::operator=( Vector const & other ) &
{
this->size_ = other.size_;
delete[] this->buffer_; // Deletes other.buffer_
this->buffer_ = new int[ other.size_ ]; // Reading from deleted storage,
// resulting in undefined behaviour
( void )std::copy_n( other.buffer_,
this->buffer_ );
return *this;
}
This unde%ned behaviour can be prevented by introducing a check for self-assignment.
Vector & Vector::operator=( Vector const & other ) &
{
if ( this != std::addressof( other ) )
{
this->size_ = other.size_;
delete[] this->buffer_;
this->buffer_ = new int[ other.size_ ];
( void )std::copy_n( other.buffer_,
this->buffer_ );
}
return *this;
}
constructor (deep copy of elements); and
Vector & Vector::operator=( Vector const & other ) &
{
Vector tmp( other ); // Copy construction, with deep copying
std::swap( this->size_, tmp.size_ );
std::swap( this->buffer_, tmp.buffer_ );
return *this;
// tmp goes out of scope and thus takes care of deleting the previous buffer
}
Self-assignment is handled appropriately when using the copy-and-swap idiom. However, the creation
Vector & Vector::operator=( Vector && other ) & noexcept
{
delete[] this->buffer_;
this->size_ = std::exchange( other.size_, 0 );
this->buffer_ = std::exchange( other.buffer_, nullptr );
return *this;
}
Vector & Vector::operator=( Vector && other ) & noexcept
{
Vector tmp( std::move( other ) );
std::swap( this->size_, tmp.size_ );
std::swap( this->buffer_, tmp.buffer_ );
return *this;
}✅ 준수 예시Compliant example
#include <iostream>
struct Buf {
char* p; int n;
Buf(const char* s, int len) : p(new char[len]), n(len) { for(int i=0;i<len;++i) p[i]=s[i]; }
Buf& operator=(const Buf& o){
if (this == &o) return *this; // 자기 대입 가드
char* np = new char[o.n];
for (int i = 0; i < o.n; ++i) np[i] = o.p[i];
delete[] p; p = np; n = o.n;
return *this;
}
~Buf(){ delete[] p; }
};
int main(){ Buf b("hi", 2); b = b; std::cout << b.n << '\n'; }⚠️ 자기 대입(b = b)을 고려하지 않은 대입 연산자는 대상의 자원을 먼저 해제한 뒤 같은(이미 해제된) 자원을 읽어 복사하므로 미정의 동작과 데이터 손상이 발생한다. this==&o 가드를 두거나 copy-and-swap 관용구를 적용해 자기 대입을 안전하게 처리한다.An assignment operator that ignores self-assignment (b = b) frees the destination’s resource first and then reads the same (now-freed) resource to copy it, causing undefined behaviour and data corruption. Add a this==&o guard or apply the copy-and-swap idiom to handle self-assignment safely.
M4섹션 4Section 4
Rule 4.1.1Required · UndecidablePDF example
A program shall conform to ISO/IEC 14882:2017 (C++17)A program shall conform to ISO/IEC 14882:2017 (C++17)
❌ 위반 예시Non-compliant example
#warning "declaring an interrupt handler" // Non-compliant __interrupt void handler(); // Non-compliant
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 4.1.1 (A program shall conform to ISO/IEC 14882:2017 (C++17))은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 4.1.1 (A program shall conform to ISO/IEC 14882:2017 (C++17)) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 4.1.2Advisory · DecidablePDF example
Deprecated features should not be usedDeprecated features should not be used
❌ 위반 예시Non-compliant example
#include <codecvt> // Non-compliant - [depr.locale.stdcvt]
void foo() throw() // Non-compliant - [depr.except.spec]
C1 c1b { c1a }; // Non-compliant - [depr.impldec]✅ 준수 예시Compliant example
C1 c1a {}; // Compliant - no use of copy constructor⚠️ Rule 4.1.2 (Deprecated features should not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 4.1.2 (Deprecated features should not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 4.1.3Required · UndecidablePDF example
There shall be no occurrence of undefined or critical unspecified behaviourThere shall be no occurrence of undefined or critical unspecified behaviour
❌ 위반 예시Non-compliant example
static_cast< int8_t >( 128 ) // Unspecified - 128 is not representable as int8_t
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 4.1.3 (There shall be no occurrence of undefined or critical unspecified behaviour)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 4.1.3 (There shall be no occurrence of undefined or critical unspecified behaviour) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 4.6.1Advisory · UndecidablePDF example
부작용의 평가 순서에 의존하지 않는다The behaviour of a program shall not depend on the order of evaluation of side effects
❌ 위반 예시Non-compliant example
x = b[ i ] + i++; // Non-compliant x = func( i++, i ); // Non-compliant uint16_t t = v1 + v2; // Non-compliant - indeterminately sequenced
✅ 준수 예시Compliant example
v1 = v1 & 0x80u; // Compliant
⚠️ 함수 인자나 한 식에서 같은 객체를 여러 번 수정하면(use(i++, i++)) 부작용의 평가 순서가 미명세라 결과가 컴파일러·최적화 수준마다 달라진다. 부작용을 별도 문장으로 분리해 순서를 명확히 확정한다.Modifying the same object multiple times in function arguments or one expression (use(i++, i++)) leaves the order of side effects unspecified, so results vary by compiler and optimization level. Split side effects into separate statements to fix the order definitively.
M5섹션 5Section 5
Rule 5.0.1Advisory · DecidablePDF example
Trigraph-like sequences should not be usedTrigraph-like sequences should not be used
❌ 위반 예시Non-compliant example
const char * msg = "(Date format is ??-??-??)"; // Non-compliant
✅ 준수 예시Compliant example
const char * msg = "(Date format is ?\?-?\?-?\?)"; // Compliant
⚠️ Rule 5.0.1 (Trigraph-like sequences should not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.0.1 (Trigraph-like sequences should not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.7.1Required · DecidablePDF example
The character sequence /* shall not be used within a C-style commentThe character sequence /* shall not be used within a C-style comment
❌ 위반 예시Non-compliant example
/* Some comment, end comment marker accidentally omitted Perform_Critical_Safety_Function( X ); /* <- this is non-compliant */
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 5.7.1 (The character sequence /* shall not be used within a C-style comment)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.7.1 (The character sequence /* shall not be used within a C-style comment) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.7.3Required · DecidablePDF example
Line-splicing shall not be used in // commentsLine-splicing shall not be used in // comments
❌ 위반 예시Non-compliant example
void f( bool b )
{
uint16_t x = 0U; // comment \
if ( b )
{
++x; // This is always executed
}
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 5.7.3 (Line-splicing shall not be used in // comments)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.7.3 (Line-splicing shall not be used in // comments) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.10.1Required · DecidablePDF example
User-defined identifiers shall have an appropriate formUser-defined identifiers shall have an appropriate form
❌ 위반 예시Non-compliant example
int32_t i ﴾= 2; // Non-compliant - character \ufd3e (even though
#define identity(a) a // Non-compliant - shall be in uppercase
auto _i = 0; // Non-compliant - using a leading _, even at
void operator ""mil( long double ); // Non-compliant - user-defined literal
double operator "" _Bq( long double ); // Non-compliant - _Bq is preceded by a
int i; // Non-compliant - defined within namespace stdN
auto final = 42; // Non-compliant✅ 준수 예시Compliant example
void operator ""_km( long double ); // Compliant - will be called for 1.0_km double operator ""_Bq ( long double ); // Compliant #include <cstdio> // Compliant - even though it introduces FILE
⚠️ Rule 5.10.1 (User-defined identifiers shall have an appropriate form)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.10.1 (User-defined identifiers shall have an appropriate form) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.13.1Required · DecidablePDF example
표준에 정의된 이스케이프 시퀀스만 사용한다Octal and hexadecimal escape sequences, and the escape sequences defined by the standard, shall be used correctly
❌ 위반 예시Non-compliant example
const char * a = "\k"; // Non-compliant
✅ 준수 예시Compliant example
const char * b = "\b\u00E9"; // Compliant
⚠️ 표준이 정의하지 않은 이스케이프 시퀀스(\q 등)는 구현마다 다르게 해석되거나 미정의 동작이 되어 의도와 다른 문자가 들어간다. \t, \n, \\ 처럼 표준이 정의한 이스케이프만 사용해 문자열의 의미를 고정한다.Escape sequences not defined by the standard (such as \q) are interpreted differently across implementations or are undefined, inserting unintended characters. Use only standard-defined escapes like \t, \n, \\ to fix the string’s meaning.
Rule 5.13.2Required · DecidablePDF example
Octal escape sequences, hexadecimal escape sequences and universal character names shall be terminatedOctal escape sequences, hexadecimal escape sequences and universal character names shall be terminated
❌ 위반 예시Non-compliant example
const char * s1 = "\1234"; // Non-compliant - \123 is not terminated const char * s2 = "\x41g"; // Non-compliant const char * s5 = "\u0001F600"; // Non-compliant - \u0001 is not terminated
✅ 준수 예시Compliant example
const char * s3 = "\x41" "g"; // Compliant - terminated by end of literal const char * s4 = "\x41\x67"; // Compliant - terminated by another escape const char * s6 = "\U0001F600"; // Compliant - terminated by end of literal
⚠️ Rule 5.13.2 (Octal escape sequences, hexadecimal escape sequences and universal character names shall be terminated)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.13.2 (Octal escape sequences, hexadecimal escape sequences and universal character names shall be terminated) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.13.3Required · DecidablePDF example
8진(octal) 상수와 8진 이스케이프 사용을 피한다Octal constants shall not be used
❌ 위반 예시Non-compliant example
code[ 3 ] = 052; // Non-compliant - equivalent to decimal 42, not 52 code[ 4 ] = 071; // Non-compliant - equivalent to decimal 57, not 71 code[ 6 ] = 000; // Non-compliant - exception does not apply
✅ 준수 예시Compliant example
code[ 1 ] = 109; // Compliant - decimal 109 code[ 2 ] = 100; // Compliant - decimal 100 code[ 5 ] = 0; // Compliant by exception
⚠️ 선행 0이 붙은 정수는 8진수로 해석되어 0755 가 493 이 되는 등 십진으로 오독하기 쉬워, 권한 비트·코드 값 설정에서 미묘한 버그를 만든다. 십진 또는 명시적 16진(0x) 표기를 사용한다.An integer with a leading 0 is interpreted as octal, so 0755 is 493 — easily misread as decimal, producing subtle bugs in permission bits and code values. Use decimal or explicit hexadecimal (0x) notation.
Rule 5.13.4Required · DecidablePDF example
Unsigned integer literals shall be appropriately su[xedUnsigned integer literals shall be appropriately su[xed
❌ 위반 예시Non-compliant example
auto y = 0x8000; // Non-compliant - unsigned type f( 0x8000 ); // Non-compliant - calls #1 as 0x8000 is unsigned
✅ 준수 예시Compliant example
auto x = 32768; // Compliant - signed type uint16_t z = 123; // Compliant - 'u' is not required as '123' is signed f( 0x8000u ); // Compliant - calls #1 f( 0x7FFF ); // Compliant - calls #2 as 0x7FFF is signed f( 0x7FFFu ); // Compliant - calls #1
⚠️ Rule 5.13.4 (Unsigned integer literals shall be appropriately su[xed)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.13.4 (Unsigned integer literals shall be appropriately su[xed) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.13.5Required · DecidablePDF example
정수 리터럴의 접미사는 대문자로 표기한다The lowercase form of L shall be used in integer literal suffixes
❌ 위반 예시Non-compliant example
int64_t const b = 0l; // Non-compliant uint64_t const d = 1lU; // Non-compliant long long const h = 3ll; // Non-compliant long double const j = 3.4l; // Non-compliant
✅ 준수 예시Compliant example
int64_t const a = 0L; // Compliant uint64_t const c = 1Lu; // Compliant uint64_t const e = 2uLL; // Compliant uint64_t const f = 2Ull; // Compliant long long const g = 3LL; // Compliant long double const i = 1.2L; // Compliant
⚠️ 소문자 l 접미사는 글꼴에 따라 숫자 1과 거의 구분되지 않아 100l 이 1001 처럼 오독되어 값 자체를 잘못 읽게 만든다. 정수 리터럴 접미사는 항상 대문자(L, LL, U)로 표기한다.A lowercase l suffix is nearly indistinguishable from the digit 1 in many fonts, so 100l can be misread as 1001, causing the value itself to be misread. Always write integer literal suffixes in uppercase (L, LL, U).
Rule 5.13.6Required · DecidablePDF example
An integer-literal of type long long shall not use a single L or l in any su[xAn integer-literal of type long long shall not use a single L or l in any su[x
❌ 위반 예시Non-compliant example
auto k1 = 12345678998L; // Non-compliant auto k2 = 12345678998UL; // Non-compliant auto k4 = 0xfeeddeadbeefL; // Non-compliant
✅ 준수 예시Compliant example
auto k3 = 12345678998ull; // Compliant auto k5 = 0xfeeddeadbeefLL; // Compliant
⚠️ Rule 5.13.6 (An integer-literal of type long long shall not use a single L or l in any su[x)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.13.6 (An integer-literal of type long long shall not use a single L or l in any su[x) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 5.13.7Required · DecidablePDF example
String literals with diCerent encoding prefixes shall not be concatenatedString literals with diCerent encoding prefixes shall not be concatenated
❌ 위반 예시Non-compliant example
const wchar_t * s2 = "Hello" L"World"; // Non-compliant const wchar_t * s3 = u"Hello" L"World"; // Non-compliant - may not compile const char * s5 = u8R"#(Hello)#" "World"; // Non-compliant
✅ 준수 예시Compliant example
const char * s0 = "Hello" "World"; // Compliant const wchar_t * s1 = L"Hello" L"World"; // Compliant const char * s4 = u8R"#(Hello)#" u8"World"; // Compliant
⚠️ Rule 5.13.7 (String literals with diCerent encoding prefixes shall not be concatenated)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 5.13.7 (String literals with diCerent encoding prefixes shall not be concatenated) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
M6섹션 6Section 6
Rule 6.0.1Required · DecidablePDF example
내부 범위 식별자가 외부 범위 식별자를 가리지 않게 한다A declaration shall not hide a declaration with the same name in an enclosing scope
❌ 위반 예시Non-compliant example
void f2(); // Non-compliant - function declaration at block scope A a1(); // Non-compliant - appears to declare an object with no int32_t ( j ); // Non-compliant - declares 'j' (using redundant parentheses)
✅ 준수 예시Compliant example
A a2; // Compliant
int32_t { j }; // Compliant with this rule, but violates "See also"⚠️ 안쪽 범위에서 바깥 식별자와 같은 이름을 선언하면(shadowing) 어느 객체를 쓰는지 혼동되어, 전역을 갱신하려다 지역만 바꾸는 결함을 만든다. 내부 식별자는 바깥 이름과 다르게(예: 접두사) 지어 가림을 방지한다.Declaring an inner-scope name identical to an enclosing identifier (shadowing) confuses which object is used, causing defects where a global is meant to be updated but only the local changes. Name inner identifiers differently (e.g., with a prefix) to avoid hiding.
Rule 6.0.2Advisory · DecidablePDF example
When an array with external linkage is declared, its size should be explicitly specifiedWhen an array with external linkage is declared, its size should be explicitly specified
❌ 위반 예시Non-compliant example
extern int32_t array2[ ]; // Non-compliant
✅ 준수 예시Compliant example
int32_t array1[ 10 ]; // Compliant
int32_t array3[ ] = { 0, 10, 15 }; // Compliant
extern int32_t array4[ 42 ]; // Compliant⚠️ Rule 6.0.2 (When an array with external linkage is declared, its size should be explicitly specified)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.0.2 (When an array with external linkage is declared, its size should be explicitly specified) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.0.3Advisory · DecidablePDF example
The only declarations in the global namespace should be main, namespace declarations and extern "C" declarationsThe only declarations in the global namespace should be main, namespace declarations and extern "C" declarations
❌ 위반 예시Non-compliant example
void f1( int32_t ); // Non-compliant int32_t x1; // Non-compliant using namespace MY_API; // Non-compliant using MY_API::b2; // Non-compliant extern void f3(); // Non-compliant
✅ 준수 예시Compliant example
namespace // Compliant namespace MY_API // Compliant namespace MY = MY_API; // Compliant int main() // Compliant
⚠️ Rule 6.0.3 (The only declarations in the global namespace should be main, namespace declarations and extern "C" declarations)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.0.3 (The only declarations in the global namespace should be main, namespace declarations and extern "C" declarations) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.0.4Required · DecidablePDF example
The identifier main shall not be used for a function other than the global function mainThe identifier main shall not be used for a function other than the global function main
❌ 위반 예시Non-compliant example
int main() // Non-compliant int main() // Non-compliant
✅ 준수 예시Compliant example
int main() // Compliant
⚠️ Rule 6.0.4 (The identifier main shall not be used for a function other than the global function main)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.0.4 (The identifier main shall not be used for a function other than the global function main) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.2.1Required · DecidablePDF example
The one-definition rule shall not be violatedThe one-definition rule shall not be violated
❌ 위반 예시Non-compliant example
// File1.h
void f( int32_t i );
// File2.h
void f( int64_t i );
// File3.h
inline void h( int64_t i )
{
f( i ); // Nested call
}
// File1.cpp
#include "File1.h"
#include "File3.h"
void f1()
{
h( 42 ); // Nested call in h is to int32_t overload of f
}
// File2.cpp
#include "File2.h"
#include "File3.h"
void f2()
{
h( 42 ); // Nested call in h is to int64_t overload of f
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 6.2.1 (The one-definition rule shall not be violated)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.2.1 (The one-definition rule shall not be violated) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.2.2Required · DecidablePDF example
All declarations of a variable or function shall have the same typeAll declarations of a variable or function shall have the same type
❌ 위반 예시Non-compliant example
extern int32_t a; // Non-compliant - see b.cpp
extern char c; // Non-compliant - see b.cpp
int32_t f1(); // Non-compliant - see b.cpp
extern "C" int32_t f3( int32_t ); // Non-compliant
int32_t f4(); // Non-compliant - see b.cpp
extern int64_t a; // Non-compliant - see a.cpp
int16_t c; // Non-compliant - see a.cpp
char f1(); // Non-compliant - see a.cpp
extern "C" int32_t f3( char ); // Non-compliant
int32_t f4() noexcept; // Non-compliant - see a.cpp
extern "C" int32_t f3; // Non-compliant
int32_t f3; // Non-compliant✅ 준수 예시Compliant example
extern int32_t b []; // Compliant
extern int32_t d; // Compliant
extern myint e; // Compliant
int32_t f2( int32_t ); // Compliant
extern int32_t b [ 5 ]; // Compliant
int32_t d { 1 }; // Compliant
int32_t e; // Compliant
char f2( char ); // Compliant - not the same function as⚠️ Rule 6.2.2 (All declarations of a variable or function shall have the same type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.2.2 (All declarations of a variable or function shall have the same type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.2.3Required · DecidablePDF example
The source code used to implement an entity shall appear only onceThe source code used to implement an entity shall appear only once
❌ 위반 예시Non-compliant example
inline int16_t i = 10; // Non-compliant - two definitions of i
int16_t b; // Non-compliant - ill-formed (see file2.cpp)
int32_t b; // Non-compliant - ill-formed (see file1.cpp)
class A< int32_t > {}; // Non-compliant
struct wrap< V * > {} // Non-compliant - should be in wrap.h✅ 준수 예시Compliant example
class A< D > {}; // Compliant⚠️ Rule 6.2.3 (The source code used to implement an entity shall appear only once)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.2.3 (The source code used to implement an entity shall appear only once) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.2.4Required · DecidablePDF example
A header %le shall not contain definitions of functions or objects that are non-inline and have external linkageA header %le shall not contain definitions of functions or objects that are non-inline and have external linkage
❌ 위반 예시Non-compliant example
void f2() { } // Non-compliant
int32_t a; // Non-compliant✅ 준수 예시Compliant example
inline void f3() { } // Compliant
void f4( T ) { } // Compliant - implicitly inline
constexpr auto ans { 42 }; // Compliant - no external linkage
int32_t a; // Compliant - no linkage
int32_t b { 2 }; // Compliant - X::b has external linkage but is inline⚠️ Rule 6.2.4 (A header %le shall not contain definitions of functions or objects that are non-inline and have external linkage)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.2.4 (A header %le shall not contain definitions of functions or objects that are non-inline and have external linkage) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.4.1Required · DecidablePDF example
식별자는 가능한 가장 좁은 범위에서 선언한다An identifier declared in a block shall have a scope no larger than necessary
❌ 위반 예시Non-compliant example
auto L4 = [ z ](){ char z { 'a' }; }; // Non-compliant - captured z is hidden✅ 준수 예시Compliant example
auto L1 = [ z ](){ return z; }; // Compliant - no hiding
auto L2 = []( char z ){ return z; }; // Compliant - no hiding
auto L3 = [](){ char z { 'a' }; }; // Compliant - no hiding⚠️ 필요 이상으로 넓은 범위에 선언된 변수는 의도치 않은 재사용·상태 누출의 위험을 키우고, 반복 간에 이전 값이 남아 미묘한 버그를 만든다. 식별자는 사용 지점에 가장 가까운 가장 좁은 범위에 선언해 수명을 한정한다.A variable declared in a scope larger than necessary increases the risk of accidental reuse and state leakage, and leftover values across iterations cause subtle bugs. Declare identifiers in the narrowest scope nearest their use to bound their lifetime.
Rule 6.4.2Required · DecidablePDF example
Derived classes shall not conceal functions that are inherited from their basesDerived classes shall not conceal functions that are inherited from their bases
❌ 위반 예시Non-compliant example
// Non-compliant - Derived::f1 conceals Base::f1
// Non-compliant - Base::f4 is concealed
// Non-compliant - Base::f5( int32_t ) is concealed✅ 준수 예시Compliant example
// Compliant - does not conceal Base::operator=
// Compliant - Base::f2 is not concealed
// Compliant - Base::f3 is not concealed
void f1( float f ); // Compliant - Base inherited privately⚠️ Rule 6.4.2 (Derived classes shall not conceal functions that are inherited from their bases)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.4.2 (Derived classes shall not conceal functions that are inherited from their bases) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.4.3Required · DecidablePDF example
A name that is present in a dependent base shall not be resolved by unqualified lookupA name that is present in a dependent base shall not be resolved by unqualified lookup
❌ 위반 예시Non-compliant example
// Non-compliant for A< int32_t > - compiler will choose ::Type
// Non-compliant for A< int16_t > - compiler will choose ::Type
// Non-compliant for A< int32_t > - compiler will choose ::g
// Non-compliant for MyString<std::string> - compiler will choose ::value_type✅ 준수 예시Compliant example
// Compliant - compiler finds the name introduced by the using declaration
// Compliant for A< int16_t > - base B< int16_t > has no member g
::Type t1 = 0; // Compliant - explicit use of global Type
::g(); // Compliant - explicit use of global g
typename B< T >::Type t2 = 0; // Compliant - explicit use of base Type
// Compliant for A< int32_t > - uses base g⚠️ Rule 6.4.3 (A name that is present in a dependent base shall not be resolved by unqualified lookup)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.4.3 (A name that is present in a dependent base shall not be resolved by unqualified lookup) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.5.1Advisory · DecidablePDF example
A function or object with external linkage should be introduced in a header %leA function or object with external linkage should be introduced in a header %le
❌ 위반 예시Non-compliant example
int32_t a2 = 0; // Non-compliant - no declaration in header void f2() // Non-compliant - no declaration in header
✅ 준수 예시Compliant example
extern int32_t a1; // Compliant extern void f3(); // Compliant
⚠️ Rule 6.5.1 (A function or object with external linkage should be introduced in a header %le)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.5.1 (A function or object with external linkage should be introduced in a header %le) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.5.2Advisory · DecidablePDF example
Internal linkage should be specified appropriatelyInternal linkage should be specified appropriately
❌ 위반 예시Non-compliant example
static void f1(); // Non-compliant extern int32_t notExtern2; // Non-compliant
✅ 준수 예시Compliant example
void f2(); // Compliant
int32_t notExtern1; // Compliant⚠️ Rule 6.5.2 (Internal linkage should be specified appropriately)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.5.2 (Internal linkage should be specified appropriately) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.7.1Required · DecidablePDF example
지역 정적(local static) 객체를 신중히 사용한다(스레드 안전·초기화 순서)Local objects with static storage duration shall be used with care
❌ 위반 예시Non-compliant example
static int32_t b = 0; // Non-compliant
static Application app; // Non-compliant✅ 준수 예시Compliant example
int32_t ga = 0; // Compliant - but violates "See also"
int32_t a = 0; // Compliant
static constexpr int32_t c = 0; // Compliant
static const int32_t d = bar(); // Compliant⚠️ 함수 지역 정적 객체는 첫 호출 시 초기화되어 초기화 순서·스레드 안전(동시 첫 호출 경합)·암묵적 전역 상태 공유 문제를 코드 뒤에 숨긴다. 상태의 수명과 동기화를 명시적으로 설계하거나 의존성을 주입해 가시화한다.A function-local static is initialized on first call, hiding initialization-order, thread-safety (races on concurrent first call), and implicit global-state-sharing issues behind the code. Design the state’s lifetime and synchronization explicitly, or inject the dependency to make it visible.
Rule 6.7.2Required · DecidablePDF example
Global variables shall not be usedGlobal variables shall not be used
❌ 위반 예시Non-compliant example
int32_t foo();
int32_t i1 { foo() }; // Non-compliant
const int32_t i2 { i1 }; // Non-compliant - dynamic initialization
namespace
{
int32_t i3 { 0 }; // Non-compliant
constexpr int32_t bar()
{
return 42;
}
constexpr int32_t i4 { bar() }; // Rule does not apply - constexpr
const int32_t SIZE { 100 }; // Rule does not apply
} // - const without dynamic initialization
struct ComplexInit
{
ComplexInit();
};
const ComplexInit c1 {}; // Non-compliant - dynamic initialization⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 6.7.2 (Global variables shall not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.7.2 (Global variables shall not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.8.1Required · UndecidablePDF example
An object shall not be accessed outside of its lifetimeAn object shall not be accessed outside of its lifetime
❌ 위반 예시Non-compliant example
struct X
{
void doSomething() {}
};
void h( X * px )
{
px->~X(); // End the lifetime of *px
px->doSomething(); // Non-compliant
}
void g()
{
X a{};
auto & b = ( X{} = a ); // Immediate dangling of b
b.doSomething(); // Non-compliant
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 6.8.1 (An object shall not be accessed outside of its lifetime)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.8.1 (An object shall not be accessed outside of its lifetime) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.8.2Mandatory · UndecidablePDF example
수명이 끝난 객체에 대한 참조/포인터를 반환·사용하지 않는다A function shall not return a reference or a pointer to an object whose lifetime has ended
❌ 위반 예시Non-compliant example
int32_t * f1()
{
int32_t x = 99;
return &x; // Non-compliant
}
int32_t * f2( int32_t y )
{
return &y; // Non-compliant
}
int32_t & f3()
{
int32_t x = 99;
return x; // Non-compliant
}
int32_t & f4( int32_t y )
{
return y; // Non-compliant
}
int32_t & f5( int32_t & x )
{
return x; // Rule does not apply
}
int32_t * f6()
{
static int32_t x = 0;
return &x; // Rule does not apply
}
void f7()
{
int32_t x = 0;
throw &x; // Non-compliant
}
void f8()
{
try
{
int32_t x = 0;
throw &x; // Rule does not apply - caught within this function
}
catch ( ... )
{
}
}
auto f9()
{
int32_t x { 42 };
return [&x]() {}; // Non-compliant - captures local by reference
}✅ 준수 예시Compliant example
int32_t * f11()
{
int32_t i = 42;
int32_t * p = &i;
return p; // Compliant with this rule
}⚠️ 지역 객체의 참조·주소는 함수가 반환되면 수명이 끝나 무효가 되므로, 그것을 반환·보관해 사용하면 사라진 스택 객체를 가리키는 댕글링 접근(미정의 동작)이 된다. 값으로 반환하거나 수명이 보장된 객체(호출자 소유·동적 수명)를 가리키게 한다.A reference or address to a local object becomes invalid when the function returns, so returning or retaining and using it is a dangling access (undefined behaviour) to a vanished stack object. Return by value, or refer to an object with guaranteed lifetime (caller-owned or dynamic).
Rule 6.8.3Required · DecidablePDF example
An assignment operator shall not assign the address of an object with automatic storage duration to an object with a greater lifetimeAn assignment operator shall not assign the address of an object with automatic storage duration to an object with a greater lifetime
❌ 위반 예시Non-compliant example
void f1()
{
int8_t * p;
{
int8_t local;
int8_t local_array[ 10 ];
p = &local; // Non-compliant
p = local_array; // Non-compliant
}
}✅ 준수 예시Compliant example
void f2()
{
int8_t * p1;
{
int8_t * p2 = nullptr;
int8_t local;
p2 = &local; // Compliant - objects have the same lifetime
p1 = p2; // Rule does not apply
}
*p1 = 0; // Undefined behaviour
}⚠️ Rule 6.8.3 (An assignment operator shall not assign the address of an object with automatic storage duration to an object with a greater lifetime)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.8.3 (An assignment operator shall not assign the address of an object with automatic storage duration to an object with a greater lifetime) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.8.4Advisory · DecidablePDF example
Member functions returning references to their object should be ref- qualified appropriatelyMember functions returning references to their object should be ref- qualified appropriately
❌ 위반 예시Non-compliant example
A & getMe2() { return *this; } // Non-compliant - not ref-qualified
// A call to the non-compliant getMe2 on a temporary results in immediate dangling✅ 준수 예시Compliant example
struct Tmpl
{
template< typename T >
Tmpl const * f( T ) const & { return this; } // Non-compliant when instantiated
// for #3
void f( int32_t ) const && = delete; // #1
};
void bar( int32_t s32, int8_t s8 )
{
Tmpl tpl;
tpl.f( s32 ); // #2
tpl.f( s8 ); // #3
}⚠️ Rule 6.8.4 (Member functions returning references to their object should be ref- qualified appropriately)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.8.4 (Member functions returning references to their object should be ref- qualified appropriately) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.9.1Required · DecidablePDF example
The same type aliases shall be used in all declarations of the same entityThe same type aliases shall be used in all declarations of the same entity
❌ 위반 예시Non-compliant example
extern int32_t i; // Non-compliant void g( Index const i ); // Non-compliant - int32_t vs. Index
✅ 준수 예시Compliant example
extern INT j; // Compliant void h( Index const index ); // Compliant - Index used consistently
⚠️ Rule 6.9.1 (The same type aliases shall be used in all declarations of the same entity)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.9.1 (The same type aliases shall be used in all declarations of the same entity) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 6.9.2Advisory · DecidablePDF example
The names of the standard signed integer types and standard unsigned integer types should not be usedThe names of the standard signed integer types and standard unsigned integer types should not be used
❌ 위반 예시Non-compliant example
int x = 0; // Non-compliant - use of int
✅ 준수 예시Compliant example
int32_t y = 0; // Compliant
int_least32_t z = 0; // Compliant
using torque_t = int; // Compliant by exception #1
C operator++( int ); // Compliant by exception #2.1
int main() { } // Compliant by exception #2.2
int main( int argc, char * argv[] ) { } // Compliant by exception #2.2 and #2.3⚠️ Rule 6.9.2 (The names of the standard signed integer types and standard unsigned integer types should not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 6.9.2 (The names of the standard signed integer types and standard unsigned integer types should not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
M7섹션 7Section 7
Rule 7.0.1Required · DecidablePDF example
There shall be no conversion from type boolThere shall be no conversion from type bool
❌ 위반 예시Non-compliant example
if ( b1 & b2 ) // Non-compliant - b1 and b2 converted to int if ( b1 < b2 ) // Non-compliant - b1 and b2 converted to int if ( ~b1 ) // Non-compliant - b1 converted to int if ( b1 ^ b2 ) // Non-compliant - b1 and b2 converted to int if ( b1 == 0 ) // Non-compliant - b1 converted to int double result = d1 * b1; // Non-compliant - b1 converted to double s8a = static_cast< int8_t >( b1 ); // Non-compliant - b1 converted to int8_t f( b ); // Non-compliant - b converted to int32_t switch ( b ) // Non-compliant - b converted to int
✅ 준수 예시Compliant example
if ( b1 == false ) // Compliant - Boolean operands to equality
if ( b1 == b2 ) // Compliant - Boolean operands to equality
if ( b1 != b2 ) // Compliant - Boolean operands to equality
if ( b1 && b2 ) // Compliant - no conversion from bool
if ( !b1 ) // Compliant - no conversion from bool
s8a = b1 ? 3 : 7; // Compliant - no conversion from bool
f( b ? 1 : 0 ); // Compliant - no conversion from bool
A anA { true }; // Compliant - constructor
anA = A { false }; // Compliant - explicit cast calls constructor⚠️ Rule 7.0.1 (There shall be no conversion from type bool)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 7.0.1 (There shall be no conversion from type bool) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 7.0.2Required · DecidablePDF example
조건 문맥에는 본질적으로 bool 인 표현식을 사용한다The operand of an explicit or implicit conversion to bool shall be of essentially Boolean type
❌ 위반 예시Non-compliant example
if ( ( u8a < u8b ) && ( u8c + u8d ) ) // Non-compliant if ( 1 && ( u8c < u8d ) ) // Non-compliant if ( u8a && ( u8c < u8d ) ) // Non-compliant if ( !0 ) // Non-compliant s32a = s16a ? s32b : s32c; // Non-compliant if ( int32_t i2 = fn() ) // Non-compliant for ( int32_t x = 10; x; --x ) // Non-compliant bool b2 = getptr(); // Non-compliant if ( int32_t i = fn(); i ) // Non-compliant - condition has type of 'i' if ( int32_t i = fn() ) // Non-compliant if ( u8 ) // Non-compliant bool b1 = static_cast< bool >( 4 ); // Non-compliant
✅ 준수 예시Compliant example
if ( ( u8a < u8b ) && ( u8c < u8d ) ) // Compliant if ( true && ( u8c < u8d ) ) // Compliant if ( !false ) // Compliant s32a = b1 ? s32b : s32c; // Compliant s32a = ( s16a < 5 ) ? s32b : s32c; // Compliant while ( int32_t i1 = fn() ) // Compliant by exception #4 if ( int32_t i3 = fn() ; i3 != 0) // Compliant version of the above line while ( std::cin ) // Compliant by exception #2 - std::istream if ( getptr() ) // Compliant by exception #2 - contextual bool b3 = getptr() != nullptr; // Compliant if ( bool b4 = fb() ) // Compliant if ( int32_t i = fn(); i != 0 ) // Compliant bool b2 = static_cast< bool >( c ); // Compliant by exception #1 if ( c ) // Compliant by exception #2 - contextual
⚠️ 포인터나 정수를 그대로 조건에 쓰면 "널이 아님/0이 아님" 이라는 비교가 암묵화되어 의도가 모호해지고, 비교 대상을 잘못 가정하는 결함을 부른다. p != nullptr, n != 0 처럼 명시적 비교로 본질적 bool 표현식을 만든다.Using a pointer or integer directly as a condition hides the implicit "not null / not zero" comparison, obscuring intent and inviting wrong assumptions about what is tested. Build an essentially Boolean expression with explicit comparisons such as p != nullptr or n != 0.
Rule 7.0.3Required · DecidablePDF example
The numerical value of a character shall not be usedThe numerical value of a character shall not be used
❌ 위반 예시Non-compliant example
char c = 10; // Non-compliant - implicit conversion from int to char
int8_t d = 'a'; // Non-compliant
uint8_t e = '\r'; // Non-compliant
char g = L'Æ'; // Non-compliant - conversion between character types
char h = a - '0'; // Non-compliant - promotion to int, conversion to char
if ( g && h ) // Non-compliant - two conversions to bool
auto i = static_cast< CT::int_type >( 'a' ); // Non-compliant - explicitly
if ( ( a >= '0' ) && ( a <= '9' ) ) // Non-compliant - promotion to int
if ( 0 == std::isdigit( a ) ) // Non-compliant - conversion to int
char c1 = i; // Non-compliant - int to char✅ 준수 예시Compliant example
if ( !CT::lt( a, '0' ) && !CT::lt( '9', a ) ) // Compliant version of the above
if ( std::isdigit( a, std::locale {} ) ) // Compliant version of the above
char c2 = CT::to_char_type( i ); // Compliant version of the above⚠️ Rule 7.0.3 (The numerical value of a character shall not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 7.0.3 (The numerical value of a character shall not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 7.0.4Required · DecidablePDF example
The operands of bitwise operators and shift operators shall be appropriateThe operands of bitwise operators and shift operators shall be appropriate
❌ 위반 예시Non-compliant example
s32 << 2; // Non-compliant - left operand is signed 1 << u8; // Non-compliant - left operand is signed ( u8 + u16 ) << 2; // Non-compliant - result of + is signed 2 << 30; // Non-compliant - exception does not s32a | s32b; // Non-compliant - signed operands ~s32; // Non-compliant - signed operand
✅ 준수 예시Compliant example
1u << u8; // Compliant 1u << 31; // Compliant 1_u8 << 2; // Compliant - but violates other rules u8 << 2; // Compliant - but violates other rules static_cast< uint16_t >( u8 + u16 ) << 2; // Compliant 1LL << 31; // Compliant by exception 1 << 30; // Compliant by exception u32a | u32b; // Compliant ~u32; // Compliant ~u8; // Compliant - but violates other rules
⚠️ Rule 7.0.4 (The operands of bitwise operators and shift operators shall be appropriate)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 7.0.4 (The operands of bitwise operators and shift operators shall be appropriate) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 7.0.5Required · DecidablePDF example
암시적 정수 변환이 값을 손실하거나 부호를 바꾸지 않게 한다Integer conversions shall not lose information or change signedness unexpectedly
❌ 위반 예시Non-compliant example
u8a += u8b // Non-compliant - same as u8a + u8b s32 > u32 // Non-compliant - s32 -> unsigned int f32 += u32 // Non-compliant - u32 -> floating ~u8 // Non-compliant - u8 -> signed int -u8 // Non-compliant - u8 -> signed int u8 << 2 // Non-compliant - u8 -> signed int
✅ 준수 예시Compliant example
static_cast< uint32_t >( u8a ) + u8b // Compliant - u8b -> unsigned int u8a += static_cast< uint32_t >( u8b ) // Compliant - u8a -> unsigned int s32 * s8 // Compliant - s8 -> signed int u32 / u8 // Compliant - u8 -> unsigned int u32a - 1 // Compliant by exception #1 f32 += 1 // Compliant by exception #2 f32 += 0x100'0001 // Compliant by exception #2 - precision lost ~u32 // Compliant u8 + fn( 10 ) // Compliant by exception #1 f32 + fn( 10 ) // Compliant by exception #2
⚠️ 넓은 정수를 좁은 타입으로 암시 변환하면 상위 비트가 잘리거나 부호 있는/없는 변환으로 값이 바뀌어, 의도와 다른 값이 조용히 저장된다. 변환 전 범위를 검사하고 static_cast 로 명시적으로 변환해 손실 가능성을 드러낸다.Implicitly converting a wide integer to a narrower type truncates high bits or changes the value through signed/unsigned conversion, silently storing the wrong value. Check the range before converting and use static_cast to make the conversion — and its potential loss — explicit.
Rule 7.0.6Required · DecidablePDF example
Assignment between numeric types shall be appropriateAssignment between numeric types shall be appropriate
❌ 위반 예시Non-compliant example
u8 = 300u; // Non-compliant - value does not fit
s.b = 32u; // Non-compliant - value does not fit
s.b = u16; // Non-compliant - narrowing
sb1( s.b ); // Non-compliant - s.b considered to be uint8_t,
u8 = c; // Non-compliant - different sizes (narrowing)
u8 = s8; // Non-compliant - different signedness
u8 = u8 + u8; // Non-compliant - change of sign and narrowing
flt1 = s32; // Non-compliant - different type category
flt2 = 0.0; // Non-compliant - different sizes and not an
int16_t val4 { s8 + s8 }; // Non-compliant - narrowing, as s8 + s8 is int
case 0xFFFF'FFFF'FFFF: // Non-compliant - value does not fit in int8_t
f1( s32 + s32 ); // Non-compliant - implicit widening conversion
f2( s32 + s64 ); // Non-compliant - implicit narrowing conversion
A a { s16 }; // Non-compliant
f3( 2 ); // Non-compliant - implicit conversion from int to
log( "f( %c )", c ); // Non-compliant - conversion of c from uint8_t
set( 42, "answer" ); // Non-compliant - even though this non-qualified
b.set( 42, "answer" ); // Non-compliant - conversion from int to long not
s16 + s16, // Non-compliant - widening from int
a.set2< size_t >( 42, "X" ); // Non-compliant - 'S1' is never the same as✅ 준수 예시Compliant example
u32 = 1; // Compliant
s32 = 4u * 2u; // Compliant
u8 = 3u; // Compliant
u8 = 3_u8; // Compliant
s.b = 2; // Compliant
s.b = u8; // Compliant - same width, but may truncate
sb2( s.b ); // Compliant
u8 = red; // Compliant - value can be represented
u32 = red; // Compliant - value can be represented
u32 = c; // Compliant - widening of id-expression
unsigned int ui = ul; // Compliant - if sizes are equal
flt3 = 0.0f; // Compliant
flt4 = 1; // Compliant
flt5 = 9999999999; // Compliant - loss of precision is possible
int16_t val1 = s8; // Compliant
int16_t val2 { s8 }; // Compliant
int16_t val3 ( s8 ); // Compliant
case 1: // Compliant
return s8; // Compliant - widening of id-expression
return s8 + s8; // Compliant - s8 + s8 is of type int
f2( s16 + s16 ); // Compliant - result of addition is int
fp( 2 ); // Compliant - calling through function pointer is
f4( MyInt { s } ); // Compliant by exception - no need to cast s
MyInt i { s }; // Compliant by exception - no need to cast s
a.set( 42, "answer" ); // Compliant - size_t can represent 42, and it is
s16 + s16, // Compliant - s16 + s16 is of type int
s16 // Compliant - widening of id-expression
a.set1( 42, "X" ); // Compliant - size_t is same type⚠️ Rule 7.0.6 (Assignment between numeric types shall be appropriate)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 7.0.6 (Assignment between numeric types shall be appropriate) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 7.11.1Required · DecidablePDF example
널 포인터 상수로는 nullptr 만 사용한다nullptr shall be the only form of the null pointer constant
❌ 위반 예시Non-compliant example
#define MYNULL NULL // Non-compliant
void f5()
{
int32_t one = NULL + 1; // Non-compliant - NULL used as an integer
throw NULL; // Non-compliant - caught by catch ( int )
}✅ 준수 예시Compliant example
f1( nullptr ); // Compliant
⚠️ 0 이나 NULL 을 널 포인터로 쓰면 정수와 포인터 문맥이 섞여, 정수 오버로드와 포인터 오버로드 중 잘못된 쪽이 선택되는 오버로드 해석 오류를 부르고 가독성도 떨어진다. C++ 에서는 타입이 포인터로 고정된 nullptr 만 사용한다.Using 0 or NULL as a null pointer mixes integer and pointer contexts, causing overload-resolution errors where an integer overload is chosen over a pointer one, and hurts readability. In C++, use only nullptr, whose type is fixed as a pointer.
Rule 7.11.2Required · DecidablePDF example
An array passed as a function argument shall not decay to a pointerAn array passed as a function argument shall not decay to a pointer
❌ 위반 예시Non-compliant example
f1( a ); // Non-compliant - dimension lost due to array to pointer conversion f2( a ); // Non-compliant - dimension lost due to array to pointer conversion log( msg ); // Non-compliant - not a literal
✅ 준수 예시Compliant example
f3( a ); // Compliant - dimension of 10 matches that of the parameter f4( a ); // Compliant - dimension deduced to be 10 log( "Hello" ); // Compliant by exception string_view msg2 = "Hello"sv; // Compliant by exception - the literal operator
⚠️ Rule 7.11.2 (An array passed as a function argument shall not decay to a pointer)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 7.11.2 (An array passed as a function argument shall not decay to a pointer) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 7.11.3Required · DecidablePDF example
A conversion from function type to pointer-to-function type shall only occur in appropriate contextsA conversion from function type to pointer-to-function type shall only occur in appropriate contexts
❌ 위반 예시Non-compliant example
if ( f == nullptr ) // Non-compliant
<< f; // Non-compliant - assignment is not to
auto x = +f; // Non-compliant
auto x = +lam; // Non-compliant
if ( lam ) // Non-compliant✅ 준수 예시Compliant example
if ( &f != nullptr ) // Compliant - no conversion (f)(); // Compliant - no conversion std::cout << std::boolalpha // Compliant - assignment to pointer-to-function type auto selected = static_cast< void(*)( uint32_t ) >( f1 ); // Compliant void ( *p )() = lam; // Compliant
⚠️ Rule 7.11.3 (A conversion from function type to pointer-to-function type shall only occur in appropriate contexts)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 7.11.3 (A conversion from function type to pointer-to-function type shall only occur in appropriate contexts) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
M8섹션 8Section 8
Rule 8.0.1Required · DecidablePDF example
연산자 우선순위는 괄호로 명시한다Parentheses should be used to make the meaning of an expression appropriately explicit
❌ 위반 예시Non-compliant example
sizeof x + y; // Non-compliant - write either sizeof ( x ) + y x = a == b ? a : a - b; // Non-compliant - operands of conditional operator x = a << b + c; // Non-compliant - operands of << operator a && b || c; // Non-compliant - || (ranking 4) has operand && (ranking 5) a || b && c; // Non-compliant - || (ranking 4) has operand && (ranking 5) #if defined( A ) && defined( B ) || defined( C ) // Non-compliant
✅ 준수 예시Compliant example
a[ i ]->n; // Compliant - no need to write ( a[ i ] )->n *p++; // Compliant - no need to write *( p++ ) a + b - c + d; // Compliant ( a + b ) - ( c + d ); // Compliant - produces a different result x = f ( a + b, c ); // Compliant - no need to write f ( ( a + b ), c ) x = ( a == b ) ? a : ( a - b ); // Compliant version of previous example a && b && c; // Compliant - all operators are the same. a || b || c; // Compliant - all operators are the same
⚠️ 시프트·비트·산술 연산이 섞인 식은 우선순위를 사람이 오해하기 쉬워, 작성자의 의도와 컴파일러의 해석이 어긋난다. 괄호로 평가 순서를 분명히 하면 의도가 코드에 드러나고 검토 오류가 줄어든다.Expressions mixing shift, bitwise, and arithmetic operators are easy for humans to misread on precedence, so the author’s intent and the compiler’s interpretation diverge. Parentheses make the evaluation order explicit, surfacing intent and reducing review errors.
Rule 8.1.1Required · DecidablePDF example
A non-transient lambda shall not implicitly capture thisA non-transient lambda shall not implicitly capture this
❌ 위반 예시Non-compliant example
auto a1 = [=]() // Non-compliant - val is not captured, but
auto a2 = [&]() // Non-compliant - val is not captured, but✅ 준수 예시Compliant example
auto a3 = [this]() // Compliant - 'this' explicitly captured
auto a4 = [self = *this]() // Compliant - current object captured by copy⚠️ Rule 8.1.1 (A non-transient lambda shall not implicitly capture this)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.1.1 (A non-transient lambda shall not implicitly capture this) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.1.2Advisory · DecidablePDF example
Variables should be captured explicitly in a non-transient lambdaVariables should be captured explicitly in a non-transient lambda
❌ 위반 예시Non-compliant example
}; // Non-compliant
process( [&](){ return s; } ); // Non-compliant - conversion to
return [=]() { return s; }; // Non-compliant - implicit capture
s.addObserver( [&]( double speed ) // Non-compliant - implicit capture✅ 준수 예시Compliant example
}(); // Compliant - called immediately
[&]( size_t elem ) { return elem == i; } ); // Compliant
[&]( size_t elem ) { return elem == i; } ); // Compliant
s.addObserver( [&os]( double speed ) // Compliant - explicit capture
s.addObserver( []( double speed ) // Compliant - no capture⚠️ Rule 8.1.2 (Variables should be captured explicitly in a non-transient lambda)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.1.2 (Variables should be captured explicitly in a non-transient lambda) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.2.1Required · DecidablePDF example
A virtual base class shall only be cast to a derived class by means of dynamic_castA virtual base class shall only be cast to a derived class by means of dynamic_cast
❌ 위반 예시Non-compliant example
D * pD1 = reinterpret_cast< D * >( pB ); // Non-compliant
✅ 준수 예시Compliant example
D * pD2 = dynamic_cast< D * >( pB ); // Compliant - pD2 may be null D & D3 = dynamic_cast< D & >( *pB ); // Compliant - may throw an exception
⚠️ Rule 8.2.1 (A virtual base class shall only be cast to a derived class by means of dynamic_cast)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.2.1 (A virtual base class shall only be cast to a derived class by means of dynamic_cast) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.2.2Required · DecidablePDF example
C 스타일 캐스트를 사용하지 않는다C-style casts and functional notation casts shall not be used
❌ 위반 예시Non-compliant example
struct A
{
A( char c);
};
struct B {};
void f1a( A x )
{
auto const & a1 = x;
A * a2 = ( A * )&a1; // Non-compliant
A * a3 = const_cast< A * >( &a1 );
}✅ 준수 예시Compliant example
int32_t g();
void f1()
{
( void ) g(); // Compliant by exception
}⚠️ C 스타일 캐스트 (int)d 는 static_cast·const_cast·reinterpret_cast 중 무엇을 수행하는지 드러나지 않아, const 제거나 위험한 재해석 같은 의도를 숨기고 검색·검토를 어렵게 한다. 의도를 명시하는 C++ 캐스트(static_cast 등)를 사용한다.A C-style cast (int)d does not reveal whether it performs static_cast, const_cast, or reinterpret_cast, hiding intent such as const removal or dangerous reinterpretation and making it hard to search and review. Use the C++ casts that state intent (static_cast, etc.).
Rule 8.2.3Required · DecidablePDF example
캐스트로 const/volatile 한정을 제거하지 않는다A cast shall not remove any const or volatile qualification from the type of a pointer or reference
❌ 위반 예시Non-compliant example
uint16_t x;
uint16_t * const cpi = &x; // const pointer
uint16_t * const * pcpi; // pointer to const pointer
uint16_t * * ppi;
const uint16_t * pci; // pointer to const
volatile uint16_t * pvi; // pointer to volatile
uint16_t * pi;
pi = cpi; // Rule does not apply - no cast
pi = const_cast< uint16_t * >( pci ); // Non-compliant
pi = const_cast< uint16_t * >( pvi ); // Non-compliant
ppi = const_cast< uint16_t ** >( pcpi ); // Non-compliant✅ 준수 예시Compliant example
#include <iostream>
static void set(int& v, int x){ v = x; } // 수정이 필요하면 비-const 인터페이스
int main(){
int v = 7;
set(v, 9);
std::cout << v << '\n';
}⚠️ const_cast 로 한정을 떼어내고 실제로 const 로 선언된 객체를 수정하면 미정의 동작이 되고, 컴파일러의 const 최적화 가정을 깨뜨려 예측 불가한 결과를 만든다. 수정이 필요한 대상은 처음부터 비-const 인터페이스로 다루고 const 한정을 제거하지 않는다.Casting away qualifiers with const_cast and then modifying an object actually declared const is undefined behaviour and breaks the compiler’s const-based optimization assumptions, yielding unpredictable results. Handle objects that must be modified through a non-const interface from the start and do not strip const.
Rule 8.2.4Required · DecidablePDF example
Casts shall not be performed between a pointer to function and any other typeCasts shall not be performed between a pointer to function and any other type
❌ 위반 예시Non-compliant example
pf32_t p2 = reinterpret_cast< pf32_t >( p1 ); // Non-compliant - function pointer pf16_t p3 = ( pf16_t ) 0x8000; // Non-compliant pf16_t p4 = reinterpret_cast< pf16_t >( 0xdeadbeef ); // Non-compliant int16_t * p5 = reinterpret_cast< int16_t * >( p4 ); // Non-compliant auto pm1 = static_cast< void ( B::* )() >( &A::foo ); // Non-compliant auto pm2 = static_cast< int32_t ( B::* ) >( &A::i ); // Non-compliant
✅ 준수 예시Compliant example
pf16_t p1 = static_cast< pf16_t >( nullptr ); // Compliant - cast is equivalent ( void ) getPf16(); // Compliant by exception f6( static_cast< void (*)() >( f5 ) ); // Compliant - overload selection
⚠️ Rule 8.2.4 (Casts shall not be performed between a pointer to function and any other type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.2.4 (Casts shall not be performed between a pointer to function and any other type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.2.5Required · DecidablePDF example
reinterpret_cast 를 사용하지 않는다reinterpret_cast shall not be used
❌ 위반 예시Non-compliant example
uint8_t * p1;
uint32_t * p2;
p2 = reinterpret_cast< uint32_t * >( p1 ); // Non-compliant
extern uint32_t read_value();
extern void print( uint32_t n );
void f()
{
uint32_t u = read_value();
uint16_t * p3 = reinterpret_cast< uint16_t * >( &u ); // Non-compliant
}
void g()
{
std::array< int32_t, 2 > a{};
auto p4 = reinterpret_cast< int32_t(*)[ 2 ]>( a.data() ); // Non-compliant
( *p4 )[ 0 ] = 42; // Undefined behaviour
}✅ 준수 예시Compliant example
void h( float x )
{
auto p5 = reinterpret_cast< std::byte const * >( &x ); // Compliant by exception
auto p6 = reinterpret_cast< std::uintptr_t >( &x ); // Compliant by exception
auto p7 = reinterpret_cast< uint64_t >( &x ); // Compliant by exception
}⚠️ reinterpret_cast 로 한 타입의 객체를 다른 타입으로 재해석해 접근하면 엄격 별칭(strict aliasing)과 정렬 규칙을 어겨 미정의 동작이 되고, 최적화 시 예측 불가한 결과가 나온다. 비트 패턴 재해석은 std::memcpy(또는 C++20 std::bit_cast)로 안전하게 수행한다.Reinterpreting an object of one type as another via reinterpret_cast and accessing it violates strict aliasing and alignment rules — undefined behaviour with unpredictable results under optimization. Reinterpret bit patterns safely with std::memcpy (or std::bit_cast in C++20).
Rule 8.2.6Required · DecidablePDF example
An object with integral, enumerated, or pointer to void type shall not be cast to a pointer typeAn object with integral, enumerated, or pointer to void type shall not be cast to a pointer type
❌ 위반 예시Non-compliant example
S * s1 = static_cast< S * >( p1 ); // Non-compliant
S * s2 = reinterpret_cast< S * >( i ); // Non-compliant
void * p2 = reinterpret_cast< void * >( i ); // Non-compliant✅ 준수 예시Compliant example
auto p3 = const_cast< void const * >( p2 ); // Compliant
⚠️ Rule 8.2.6 (An object with integral, enumerated, or pointer to void type shall not be cast to a pointer type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.2.6 (An object with integral, enumerated, or pointer to void type shall not be cast to a pointer type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.2.7Advisory · DecidablePDF example
A cast should not convert a pointer type to an integral typeA cast should not convert a pointer type to an integral type
❌ 위반 예시Non-compliant example
struct S;
void f( S * s )
{
std::intptr_t p = reinterpret_cast< std::intptr_t >( s ); // Non-compliant
std::uint8_t q = reinterpret_cast< std::uint8_t >( s ); // Non-compliant
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 8.2.7 (A cast should not convert a pointer type to an integral type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.2.7 (A cast should not convert a pointer type to an integral type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.2.8Required · DecidablePDF example
An object pointer type shall not be cast to an integral type other than std::uintptr_t or std::intptr_tAn object pointer type shall not be cast to an integral type other than std::uintptr_t or std::intptr_t
❌ 위반 예시Non-compliant example
auto p1 = reinterpret_cast< unsigned long >( s ); // Non-compliant auto p2 = reinterpret_cast< hashPtr_t >( s ); // Non-compliant auto p = reinterpret_cast< T >( s ); // Non-compliant - T is not explicitly
✅ 준수 예시Compliant example
auto p0 = reinterpret_cast< std::uintptr_t >( s ); // Compliant
⚠️ Rule 8.2.8 (An object pointer type shall not be cast to an integral type other than std::uintptr_t or std::intptr_t)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.2.8 (An object pointer type shall not be cast to an integral type other than std::uintptr_t or std::intptr_t) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.2.9Required · DecidablePDF example
The operand to typeid shall not be an expression of polymorphic class typeThe operand to typeid shall not be an expression of polymorphic class type
❌ 위반 예시Non-compliant example
return typeid( *p ); // Non-compliant return typeid( p ); // Non-compliant
✅ 준수 예시Compliant example
return typeid( *s ); // Compliant return typeid( p->foo() ); // Compliant - type is always 'void'
⚠️ Rule 8.2.9 (The operand to typeid shall not be an expression of polymorphic class type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.2.9 (The operand to typeid shall not be an expression of polymorphic class type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.2.10Required · DecidablePDF example
함수를 정의되지 않은 시그니처로 호출하지 않는다Functions shall not be called through a pointer of an incompatible function type
❌ 위반 예시Non-compliant example
x = x * fn( x - 1 ); // Non-compliant
x = x * fn_3( x - 1 ); // Non-compliant
x = x * fn_2( x - 1 ); // Non-compliant
x = x * fn_5( x - 1 ); // Non-compliant✅ 준수 예시Compliant example
x = x * fn_4( x - 1 ); // Compliant by exception return t + Sum( vals ... ); // Compliant - calls a different overload
⚠️ 함수를 실제 정의와 다른 시그니처의 포인터로 호출하면 인자·반환값 전달 규약이 어긋나 스택·레지스터가 오염되는 미정의 동작이 된다. 함수 포인터는 대상 함수의 정확한 타입으로 선언하고 그 시그니처대로 호출한다.Calling a function through a pointer with a signature different from its real definition mismatches the argument/return calling convention, corrupting the stack and registers — undefined behaviour. Declare function pointers with the target function’s exact type and call them according to that signature.
Rule 8.2.11Required · DecidablePDF example
An argument passed via ellipsis shall have an appropriate typeAn argument passed via ellipsis shall have an appropriate type
❌ 위반 예시Non-compliant example
struct A
{
int i { 42 };
virtual ~A() = default;
};
void f()
{
std::printf ( "hello %d", A{} ); // Non-compliant
}✅ 준수 예시Compliant example
struct two { char x[2]; };
two test( int );
char test( ... );
template< typename T >
constexpr bool isIntCompatible( T x )
{
if constexpr ( sizeof( test( x ) ) == 1 ) // Compliant - unevaluated context
{
return false; // Overload resolution -> test( ... )
}⚠️ Rule 8.2.11 (An argument passed via ellipsis shall have an appropriate type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.2.11 (An argument passed via ellipsis shall have an appropriate type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.3.1Required · DecidablePDF example
시프트 횟수는 0 이상이며 피연산자 비트폭 미만이어야 한다The right operand of a shift operator shall lie between zero and one less than the width in bits of the left operand
❌ 위반 예시Non-compliant example
void f( int32_t a );
void f( uint32_t a );
void g( uint32_t x, uint16_t y )
{
f( -x ); // Non-compliant - calls f( uint32_t a )
f( -y ); // Non-compliant - calls f( int32_t a )
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstdint>
int main(){
std::uint32_t v = 1;
unsigned n = 40;
if (n < 32u) { // 0..31 범위 보장
auto r = v << n;
std::cout << r << '\n';
} else {
std::cout << "shift out of range\n";
}
}⚠️ 피연산자의 비트폭 이상으로, 또는 음수로 시프트하면 결과가 미정의가 되어 0·원값·쓰레기 등 플랫폼마다 다르게 동작한다. 시프트량을 0..(폭-1) 범위로 검증한 뒤에만 시프트한다.Shifting by the operand width or more, or by a negative amount, is undefined behaviour that yields 0, the original, or garbage depending on the platform. Validate the shift amount to the range 0..(width-1) before shifting.
Rule 8.3.2Advisory · DecidablePDF example
The built-in unary + operator should not be usedThe built-in unary + operator should not be used
❌ 위반 예시Non-compliant example
auto x = + u8a; // Non-compliant - triggers promotion to int
auto pf = +[](){}; // Non-compliant - pf is a void(*)()
x = +1; // Non-compliant
x =+ 1; // Non-compliant - unary +, not +=
enum A : uint8_t { one };
enum B : uint8_t { two };
uint8_t operator+( B b ) { return b; }
auto a = +one; // Non-compliant
auto b = +two; // Rule does not apply
auto c = operator+( two ); // Rule does not apply⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 8.3.2 (The built-in unary + operator should not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.3.2 (The built-in unary + operator should not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.7.1Required · UndecidablePDF example
포인터 산술 결과는 같은 배열의 범위 안을 가리켜야 한다A pointer operand and any pointer resulting from pointer arithmetic shall address an element of the same array
❌ 위반 예시Non-compliant example
int32_t * p3 = a1 + 11; // Non-compliant - points to two beyond, resulting
a1[ -1 ] = 0; // Non-compliant - exceeding array bounds results
i = a2[ 2 ][ 3 ]; // Non-compliant - exceeding array bounds results
++p; // Non-compliant - more than one past the end
p = p + 3; // Non-compliant - more than one past the end
if ( std::memcmp( buf1, buf2, 7 ) == 0 ) {} // Non-compliant
auto p2 = std::next( buf1, 7 ); // Non-compliant✅ 준수 예시Compliant example
a1[ 3 ] = 0; // Compliant only if the array pointed
*( a2 + 9 ) = 0; // Compliant only if the array pointed
return a3 + 9; // Compliant
int32_t * p1 = &a1[ 0 ]; // Compliant
int32_t * p2 = a1 + 10; // Compliant - points to one beyond and
p1++; // Compliant
i = *( &i + 0 ); // Compliant - 'i' is treated as an array
a2[ 3 ][ 1 ] = 0; // Compliant
i = *( *( a2 + 3 ) + 1 ); // Compliant
int32_t * p4 = a2[ 1 ]; // Compliant
i = p4[ 1 ]; // Compliant - p4 addresses an array of size 2
++p; // Compliant - p points one past the end of s.x,
p = &s.a[ 0 ]; // Compliant - p points into s.a
p = p + 8; // Compliant - p still points into s.a
if ( std::memcmp( buf1, buf2, 5 ) == 0 ) {} // Compliant
auto p1 = std::next( buf1, 3 ); // Compliant⚠️ 배열 경계를 벗어난 포인터를 만들어 역참조하면 인접 메모리를 침범하는 미정의 동작이 되어 데이터 손상·보안 결함으로 이어진다. 인덱스를 사용 전에 [0, 길이) 범위로 검증해 항상 같은 배열 안을 가리키는 접근만 수행한다.Forming and dereferencing a pointer past an array’s bounds is undefined behaviour that intrudes on adjacent memory, causing corruption or security defects. Validate the index against [0, length) before use so accesses stay within the same array.
Rule 8.7.2Required · UndecidablePDF example
관계 연산은 같은 배열/객체를 가리키는 포인터끼리만 한다The relational operators shall not be applied to pointers that do not address elements of the same array
❌ 위반 예시Non-compliant example
ptrdiff_t diff3 = p1 - p2; // Non-compliant ptrdiff_t diff4 = ptr - p1; // Non-compliant
✅ 준수 예시Compliant example
ptrdiff_t diff1 = p1 - a1; // Compliant ptrdiff_t diff2 = p2 - a2; // Compliant
⚠️ 서로 다른 객체·배열을 가리키는 포인터의 대소 비교 결과는 표준이 보장하지 않아 미정의이며, 메모리 배치 가정에 의존한 코드는 플랫폼마다 다르게 동작한다. 같은 배열 내 포인터끼리 비교하거나 인덱스로 비교한다.Relational comparison of pointers to different objects or arrays is undefined, so code relying on memory-layout assumptions behaves differently across platforms. Compare pointers within the same array, or compare indices instead.
Rule 8.9.1Required · UndecidablePDF example
The built-in relational operators >, >=, < and <= shall not be applied to objects of pointer type, except where they point to elements of the same arrayThe built-in relational operators >, >=, < and <= shall not be applied to objects of pointer type, except where they point to elements of the same array
❌ 위반 예시Non-compliant example
if ( p1 < a2 ) {} // Non-compliant
if ( &x.m1 <= &x.m2 ) {} // Non-compliant - m1 and m2 are not array elements✅ 준수 예시Compliant example
if ( p1 < a1 ) {} // Compliant
if ( p1 < std::end( a1 ) ) {} // Compliant - right operand is one beyond
if ( std::less<>{}( p1, a2 ) ) { } // Compliant⚠️ Rule 8.9.1 (The built-in relational operators >, >=, < and <= shall not be applied to objects of pointer type, except where they point to elements of the same array)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.9.1 (The built-in relational operators >, >=, < and <= shall not be applied to objects of pointer type, except where they point to elements of the same array) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.14.1Advisory · UndecidablePDF example
The right-hand operand of a logical && or || operator should not contain persistent side eAectsThe right-hand operand of a logical && or || operator should not contain persistent side eAects
❌ 위반 예시Non-compliant example
if ( ishigh && ( a == h( x ) ) ) // Non-compliant - h() has a persistent if ( ( x == 0u ) || ( v == 1u ) ) // Non-compliant - access to volatile v ( fp != nullptr ) && ( *fp )( 0 ); // Non-compliant if fp points to a function
✅ 준수 예시Compliant example
if ( ishigh && ( a == f( x ) ) ) // Compliant - f() has no persistent ( *fp )( 0 ); // Compliant version of the above
⚠️ Rule 8.14.1 (The right-hand operand of a logical && or || operator should not contain persistent side eAects)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.14.1 (The right-hand operand of a logical && or || operator should not contain persistent side eAects) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.18.1Mandatory · UndecidablePDF example
겹치는(overlapping) 객체에 대입/복사하지 않는다An object shall not be assigned or copied to an overlapping object
❌ 위반 예시Non-compliant example
a.j = a.i; // Non-compliant memcpy ( &a[ 0 ], &a[ 1 ], 10u * sizeof ( a[ 0 ] ) ); // Non-compliant memcpy ( &a[ 1 ], &a[ 0 ], 10u * sizeof ( a[ 0 ] ) ); // Non-compliant
✅ 준수 예시Compliant example
memcpy ( &a[ 0 ], &a[ 5 ], 5u * sizeof ( a[ 0 ] ) ); // Compliant - no overlap
⚠️ memcpy 나 단순 대입은 원본과 대상 메모리가 겹치지 않는다고 가정하므로, 중첩된 영역에 사용하면 복사 도중 원본을 덮어써 미정의 동작과 데이터 손상이 발생한다. 중첩 가능성이 있으면 중첩을 허용하도록 정의된 std::memmove 를 사용한다.memcpy and plain assignment assume the source and destination do not overlap, so using them on overlapping regions overwrites the source mid-copy — undefined behaviour and data corruption. When overlap is possible, use std::memmove, which is defined to handle it.
Rule 8.18.2Advisory · DecidablePDF example
The result of an assignment operator should not be usedThe result of an assignment operator should not be used
❌ 위반 예시Non-compliant example
a[ x ] = a[ x = y ]; // Non-compliant - value of x = y is used if ( bool_a = bool_b ) // Non-compliant - value of bool_a = bool_b is used if ( ( 0u == 0u ) || ( bool_a = bool_b ) ) // Non-compliant - even though if ( ( x = f() ) != 0 ) // Non-compliant - value of x = f() is used a[ b += c ] = a[ b ]; // Non-compliant - value of b += c is used a = b = c = 0; // Non-compliant - values of c = 0, b = c = 0 are used
✅ 준수 예시Compliant example
x = y; // Compliant
⚠️ Rule 8.18.2 (The result of an assignment operator should not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.18.2 (The result of an assignment operator should not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 8.19.1Advisory · DecidablePDF example
쉼표(,) 연산자를 사용하지 않는다The comma operator should not be used
❌ 위반 예시Non-compliant example
for ( i = 0, p = &a[ 0 ]; i < N; ++i, ++p ) // Non-compliant
{
}
4.8.20 Constant expressions [expr.const]✅ 준수 예시Compliant example
#include <iostream>
static int a(){ std::cout << "a "; return 1; }
static int b(){ std::cout << "b "; return 2; }
int main(){
a(); // 부작용을 문장으로 분리
int x = b();
std::cout << "x=" << x << '\n';
}⚠️ 쉼표 연산자는 여러 부작용과 평가 순서를 한 식에 압축해 숨기고 좌변 결과를 조용히 버려, 가독성과 정적 분석을 모두 해친다. 각 부작용을 독립된 문장으로 분리하면 실행 순서와 의도가 분명해진다.The comma operator packs multiple side effects and their order into one expression and silently discards the left result, hurting readability and static analysis. Splitting each side effect into its own statement makes execution order and intent clear.
Rule 8.20.1Advisory · DecidablePDF example
An unsigned arithmetic operation with constant operands should not wrapAn unsigned arithmetic operation with constant operands should not wrap
❌ 위반 예시Non-compliant example
case BASE + 512u: h(); break; // Non-compliant - wraps to 0 auto off_time = DELAY + WIDTH; // Non-compliant - wraps to 4464 uint16_t x = b ? 0u : ( 0u - 1u ); // Non-compliant #if 1u + ( 0u - 10u ) // Non-compliant as ( 0u - 10u ) wraps #if 11u + ( 0u - 10u ) // Non-compliant as both operations wrap
✅ 준수 예시Compliant example
uint16_t y = ( 0u == 0u ) ? 0u : ( 0u - 1u ); // Compliant #if 11u + 0u - 10u // Compliant
⚠️ Rule 8.20.1 (An unsigned arithmetic operation with constant operands should not wrap)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 8.20.1 (An unsigned arithmetic operation with constant operands should not wrap) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
M9섹션 9Section 9
Rule 9.2.1Required · DecidablePDF example
명시적 형변환을 단독 표현식 문장으로 쓰지 않는다An explicit type conversion shall not be used as a standalone expression statement
❌ 위반 예시Non-compliant example
std::scoped_lock { a_mutex }; // Non-compliant
std::scoped_lock ( a_mutex, other_mutex ); // Non-compliant✅ 준수 예시Compliant example
f( std::unique_lock { a_mutex } ); // Compliant - type conversion is⚠️ 결과를 사용하지 않는 캐스트 단독 문장은 아무 효과가 없으면서, 대입을 빠뜨렸거나 다른 부작용을 의도했을 가능성을 숨긴다. 변환 결과를 변수에 담거나 반환해 실제로 사용하도록 작성한다.A standalone cast statement whose result is unused has no effect while hiding a likely missed assignment or intended side effect. Store the conversion result in a variable or return it so it is actually used.
Rule 9.3.1Required · DecidablePDF example
반복문·선택문의 본문은 복합문(중괄호 블록)이어야 한다The body of an iteration or selection statement shall be a compound statement
❌ 위반 예시Non-compliant example
process_data(); // Non-compliant
process_data(); // Non-compliant
if ( flag_2 ) // Non-compliant
action_1(); // Non-compliant
action_2(); // Non-compliant
while ( flag ); // Non-compliant✅ 준수 예시Compliant example
else { } // Compliant - else with empty block
while ( !data_available ) { } // Compliant - loop with empty body⚠️ 중괄호 없는 단일 문 본문은 나중에 문장을 추가할 때 들여쓰기만 맞춘 채 본문 밖에 놓이는 결함(dangling)을 부른다. 반복문·선택문 본문을 항상 복합문 블록으로 감싸 범위를 코드로 고정한다.A braceless single-statement body invites the dangling defect where a later-added statement is indented but falls outside the body. Always wrap iteration and selection bodies in a compound-statement block to fix the scope in code.
Rule 9.4.1Required · DecidablePDF example
if … else if 연쇄는 마지막 else로 종결한다All if ... else if chains shall be terminated with an else statement
❌ 위반 예시Non-compliant example
} // Non-compliant
✅ 준수 예시Compliant example
#include <iostream>
static int classify(int x){
int r;
if (x > 0) r = 1;
else if (x < 0) r = 2;
else r = 0; // 모든 경우를 명시적으로 처리
return r;
}
int main(){ std::cout << classify(0) << '\n'; }⚠️ 마지막 else 가 없는 if-else if 연쇄는 어느 분기에도 맞지 않는 입력을 아무 처리 없이 통과시켜, 오류 상황이 조용히 무시되고 디버깅을 어렵게 한다. 마지막 else 로 나머지 모든 경우를 명시적으로 처리한다.An if-else if chain without a final else lets inputs matching no branch pass with no handling, silently ignoring error cases and hampering debugging. Terminate with a final else that explicitly handles all remaining cases.
Rule 9.4.2Required · DecidablePDF example
switch 문은 적절한 구조(default·break·case 라벨)를 갖춘다A switch statement shall be a well-formed switch statement
❌ 위반 예시Non-compliant example
switch ( x = f(); x ) // Non-compliant - x = f() is not a simple-declaration
int32_t i; // Non-compliant - not a switch label group
// Non-compliant - termination is not unconditional
a = b; // Non-compliant - non-empty, implicit fall-through
case 8: // Non-compliant - case not in a switch label group
} // Non-compliant - default is required
switch ( x ) // Non-compliant - only one switch branch
; // Non-compliant - default must also be terminated
} // Non-compliant - default is required
switch ( colour ) // Non-compliant - only one switch branch✅ 준수 예시Compliant example
switch ( int8_t x = f(); x ) // Compliant - declaration of x is simple
break; // Compliant - branch unconditionally terminated
throw; // Compliant - branch unconditionally terminated
[[fallthrough]]; // Compliant - branch has explicit fall-through
default: // Compliant - default is last label
return; // Compliant - branches unconditionally terminated
} // Compliant by exception - all enumerators listed⚠️ break 누락은 의도치 않은 fall-through 로 한 case 가 다음 case 까지 실행시키고, default 부재는 정의되지 않은 값을 조용히 무시해 오류를 숨긴다. 각 case 를 break 로 닫고 default 절을 두어 모든 입력을 처리한다.A missing break causes unintended fall-through where one case runs into the next, and a missing default silently ignores undefined values, hiding errors. Close each case with break and provide a default to handle all inputs.
Rule 9.5.1Advisory · DecidablePDF example
전통적 for 문은 단순하게 작성한다A traditional for-loop should be simple
❌ 위반 예시Non-compliant example
for ( int32_t i = 0; i < 10; ++i ) // Non-compliant for ( uint32_t i = 0u; i < u64a; ++i ) // Non-compliant - loop-counter and
✅ 준수 예시Compliant example
for ( int32_t i = 0; i < 10; ++i ) // Compliant for ( auto i = 0u; i < arr.size(); ++i ) // Compliant- arr.size() is constant
⚠️ 다중 카운터나 본문 내 카운터 변경은 루프가 몇 번 도는지, 언제 끝나는지 정적으로 추론하기 어렵게 만들어 오프바이원·무한루프 결함을 숨긴다. 카운터는 하나로, 증감은 for 헤더에서만 수행한다.Multiple counters or modifying the counter in the body make it hard to statically reason about how many times the loop runs and when it ends, hiding off-by-one and infinite-loop defects. Use a single counter and change it only in the for header.
Rule 9.5.2Required · DecidablePDF example
범위 기반 for의 범위식은 함수 호출을 최대 1회만 포함한다A range-based for loop’s range-initializer should contain at most one function call
❌ 위반 예시Non-compliant example
for ( auto e : make( s ) ) // Non-compliant - call to 'make' and an
✅ 준수 예시Compliant example
for ( auto e : r ) // Compliant version of the above
⚠️ 범위 기반 for 의 범위식에 임시객체를 만드는 함수 호출이 여럿이면, 임시객체의 수명과 평가 순서가 모호해져 순회 도중 댕글링 참조 위험이 생긴다. 범위 객체를 먼저 변수로 확정한 뒤 그 lvalue 를 순회한다.When a range-based for’s range-initializer contains several calls that create temporaries, their lifetimes and evaluation order become unclear, risking a dangling reference during iteration. Bind the range object to a variable first and iterate over that lvalue.
Rule 9.6.1Advisory · Decidable✓ compilablePDF rule
goto 문은 사용하지 않는다The goto statement should not be used
❌ 위반 예시Non-compliant example
#include <iostream>
static int find(const int* a, int n, int key){
int idx = -1;
for (int i = 0; i < n; ++i) {
if (a[i] == key) { idx = i; goto done; } // 비구조적 제어 흐름
}
done:
return idx;
}
int main(){ int a[3] = {1,2,3}; std::cout << find(a, 3, 2) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
static int find(const int* a, int n, int key){
int idx = -1;
for (int i = 0; i < n; ++i) {
if (a[i] == key) { idx = i; break; } // 구조적 제어로 대체
}
return idx;
}
int main(){ int a[3] = {1,2,3}; std::cout << find(a, 3, 2) << '\n'; }⚠️ goto 는 제어 흐름을 비구조적으로 만들어 어디로 점프하는지 추적·검증을 어렵게 하고 초기화·정리 순서를 무너뜨릴 수 있다. break/continue/return 같은 구조적 제어나 함수 분리로 같은 의도를 표현한다.goto makes control flow non-structured, making jumps hard to trace and verify and able to break initialization/cleanup order. Express the same intent with structured control (break/continue/return) or by factoring into functions.
Rule 9.6.2Required · DecidablePDF example
goto는 같은 또는 둘러싼 블록의 라벨만 참조한다A goto statement shall reference a label in a surrounding block
❌ 위반 예시Non-compliant example
void f1()
{
int32_t j = 0;
goto L1; // Non-compliant
for ( j = 0; j < 10 ; ++j )
{✅ 준수 예시Compliant example
j;
}
}
void f2()
{
for ( int32_t j = 0; j < 10 ; ++j )
{
for ( int32_t i = 0; i < 10; ++i )
{
goto L2; // Compliant
}
}⚠️ 바깥에서 더 안쪽 블록의 라벨로 점프하면 그 블록 안 객체의 초기화를 건너뛰어 미초기화 객체 사용 등 정의되지 않은 흐름을 만든다. 점프를 제거하거나, 불가피하면 같은/둘러싼 블록의 라벨만 참조한다.Jumping from outside into a more deeply nested block bypasses initialization of objects in that block, creating undefined flow such as use of uninitialized objects. Remove the jump, or if unavoidable, only reference labels in the same or an enclosing block.
Rule 9.6.3Required · DecidablePDF example
goto는 본문에서 나중에 선언된 라벨로만 전방 점프한다A goto statement shall jump forward to a label declared later in the same function
❌ 위반 예시Non-compliant example
{
++x;
goto L1; // Non-compliant
}✅ 준수 예시Compliant example
if ( x == 10 )
{
goto L2; // Compliant
}⚠️ 후방 goto 는 명시적 반복문 없이 암묵적 루프를 만들어 반복 횟수와 종료 조건을 코드만으로 파악하기 어렵게 한다. 반복이 필요하면 for/while 같은 명시적 반복문을 사용하고, goto 는 전방 점프로만 제한한다.A backward goto forms an implicit loop without an explicit loop construct, making iteration count and termination hard to read from the code. Use explicit loops (for/while) when iteration is needed and restrict goto to forward jumps.
Rule 9.6.4Mandatory · Undecidable✓ compilablePDF rule
[[noreturn]] 함수는 절대 반환하지 않는다A function declared [[noreturn]] shall not return
❌ 위반 예시Non-compliant example
#include <cstdlib>
[[noreturn]] static void fail(int code){
if (code == 0) {
return; // noreturn 인데 정상 반환 경로 존재 — 미정의 동작
}
std::abort();
}
int main(){ (void)&fail; return 0; }✅ 준수 예시Compliant example
#include <cstdlib>
[[noreturn]] static void fail(int /*code*/){
std::abort(); // 모든 경로가 비반환(abort)으로 종료
}
int main(){ (void)&fail; return 0; }⚠️ [[noreturn]] 로 선언한 함수가 실제로 반환하면, 호출자는 절대 돌아오지 않는다는 가정 하에 생성된 코드로 인해 미정의 동작에 빠진다. 모든 실행 경로가 abort·throw·exit·무한 루프 등으로 반드시 종료되도록 보장한다.If a function declared [[noreturn]] actually returns, the caller — built on the assumption it never comes back — enters undefined behaviour. Ensure every execution path terminates via abort, throw, exit, or an infinite loop.
Rule 9.6.5Mandatory · UndecidablePDF example
비-void 반환형 함수는 모든 경로에서 값을 반환한다A function with non-void return type shall return a value on all paths
❌ 위반 예시Non-compliant example
int32_t fn1() // Non-compliant
✅ 준수 예시Compliant example
int32_t fn2( int32_t x ) // Compliant
⚠️ 값을 반환하지 않고 함수 끝에 도달하면 호출자는 스택·레지스터에 남은 불확정 값을 결과로 읽어 미정의 동작이 된다. 모든 분기에서 명시적으로 값을 반환하도록 보장한다.Falling off the end without returning a value makes the caller read an indeterminate leftover from the stack/registers — undefined behaviour. Ensure a value is explicitly returned on every branch.
M10섹션 10Section 10
Rule 10.0.1Advisory · DecidablePDF example
한 선언에서 둘 이상의 변수/멤버를 선언하지 않는다Only one variable or member shall be declared in a declaration
❌ 위반 예시Non-compliant example
int32_t i2, * j2; // Non-compliant
& j3 = i2; // Non-compliant
int32_t x, y; // Non-compliant✅ 준수 예시Compliant example
int32_t i1; int32_t j1; // Compliant map.insert( make_pair( 'A', 'a' ) ); // Compliant - structured binding
⚠️ 한 줄에 여러 객체를 선언하면 int* p, q; 에서 q 가 포인터가 아닌 점처럼 포인터 결합을 오해하기 쉽고, 일부 변수의 초기화를 빠뜨리기도 쉽다. 선언당 하나의 변수만 두고 각각 초기화한다.Declaring multiple objects in one statement invites misreading pointer binding (in int* p, q; only p is a pointer) and makes it easy to miss initializing some of them. Declare one variable per declaration and initialize each.
Rule 10.1.1Advisory · DecidablePDF example
포인터·참조 매개변수의 대상 타입은 적절히 const 한정한다The target type of a pointer or lvalue reference parameter should be const-qualified where appropriate
❌ 위반 예시Non-compliant example
int8_t * p3, // Non-compliant - *p3 not modified, no const
int8_t * const p4, // Non-compliant - *p4 not modified, no const
int8_t a[3] ) // Non-compliant - 'a' decays to int8_t *
auto f4( std::vector< int32_t > & x ) // Non-compliant✅ 준수 예시Compliant example
void f1( int8_t * p1, // Compliant - *p1 modified
const int8_t * p2, // Compliant - *p2 not modified, but is const
auto & f2( int32_t & i, // Compliant
auto f3( std::vector< int32_t > & x ) // Compliant - even though x.begin has an⚠️ 대상을 수정하지 않는데 const 를 빠뜨리면 함수의 의도(읽기 전용)가 드러나지 않고, const 객체나 리터럴을 인자로 받지 못해 호출 측 유연성이 떨어진다. 읽기 전용 대상은 const 로 한정해 의도와 인터페이스를 명확히 한다.Omitting const where the target is not modified hides the read-only intent and prevents accepting const objects or literals as arguments, reducing caller flexibility. Const-qualify read-only targets to make intent and interface explicit.
Rule 10.1.2Required · DecidablePDF example
volatile 한정자는 적절한 경우에만 사용한다The volatile qualifier shall be used only where necessary
❌ 위반 예시Non-compliant example
void f1( volatile int32_t i ) // Non-compliant void f3( int32_t * volatile p ) // Non-compliant - parameter is volatile volatile int32_t j = i; // Non-compliant volatile int32_t f5(); // Non-compliant auto volatile [ a, b ] = g; // Non-compliant
✅ 준수 예시Compliant example
void f2( volatile int32_t * p ) // Compliant - parameter is not volatile volatile uint32_t reg; // Compliant void f7( S s ); // Compliant - but unlikely to work as expected void f8( S & s ); // Compliant - preserves volatile behaviour of reg
⚠️ 외부 요인으로 값이 바뀌지 않는 일반 객체에 volatile 을 붙이면 컴파일러의 최적화(레지스터 보관·중복 제거)를 막아 성능만 떨어뜨리고, volatile 의 의미를 오해하게 만든다. volatile 은 하드웨어 레지스터·시그널 핸들러 공유 변수처럼 진짜 필요한 곳에만 적용한다.Applying volatile to an ordinary object whose value is not changed by external factors blocks compiler optimizations (register caching, redundancy removal), costing performance and obscuring volatile’s meaning. Use volatile only where truly needed, such as hardware registers or signal-handler-shared variables.
Rule 10.2.1Required · DecidablePDF example
열거형은 기반 정수 타입을 명시해 정의한다An enumeration shall be defined with an explicit underlying type
❌ 위반 예시Non-compliant example
enum class Enum2 // Non-compliant - no explicit underlying type enum class Enum3 : uint8_t // Non-compliant - cannot represent value for E2
✅ 준수 예시Compliant example
enum class Enum1 : int8_t // Compliant enum class Enum4 // Compliant by exception #1 enum Enum5 // Compliant by exception #2
⚠️ 기반 타입을 명시하지 않은 열거형은 크기와 표현 범위가 구현에 따라 달라져, 직렬화·하드웨어 인터페이스·이식 시 레이아웃이 어긋난다. 명시적 underlying type(예: std::uint8_t)을 지정해 표현을 고정한다.An enumeration without an explicit underlying type has implementation-defined size and range, so its layout diverges across serialization, hardware interfaces, and ports. Specify an explicit underlying type (e.g., std::uint8_t) to fix the representation.
Rule 10.2.2Advisory · DecidablePDF example
범위 없는(unscoped) 열거형은 선언하지 않는다Unscoped enumerations should not be declared
❌ 위반 예시Non-compliant example
enum E1 : int32_t { E10, E11, E12 }; // Non-compliant - ill-formed as✅ 준수 예시Compliant example
enum class E2 : int32_t { E20, E21, E22 }; // Compliant
enum Cstyle { E10, E20, E30 }; // Compliant by exception⚠️ unscoped enum 은 열거자 이름을 둘러싼 이름공간에 그대로 노출해 충돌을 일으키고, 정수로 암묵 변환되어 잘못된 비교·산술을 조용히 허용한다. enum class(scoped enum)를 사용해 이름을 한정하고 암묵 변환을 차단한다.An unscoped enum leaks enumerator names into the enclosing namespace causing clashes, and implicitly converts to int, silently allowing wrong comparisons and arithmetic. Use enum class (scoped enum) to qualify names and block implicit conversion.
Rule 10.2.3Required · DecidablePDF example
고정 기반 타입 없는 unscoped 열거형의 수치값을 사용하지 않는다The numeric value of an unscoped enumeration without a fixed underlying type shall not be used
❌ 위반 예시Non-compliant example
e == e2a; // Non-compliant - second operand of a different type e + 1; // Non-compliant - addition switch( e ) // Non-compliant - cases are not all enumerators of E E e3 = static_cast< E >( 0 ); // Non-compliant *( a1 + e1a ); // Non-compliant
✅ 준수 예시Compliant example
E e2 = e; // Compliant - assignment to the same type int32_t i1 = e; // Compliant - assignment to a large enough integer e == e1a; // Compliant e < e1b; // Compliant g( e ); // Compliant - assignment to large enough integer a1[ e1a ]; // Compliant - index operator a2[ e1a ]; // Compliant - assignment to a large enough integer (size_t)
⚠️ 기반 타입이 고정되지 않은 unscoped 열거형은 표현 범위가 구현 정의라, 그 값을 직접 산술에 쓰면 범위·승격 규칙이 불명확해 이식 시 다른 결과가 날 수 있다. 고정 기반 타입을 가진 enum class 로 선언하고 수치가 필요할 때만 명시적으로 변환한다.An unscoped enumeration without a fixed underlying type has an implementation-defined range, so using its value directly in arithmetic leaves range and promotion rules unclear, risking different results across ports. Declare an enum class with a fixed underlying type and convert explicitly only when a numeric value is needed.
Rule 10.3.1Advisory · DecidablePDF example
헤더 파일에는 익명 네임스페이스를 두지 않는다There should be no unnamed namespaces in header files
❌ 위반 예시Non-compliant example
// Header.hpp
namespace // Non-compliant
{
inline int32_t x;
}
void fn_a();
// File1.cpp
#include "Header.hpp"
void fn_a()
{
x = 42;
}
// File2.cpp
#include "Header.hpp"
void fn_b()
{
fn_a(); // Assigns 42 to 'x' in translation unit for 'File1.cpp'
if ( x == 42 ) {} // 'x' within this translation unit will not have the value 42
}✅ 준수 예시Compliant example
// util.hpp (준수) — 헤더에는 선언만
namespace util {
void tick();
}
// util.cpp — 정의는 한 곳에, 내부 연결은 파일 정적으로
namespace util {
static int counter = 0;
void tick() { ++counter; }
}⚠️ 헤더의 익명 네임스페이스는 그 헤더를 포함하는 번역단위마다 내부 연결의 별도 실체(별도 counter)를 만들어, 모두가 같은 상태를 공유한다는 착각과 ODR 혼란을 일으킨다. 헤더에는 선언만 두고 정의·내부 상태는 소스 파일에 둔다.An unnamed namespace in a header creates a separate internal-linkage instance (a separate counter) in every translation unit that includes it, causing the illusion of shared state and ODR confusion. Keep only declarations in headers and put definitions and internal state in source files.
Rule 10.4.1Required · Decidable✓ compilablePDF rule
asm 선언(인라인 어셈블리)을 사용하지 않는다The asm declaration shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
static int read_low(){
int lo = 0;
asm volatile("rdtsc" : "=a"(lo)); // 인라인 어셈블리 — 이식성·정적분석 저하
return lo;
}
int main(){ std::cout << (read_low() != 0) << '\n'; }✅ 준수 예시Compliant example
#include <chrono>
#include <iostream>
static long read_low(){
auto now = std::chrono::steady_clock::now().time_since_epoch(); // 이식성 있는 표준 API
return static_cast<long>(
std::chrono::duration_cast<std::chrono::nanoseconds>(now).count());
}
int main(){ std::cout << (read_low() != 0) << '\n'; }⚠️ 인라인 어셈블리는 특정 CPU·컴파일러에 묶여 이식성을 깨뜨리고, 정적 분석 도구가 의미를 파악하지 못해 검증 사각지대를 만든다. 표준 라이브러리(예: <chrono>)나 잘 캡슐화된 컴파일러 내장함수로 대체한다.Inline assembly ties code to a specific CPU and compiler, breaking portability, and static-analysis tools cannot interpret it, creating a verification blind spot. Replace it with the standard library (e.g., <chrono>) or well-encapsulated compiler intrinsics.
M11섹션 11Section 11
Rule 11.3.1Advisory · DecidablePDF example
C 스타일 배열 타입 변수를 선언하지 않는다A C-style array shall not be declared
❌ 위반 예시Non-compliant example
wchar_t a1 [ size ]; // Non-compliant
std::uint16_t a3[ 10 ]; // Non-compliant
char s2[] = "abcd"; // Non-compliant✅ 준수 예시Compliant example
std::array< wchar_t, size > a2; // Compliant const char s1[] = "abcd"; // Compliant by exception const auto best = "abcd"sv; // Compliant
⚠️ C 스타일 배열은 자신의 크기 정보를 갖지 않고 포인터로 쉽게 붕괴(decay)되어 경계 검사 없이 오버런을 일으킨다. std::array(고정 크기)·std::vector(가변 크기)는 size()와 경계 검사 인터페이스를 제공해 안전하게 다룰 수 있다.A C-style array carries no size information and decays to a pointer, enabling overruns with no bounds checking. std::array (fixed size) and std::vector (dynamic) provide size() and bounds-aware interfaces for safe handling.
Rule 11.3.2Advisory · DecidablePDF example
객체 선언의 포인터 간접 단계는 2단계를 넘지 않는다The declaration of an object should contain no more than two levels of pointer indirection
❌ 위반 예시Non-compliant example
int8_t *** s3; // Non-compliant
struct s *** ps3; // Non-compliant
int8_t ** ( ***pfunc3 )(); // Non-compliant
int8_t *** ( **pfunc4 )(); // Non-compliant
int8_t *** par3, // Non-compliant
INTPTR1 * const * const par5, // Non-compliant
int8_t ** par7[], // Non-compliant
int8_t *** ptr3; // Non-compliant
INTPTR2 * const * const ptr5; // Non-compliant
int8_t. This is three levels and is non-compliant.✅ 준수 예시Compliant example
int8_t * s1; // Compliant
int8_t ** s2; // Compliant
struct s * ps1; // Compliant
struct s ** ps2; // Compliant
int8_t ** ( *pfunc1 )(); // Compliant
int8_t ** ( **pfunc2 )(); // Compliant
void function( int8_t * par1, // Compliant
int8_t ** par2, // Compliant
INTPTR1 * par4, // Compliant
int8_t * par6[], // Compliant
int8_t ** &par8) // Compliant
int8_t * ptr1; // Compliant
int8_t ** ptr2; // Compliant
INTPTR2 * ptr4; // Compliant
int8_t * ptr6[ 10 ]; // Compliant
int8_t ** ptr7[ 10 ]; // Compliant⚠️ 2단계를 넘는 포인터 간접(int***)은 각 단계가 무엇을, 누가 소유하며, 언제 해제되는지 추론하기 매우 어려워 누수·댕글링을 부른다. 중첩 컨테이너(std::vector<std::vector<...>>)나 전용 타입으로 표현해 간접 단계를 낮춘다.More than two levels of pointer indirection (int***) make it very hard to reason about what each level points to, who owns it, and when it is freed, inviting leaks and dangling. Express it with nested containers (std::vector<std::vector<...>>) or a dedicated type to reduce indirection.
Rule 11.6.1Advisory · DecidablePDF example
모든 변수는 초기화한다All variables should be initialized
❌ 위반 예시Non-compliant example
int32_t i; // Non-compliant
✅ 준수 예시Compliant example
int32_t j = cond ? 42 : -1; // Compliant int32_t k = [&]() // Compliant string s; // Compliant - default-initialized int32_t g; // Compliant - static initialization applies thread_local int32_t i; // Compliant - static initialization applies
⚠️ 미초기화 변수는 일부 경로에서 스택에 남은 비결정적 값을 읽어, 실행마다 결과가 달라지는 재현 불가 버그를 만든다. 모든 변수를 선언 시점에 의미 있는 초기값으로 초기화한다.An uninitialized variable read on some path uses non-deterministic leftover stack values, producing irreproducible bugs that vary by run. Initialize every variable with a meaningful value at the point of declaration.
Rule 11.6.2Mandatory · UndecidablePDF example
객체의 값은 설정되기 전에 읽지 않는다The value of an object shall not be read before it has been set
❌ 위반 예시Non-compliant example
int32_t j = i + 1; // Non-compliant - i has not been assigned a value int32_t k = *p; // Non-compliant - *p has not been assigned a value if ( q == p ) // Non-compliant - q has not been assigned a value x = x + 1u; // Non-compliant - x may not have been assigned a value auto i1 = s1.a; // Non-compliant auto i4 = array2[ 5 ]; // Non-compliant if ( c2.GetmB() > 0 ) // Non-compliant - m_b not initialized
✅ 준수 예시Compliant example
int32_t Z; // Compliant - implicitly initialized with '0' auto i2 = s2.b; // Compliant - s2.b implicitly initialized to 0 auto i3 = array1[ 5 ]; // Compliant - array1[ 5 ] implicitly initialized to 0 if ( c1.GetmB() > 0 ) // Compliant - m_b initialized
⚠️ 설정되기 전의 객체를 읽으면 불확정 값을 사용하게 되어 동작이 미정의가 되고, 컴파일러 최적화에 따라 예측 불가한 결과가 나온다(필수 규칙). 모든 읽기 경로에서 사전 대입을 보장한다.Reading an object before it is set uses an indeterminate value — undefined behaviour with results unpredictable under optimization (a mandatory rule). Guarantee a prior assignment on every read path.
Rule 11.6.3Required · DecidablePDF example
열거자 목록에서 암묵적으로 결정되는 값은 서로 중복되지 않는다Within an enumerator list, the value of an implicitly-specified enumeration constant shall be unique
❌ 위반 예시Non-compliant example
enum E3 { A = 3, B, C, D = 4 }; // 'B' and 'D' have the same value
enum E4 { A = 3, B, C, D = B, E }; // 'C' and 'E' have the same value
enum E5 { A = 3, B, C, D = B + 1 }; // Non-compliant✅ 준수 예시Compliant example
enum E1 { A = 3, B, C = 5, D = 5 }; // Compliant
enum E2 { A = 3, B, C, D = C, E = D }; // Compliant by exception⚠️ 명시 값과 암묵(앞 값+1) 값이 섞여 두 열거자가 같은 정수가 되면, switch 분기나 값-기반 테이블 매핑에서 둘을 구분하지 못해 논리 오류가 숨는다. 각 열거자의 값이 고유하도록 명시한다.When explicit and implicit (previous+1) values mix so two enumerators share the same integer, switch branches or value-based table mappings cannot distinguish them, hiding logic errors. Specify values so each enumerator is unique.
M12섹션 12Section 12
Rule 12.2.1Advisory · DecidablePDF example
비트필드는 선언하지 않는다Bit-fields should not be declared
❌ 위반 예시Non-compliant example
struct message
{
unsigned char low : 4; // Non-compliant
unsigned char high : 4; // Non-compliant
};✅ 준수 예시Compliant example
#include <cstdint>
#include <iostream>
struct Reg { std::uint8_t value; }; // 명시적 정수 + 마스크 상수로 표현
constexpr std::uint8_t ENABLE = 0x01u;
constexpr std::uint8_t MODE = 0x0Eu; // bits 1..3
int main(){
Reg r{0};
r.value |= ENABLE;
r.value = static_cast<std::uint8_t>((r.value & ~MODE) | (2u << 1));
std::cout << ((r.value & MODE) >> 1) << '\n';
}⚠️ 비트필드는 메모리 내 배치 순서, 부호 처리, 패딩이 모두 구현 의존적이라 같은 코드가 컴파일러·엔디안마다 다른 비트를 가리켜 하드웨어 레지스터 매핑·직렬화에서 깨진다. 명시적 부호 없는 정수와 마스크 연산으로 비트 위치를 코드에 고정한다.Bit-fields have implementation-defined layout order, sign handling, and padding, so the same code addresses different bits across compilers and endianness, breaking hardware-register mapping and serialization. Use explicit unsigned integers with mask operations to fix bit positions in code.
Rule 12.2.2Required · DecidablePDF example
비트필드를 쓴다면 적절한 타입(명시적 부호/크기)을 사용한다If a bit-field is used, it shall have an appropriate type
❌ 위반 예시Non-compliant example
char c : 2; // Non-compliant
wchar_t e : 2; // Non-compliant - not a signed or unsigned integer type
char32_t f : 2; // Non-compliant - not a signed or unsigned integer type
Direction dir : 4; // Non-compliant - unscoped and no underlying type
Colour lineColour : 2; // Non-compliant - underlying type is plain char
Line lineStyle1 : 1; // Non-compliant - cannot represent Dot✅ 준수 예시Compliant example
signed int a : 2; // Compliant
int : 2; // Compliant
int32_t b : 2; // Compliant
signed char d : 2; // Compliant - signed integer type
bool g : 1; // Compliant
Line lineStyle2 : 2; // Compliant⚠️ 부호 있는 정수나 구현정의 타입의 비트필드는 표현 범위와 부호 동작이 모호해, 같은 비트 폭이라도 값 해석이 컴파일러마다 달라진다. 비트필드가 불가피하면 std::uint8_t 같은 부호 없는 고정폭 타입을 기반으로 사용한다.A bit-field of signed or implementation-defined type has ambiguous range and sign behaviour, so the same bit width is interpreted differently across compilers. When a bit-field is unavoidable, base it on an unsigned fixed-width type such as std::uint8_t.
Rule 12.2.3Required · DecidablePDF example
부호 있는 정수형 명명 비트필드의 길이를 1비트로 두지 않는다A named bit-field with signed integer type shall not have a length of one bit
❌ 위반 예시Non-compliant example
signed int a : 1; // Non-compliant
int c : 1; // Non-compliant✅ 준수 예시Compliant example
signed int b : 2; // Compliant
⚠️ 부호 있는 1비트 비트필드는 값을 담을 비트가 부호 비트뿐이라 표현 가능한 값이 0 과 -1 로 제한되어, flag=1 을 넣어도 -1 로 저장되는 직관 위배가 생긴다. 1비트 플래그는 항상 부호 없는 타입으로 선언한다.A signed one-bit bit-field has only the sign bit to hold a value, limiting representable values to 0 and -1, so assigning flag=1 stores -1 — counterintuitive. Always declare one-bit flags with an unsigned type.
Rule 12.3.1Required · DecidablePDF example
union 키워드를 사용하지 않는다The union keyword shall not be used
❌ 위반 예시Non-compliant example
{
int32_t i;
float j;
};
using Data2 = std::variant< int32_t, float >; // Rule does not apply✅ 준수 예시Compliant example
#include <variant>
#include <iostream>
using Packet = std::variant<int, float>; // 타입 안전 합집합
static float read(const Packet& p){
return std::holds_alternative<float>(p) ? std::get<float>(p) : 0.0f;
}
int main(){ Packet p = 1.0f; std::cout << read(p) << '\n'; }⚠️ union 은 어느 멤버가 현재 유효한지 자체적으로 추적하지 못해, 쓴 멤버와 다른 멤버를 읽는 타입 혼동·미정의 읽기를 쉽게 허용한다. std::variant 는 활성 타입을 추적하고 잘못된 접근을 검출해 타입 안전한 합집합을 제공한다.A union does not track which member is currently active, easily allowing type confusion and undefined reads where a member other than the one written is read. std::variant tracks the active type and detects wrong access, providing a type-safe union.
M13섹션 13Section 13
Rule 13.1.1Advisory · DecidablePDF example
가상 상속(virtual base)을 사용하지 않는다Virtual base classes should not be used
❌ 위반 예시Non-compliant example
struct A
{
virtual int32_t foo() { return 1; }
};
struct B : public virtual A // Non-compliant
{
int32_t goo()
{
return foo();
}
};
struct C : public virtual A // Non-compliant
{
int32_t foo() override { return 2; }
};
struct D : C, B
{
};
int main()
{
D d;
return d.goo(); // Calls C::foo(), which may not be expected
}✅ 준수 예시Compliant example
#include <iostream>
struct Base { int v{0}; };
struct D { // 가상 상속 대신 합성(composition)으로 공유
Base shared;
};
int main(){ D d; d.shared.v = 5; std::cout << d.shared.v << '\n'; }⚠️ 가상 상속은 공유 기반 서브객체를 위해 추가 포인터·복잡한 초기화 순서를 도입해 객체 레이아웃을 어렵게 만들고 검증 부담과 미묘한 초기화 버그를 키운다. 공유 구조가 필요하면 합성(멤버로 포함)으로 단순화한다.Virtual inheritance introduces extra pointers and a complex initialization order for the shared base subobject, complicating object layout and increasing verification burden and subtle init bugs. When a shared structure is needed, simplify with composition (holding it as a member).
Rule 13.1.2Required · DecidablePDF example
접근 가능한 기반 클래스를 가상·비가상으로 동시에 두지 않는다An accessible base class shall not be both virtual and non-virtual in the same hierarchy
❌ 위반 예시Non-compliant example
class A {};
class B1: public virtual A {};
class B2: public virtual A {};
class B3: public A {};
class C: public B1, B2, B3 {}; // Non-compliant - C has two A subobjects✅ 준수 예시Compliant example
#include <iostream>
struct Base { int v{0}; };
struct A : virtual Base {};
struct B : virtual Base {}; // 일관되게 가상으로 — 단일 공유 서브객체
struct D : A, B {};
int main(){ D d; d.v = 1; std::cout << d.v << '\n'; }⚠️ 같은 기반 클래스가 한 계층에서 가상과 비가상으로 섞여 상속되면 가상 경로의 공유 서브객체와 비가상 경로의 별도 서브객체가 동시에 생겨, 멤버 접근이 모호해지고 데이터가 둘로 갈려 불일치가 발생한다. 상속 방식을 일관되게(모두 가상 또는 모두 비가상) 통일한다.When the same base is inherited both virtually and non-virtually in one hierarchy, a shared subobject from the virtual path coexists with a separate subobject from the non-virtual path, making member access ambiguous and splitting data into two inconsistent copies. Make the inheritance consistent (all virtual or all non-virtual).
Rule 13.3.1Required · DecidablePDF example
멤버 함수는 virtual/override/final 지정자를 적절히(셋 중 하나만) 사용한다A function that overrides shall be declared with override or final but not virtual
❌ 위반 예시Non-compliant example
virtual void f5() noexcept final = 0; // 'virtual' and 'final'
virtual void f6() noexcept final {} // 'virtual' and 'final'
void f7() noexcept final {} // Ill-formed - not virtual
};
class B : public A
{
~B(); // No specifier given for override
virtual void f1() noexcept override {} // 'virtual' and 'override'
void f2() noexcept override final {} // 'override' and 'final'
void f3() noexcept {} // No specifier given for override
void f4() noexcept override {} // Ill-formed - A::f4() not virtual
};✅ 준수 예시Compliant example
virtual void f1() noexcept = 0; // Compliant
virtual void f2() noexcept {} // Compliant
virtual void f3() noexcept {} // Compliant
void f4() noexcept {} // Compliant⚠️ 재정의 함수에 virtual 과 override 를 함께 쓰면 의미가 중복되어 의도(새 가상 함수인지, 재정의인지)가 흐려지고 일관성이 떨어진다. 재정의는 override, 더 이상 재정의 금지는 final 로 하나만 명시해 의도를 분명히 한다.Specifying both virtual and override on an overriding function is redundant and blurs intent (a new virtual function vs. an override) and consistency. Mark overrides with override, and seal further overriding with final — exactly one, to state intent clearly.
Rule 13.3.2Required · DecidablePDF example
재정의 가상 함수는 다른 기본 인자를 지정하지 않는다Parameters in an overriding virtual function shall not specify different default arguments
❌ 위반 예시Non-compliant example
void bad1 ( int32_t a = 1 ) override; // Non-compliant - different value void bad2 ( int32_t a = 2 ) override; // Non-compliant - no default in base void bad3 ( int32_t a = x() ) override; // Non-compliant - not constant
✅ 준수 예시Compliant example
void good1( int32_t a = 0 ) override; // Compliant - same default used void good2( int32_t a ) override; // Compliant - no default specified
⚠️ 기본 인자는 호출 식의 정적 타입을 기준으로 결정되는데, 실제 호출되는 함수는 동적 타입의 재정의본이므로, 기반과 파생의 기본값이 다르면 같은 호출이 정적 타입에 따라 다른 인자로 실행되어 예측 불가해진다. 재정의에서는 기본 인자를 기반과 일치시킨다(가능하면 기본 인자 미사용).Default arguments are chosen by the static type of the call expression, while the function actually invoked is the dynamic-type override; if base and derived defaults differ, the same call runs with different arguments depending on the static type — unpredictable. Match the override’s default arguments to the base (preferably avoid default arguments).
Rule 13.3.3Required · DecidablePDF example
함수의 모든 선언·재정의에서 매개변수 이름은 무명이거나 동일해야 한다Parameters shall be unnamed or have the same name in all declarations and overrides
❌ 위반 예시Non-compliant example
void CreateRectangle( uint32_t Height, uint32_t Width );
void CreateRectangle( uint32_t Width, uint32_t Height );
void fn2( int32_t a );
void fn2( int32_t b ) { }✅ 준수 예시Compliant example
void fn1( int32_t a ); void fn1( int32_t );
⚠️ 선언마다 매개변수 이름이 다르거나(특히 width/height 처럼 뒤바뀌면) 호출자가 인자의 의미를 오해해 순서를 바꿔 전달하는 결함을 부른다. 한 함수의 모든 선언·재정의에서 매개변수 이름을 동일하게(또는 전부 무명으로) 맞춘다.Different parameter names across declarations — especially swapped ones like width/height — lead callers to misunderstand argument meaning and pass them in the wrong order. Keep parameter names identical (or all unnamed) across every declaration and override of a function.
Rule 13.3.4Required · DecidablePDF example
멤버 함수 포인터는 널 상수와의 동등 비교에만 쓴다A pointer to member function shall only be compared for equality with a null pointer constant
❌ 위반 예시Non-compliant example
if ( &A::f3 == &A::f2 ) {} // Non-compliant - f3 virtual
if ( ptr == &A::f2 ) {} // Non-compliant - ptr potentially points to A::f3,
if ( ptr == &D::f4 ) {} // Non-compliant - ptr potentially points to A::f3,
if ( p1 == p2 ) {} // Non-compliant - 'E' is incomplete, so it is✅ 준수 예시Compliant example
if ( &A::f1 != &A::f2 ) {} // Compliant
if ( &A::f1 != nullptr ) {} // Compliant
if ( &A::f3 == nullptr ) {} // Compliant
Note: the example above would be compliant if A had no virtual members.
if ( ptr == &B::f2 ) {} // Compliant - there are no virtual functions
// unit would make the above example compliant⚠️ 가상 멤버 함수에 대한 포인터끼리의 동등 비교는 표준이 결과를 명확히 규정하지 않아 구현마다 다르게 동작할 수 있어 신뢰할 수 없다. 멤버 함수 포인터는 nullptr 과의 동등 비교(설정 여부 판정)에만 사용한다.Equality comparison between pointers to virtual member functions is not clearly specified by the standard and may behave differently across implementations, so it is unreliable. Use pointers to member functions only for equality comparison with nullptr (to test whether one is set).
M14섹션 14Section 14
Rule 14.1.1Advisory · DecidablePDF example
비정적 데이터 멤버는 모두 private이거나 모두 public이어야 한다Non-static data members should be either all private or all public
❌ 위반 예시Non-compliant example
class C1 // Non-compliant - has public and private members
{✅ 준수 예시Compliant example
int32_t b;
};
struct C2 // Compliant
{
C2( int32_t a, int32_t b ) : a{ a }, b{ b } {}
int32_t a;
int32_t b;
};
class C3 // Compliant - rule does not apply to static members
{⚠️ 데이터 멤버의 접근 수준이 섞이면 일부는 외부에서 직접 수정 가능하고 일부는 메서드를 통해서만 바뀌어, 불변식(invariant) 유지 책임이 흩어지고 캡슐화가 깨진다. 비정적 데이터 멤버는 전부 private(또는 단순 집합체면 전부 public)으로 통일한다.Mixed access levels on data members let some be modified directly from outside while others change only through methods, scattering responsibility for invariants and breaking encapsulation. Make non-static data members all private (or all public for a plain aggregate).
M15섹션 15Section 15
Rule 15.0.1Required · DecidablePDF example
특수 멤버 함수를 일관되게 제공한다(Rule of Five)Special member functions shall be provided consistently (Rule of Five)
❌ 위반 예시Non-compliant example
struct PolyBaseWrong // Non-compliant - base class that is not an aggregate struct NonEmptyDestructor // Non-compliant - copy-enabled class with a customized ~NonEmptyDestructor() // Non-compliant - customized destructor has empty body struct NonMovable // Non-compliant - copy-constructible, but not
✅ 준수 예시Compliant example
struct MyTagClass {}; // Compliant - Rule of Zero (empty class)
struct MyValue // Compliant - Rule of Zero
struct PolyBase // Compliant - unmovable base class with virtual public
struct Locker // Compliant - scoped manager
struct Child : Aggregate // Compliant by exception - base class without⚠️ 소멸자·복사·이동 중 하나만 정의하면 나머지는 컴파일러 기본 구현이 쓰이는데, 자원을 소유한 클래스에서는 기본 복사가 얕은 복사가 되어 이중 해제·댕글링을 일으킨다. 특수 멤버 집합(Rule of Five)을 일관되게 정의하거나 명시적으로 삭제(=delete)하고, 가능하면 스마트 포인터로 소유권을 위임한다.Defining only one of destructor/copy/move leaves the rest to compiler defaults, and for a resource-owning class the default copy is a shallow copy causing double free or dangling. Provide the special-member set (Rule of Five) consistently or explicitly =delete them, and prefer delegating ownership to smart pointers.
Rule 15.0.2Advisory · DecidablePDF example
사용자 제공 복사/이동 멤버 함수는 적절한 시그니처를 가진다User-provided copy and move member functions should have the correct signature
❌ 위반 예시Non-compliant example
UniqueManager & operator=( UniqueManager && ) noexcept; // Non-compliant - Manager( Manager && other, char c = 'x' ) noexcept; // Non-compliant - Bad( Bad volatile const & ); // Non-compliant - volatile virtual Bad & operator=( Bad const & ) &; // Non-compliant - virtual
✅ 준수 예시Compliant example
UniqueManager( UniqueManager && ) noexcept; // Compliant Manager( Manager const & other ) noexcept( false ); // Compliant
⚠️ 복사 생성자의 매개변수가 const& 가 아니면 const 객체·임시객체를 복사할 수 없고, 대입 연산자가 참조 대신 값을 반환하면 a = b = c 같은 연쇄 대입이나 표준 알고리즘과 어긋난다. 관례에 따라 const& 매개변수와 *this 참조 반환 시그니처를 사용한다.A copy constructor whose parameter is not const& cannot copy const or temporary objects, and an assignment operator that returns by value rather than reference breaks chained assignment (a = b = c) and standard algorithms. Follow the convention of a const& parameter and returning a reference to *this.
Rule 15.1.1Required · UndecidablePDF example
생성자/소멸자 본문에서 가상 디스패치에 의존하지 않는다A virtual function shall not be called from a constructor or destructor in a way that relies on dynamic type
❌ 위반 예시Non-compliant example
class B4;
class B3
{
explicit B3( B4 * b );
virtual ~B3();
virtual void foo();
};
class B4 : public B3
{
B4() : B3( this ) { }
};
B3::B3( B4 * b )
{
foo(); // Non-compliant - calls B3::foo
this->foo(); // Non-compliant - calls B3::foo
b->foo(); // Non-compliant - undefined behaviour
}✅ 준수 예시Compliant example
{
typeid( *this ); // Compliant - B1 not polymorphic
}
};⚠️ 생성자·소멸자가 실행되는 동안 객체의 동적 타입은 현재 생성/소멸 중인 클래스이므로, 그 안에서 가상 함수를 부르면 파생 클래스의 재정의가 아니라 현재 클래스 버전이 호출되어 의도와 다르게 동작한다. 가상 디스패치가 필요한 초기화는 객체 생성이 완료된 뒤에 호출한다.During a constructor or destructor the object’s dynamic type is the class currently being constructed/destroyed, so calling a virtual function invokes that class’s version, not the derived override — behaving unexpectedly. Perform initialization that needs virtual dispatch after the object is fully constructed.
Rule 15.1.2Advisory · DecidablePDF example
모든 생성자는 기반 클래스 생성자를 명시적으로 호출한다All constructors should explicitly call a base class constructor
❌ 위반 예시Non-compliant example
D() {} // Non-compliant
};✅ 준수 예시Compliant example
B() {} // Compliant by exception
};
class V
{⚠️ 파생 생성자가 기반 생성자를 명시적으로 호출하지 않으면 기본 생성에 의존하게 되어 초기화 의도가 흐려지고, 기반에 기본 생성자가 없으면 아예 컴파일되지 않는다. 모든 생성자에서 적절한 기반 생성자를 초기화 목록에 명시해 초기화 경로를 분명히 한다.If a derived constructor does not explicitly call a base constructor it relies on default construction, obscuring initialization intent, and fails to compile when the base has no default constructor. Name the appropriate base constructor in every constructor’s initializer list to make the initialization path explicit.
Rule 15.1.3Required · DecidablePDF example
단일 인자 변환 생성자/연산자는 explicit로 선언한다Conversion operators and constructors callable with a single argument shall be explicit
❌ 위반 예시Non-compliant example
C( int32_t a ); // Non-compliant operator int32_t() const; // Non-compliant E( int32_t a, int32_t b = 0 ); // Non-compliant - callable with one argument E( char a = 'a', int32_t b = 0 ); // Non-compliant - callable with one argument
✅ 준수 예시Compliant example
explicit D( int32_t a ); // Compliant explicit operator bool() const; // Compliant
⚠️ 단일 인자로 호출 가능한 생성자나 변환 연산자가 암묵 변환을 허용하면, 의도하지 않은 형변환이 조용히 일어나 잘못된 단위·타입이 함수에 전달되는 결함을 만든다. explicit 로 선언해 변환을 의도적으로 명시할 때만 일어나게 한다.A constructor or conversion operator callable with a single argument that permits implicit conversion lets unintended conversions happen silently, passing the wrong unit or type into functions. Declare it explicit so conversion happens only when deliberately spelled out.
Rule 15.1.4Advisory · UndecidablePDF example
클래스의 모든 직접 비정적 데이터 멤버를 초기화한다All direct non-static data members of a class shall be initialized
❌ 위반 예시Non-compliant example
name { name } // Non-compliant - age not initialized
PersonClass() = default; // Non-compliant - age not initialized
PersonAggregate p1; // Non-compliant - age not initialized, even though
class Building // Non-compliant - height not initialized in the
using Base::Base; // Non-compliant - b not initialized by the✅ 준수 예시Compliant example
name { name }, age { age } // Compliant
age { age } // Compliant - name is default constructed,
PersonAggregate p2 {}; // Compliant - name is default constructed, and age is⚠️ 생성자에서 일부 데이터 멤버를 초기화하지 않으면 객체가 부분적으로 비결정적 상태가 되어, 그 멤버를 읽는 순간 재현 불가한 버그가 발생한다. 기본 멤버 초기자(int x{0};)나 초기화 목록으로 모든 직접 비정적 멤버를 빠짐없이 초기화한다.Leaving some data members uninitialized in a constructor puts the object in a partially non-deterministic state, producing irreproducible bugs the moment such a member is read. Initialize every direct non-static member via default member initializers (int x{0};) or the initializer list.
Rule 15.1.5Required · DecidablePDF example
initializer-list 생성자는 그것이 유일한 생성자일 때만 정의한다An initializer-list constructor should be the only constructor when provided
❌ 위반 예시Non-compliant example
class A // Non-compliant
{✅ 준수 예시Compliant example
A( std::size_t x, std::size_t y );
A( std::initializer_list< std::size_t > list );
};
class B // Compliant - no initializer-list constructor
{⚠️ initializer-list 생성자가 다른 생성자와 공존하면, 중괄호 초기화 Vec{5} 가 "원소 5 하나" 인지 "count=5" 인지 오버로드 해석이 initializer-list 쪽을 강하게 선호해 의도와 다른 생성자가 선택된다. 둘 중 의도에 맞는 하나만 두어 모호함을 없앤다.When an initializer-list constructor coexists with other constructors, brace initialization like Vec{5} is strongly biased toward the initializer-list overload, so it may pick a different constructor than intended ("one element 5" vs "count=5"). Keep only the one that matches intent to remove the ambiguity.
M16섹션 16Section 16
Rule 16.5.1Required · DecidablePDF example
논리 AND(&&)·OR(||) 연산자를 오버로드하지 않는다The logical && and || operators shall not be overloaded
❌ 위반 예시Non-compliant example
bool isOvertaking();
bool increaseSpeed();
};
bool operator&&( FuzzyBool fb, bool b ); // Non-compliant
template< class Vehicle >
void f( Vehicle & v )
{
if ( v.isOvertaking() && v.increaseSpeed() )
{
}
}✅ 준수 예시Compliant example
#include <iostream>
struct Cond {
bool v;
explicit operator bool() const { return v; } // bool 변환만 제공
};
int main(){ Cond a{false}, b{true}; std::cout << (a && b) << '\n'; } // 내장 && 의 단락 평가 유지⚠️ &&/|| 를 오버로드하면 일반 함수 호출이 되어 내장 연산자의 단락 평가(short-circuit)가 사라지고 두 피연산자가 항상 평가되므로, 좌변으로 우변을 보호하던 코드(예: p != nullptr && p->ok())가 깨진다. 대신 explicit operator bool 등을 제공해 내장 &&/|| 의 단락 평가를 유지한다.Overloading && or || turns them into ordinary function calls, losing the built-in short-circuit so both operands are always evaluated, breaking code that guards the right operand with the left (e.g., p != nullptr && p->ok()). Provide explicit operator bool instead, preserving the built-in short-circuit of && and ||.
Rule 16.5.2Required · DecidablePDF example
주소 연산자(단항 &)를 오버로드하지 않는다The unary & operator shall not be overloaded
❌ 위반 예시Non-compliant example
A * operator&(); // Non-compliant };
✅ 준수 예시Compliant example
#include <iostream>
struct Handle {
int id;
int key() const { return id; } // 의도를 별도 이름 함수로 표현
};
int main(){ Handle h{7}; Handle* p = &h; std::cout << (p->id) << '\n'; } // & 는 정상적으로 주소⚠️ 단항 & 를 오버로드하면 그 타입의 실제 주소를 얻을 수 없게 되어, 객체 주소를 가정하는 표준 라이브러리(std::addressof 없이 쓰는 코드)와 일반 코드가 조용히 깨진다. 주소가 아닌 의미(키·식별자 반환 등)는 별도 명명 함수로 표현하고 & 는 본래 의미를 유지한다.Overloading unary & makes it impossible to obtain the type’s real address, silently breaking standard-library and generic code that assumes the object’s address. Express non-address meanings (returning a key or identifier) with a separately named function and keep & for its original meaning.
Rule 16.6.1Advisory · DecidablePDF example
대칭 이항 연산자는 비멤버 함수로 구현한다Symmetric binary operators should be implemented as non-member functions
❌ 위반 예시Non-compliant example
C operator+( C rhs ) const; // Non-compliant C operator+( int32_t rhs ) const; // Non-compliant C operator and( C rhs ) const; // Non-compliant
✅ 준수 예시Compliant example
friend C operator*( C lhs, C rhs ); // Compliant - non-member friend friend C operator-( C lhs, C rhs ) // Compliant - hidden friend C operator/( C lhs, C rhs ); // Compliant - non-member C operator*( C lhs, C rhs ); // Compliant - non-member friend
⚠️ + 나 == 같은 대칭 이항 연산자를 멤버 함수로 두면 좌측 피연산자에는 암묵 변환이 적용되지 않아, 100 + m 처럼 좌측이 변환 대상인 경우 a + b 와 b + a 의 동작이 달라지는 비대칭이 생긴다. 대칭 연산자는 비멤버 함수로 구현해 양쪽 피연산자에 동일한 변환 규칙이 적용되게 한다.Implementing a symmetric binary operator like + or == as a member means no implicit conversion applies to the left operand, so when the left side needs conversion (e.g., 100 + m) a + b and b + a behave differently — an asymmetry. Implement symmetric operators as non-member functions so the same conversion rules apply to both operands.
M17섹션 17Section 17
Rule 17.8.1Advisory · DecidablePDF example
함수 템플릿의 명시적 특수화를 사용하지 않는다Function templates should not be explicitly specialized
❌ 위반 예시Non-compliant example
template< typename T > void f1( T ); // Overload # 1A
template<> void f1< char * >( char * ); // Non-compliant - explicit
// specialization of overload # 1A
template< typename T > void f1( T * ); // Overload # 1B
template< typename T > void f2( T ); // Overload # 2A
template< typename T > void f2( T * ); // Overload # 2B
void f2( char * ); // Overload # 2C - rule does not apply
template< typename T > void f3( T );
template<> void f3< char * >( char * ); // Non-compliant - explicit
// specialization of f3
void b( char * s )
{
f1( s ); // Calls overload # 1B, with T = char
f2( s ); // Calls overload # 2C
}✅ 준수 예시Compliant example
#include <iostream>
template <typename T> void f(T){ std::cout << "generic\n"; }
void f(int){ std::cout << "int overload\n"; } // 일반 오버로드
int main(){ f(3); }⚠️ 함수 템플릿의 명시적 특수화는 오버로드 해석에 직접 참여하지 않고 이미 선택된 기본 템플릿에 한해 적용되므로, 일반 오버로드가 함께 있으면 직관과 다른 함수가 선택되는 함정을 만든다. 동작을 분기하려면 명시적 특수화 대신 일반 함수 오버로드를 사용한다.An explicit function-template specialization does not take part in overload resolution directly but only applies once the primary template is chosen, so with overloads present an unexpected function may be selected. Use ordinary function overloads instead of explicit specialization to branch behaviour.
M18섹션 18Section 18
Rule 18.1.1Required · DecidablePDF example
예외는 값으로 throw 한다(포인터로 throw 금지)An exception object shall be thrown by value, not by pointer
❌ 위반 예시Non-compliant example
class A
{
// Implementation
};
void fn( int16_t i )
{
static A a1;
A * a2 = new A;
if ( i > 10 )
{
throw &a1; // Non-compliant - pointer type thrown
}✅ 준수 예시Compliant example
#include <stdexcept>
#include <iostream>
struct MyError : std::runtime_error { using std::runtime_error::runtime_error; };
int main(){
try { throw MyError("disk"); } // 값으로 throw
catch (const MyError& e){ std::cout << e.what() << '\n'; } // const 참조로 catch
}⚠️ 예외를 포인터로 던지면 예외 객체를 누가·언제 해제해야 하는지 모호해져, catch 측이 delete 를 빠뜨리면 누수, 중복 delete 하면 이중 해제가 발생한다. 예외는 값으로 던지고 const 참조로 잡아 수명을 런타임이 자동 관리하게 한다.Throwing an exception by pointer makes it unclear who frees the object and when, so the catch site leaks if it forgets delete or double-frees if it deletes twice. Throw by value and catch by const reference so the runtime manages the lifetime automatically.
Rule 18.1.2Required · DecidablePDF example
An empty throw shall only occur within the compound-statement of a catch handlerAn empty throw shall only occur within the compound-statement of a catch handler
❌ 위반 예시Non-compliant example
throw; // Non-compliant - not syntactically within a catch
✅ 준수 예시Compliant example
throw; // Compliant - re-throws an exception object
⚠️ Rule 18.1.2 (An empty throw shall only occur within the compound-statement of a catch handler)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 18.1.2 (An empty throw shall only occur within the compound-statement of a catch handler) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 18.3.1Advisory · DecidablePDF example
There should be at least one exception handler to catch all otherwise unhandled exceptionsThere should be at least one exception handler to catch all otherwise unhandled exceptions
❌ 위반 예시Non-compliant example
catch ( ... ) // Catch-all handler
{
try
{
logError( "Unexpected" );
}
catch (...)
{
// Logging also threw
}
}
int main() // Non-compliant - handler may throw
try
{
// Program code
}
catch ( ... ) // Catch-all handler
{
logError( "Unexpected"); // Potentially throwing function may lead to
} // an exception propagating from main✅ 준수 예시Compliant example
int main() // Compliant
{
try
{
// Program code
}
catch ( specific_type & e ) // Optional, explicit handler(s) are permitted
{
// Handle expected exceptions
}
catch ( ... ) // Catch-all handler should be provided
{
// Handle unexpected exceptions
}
return 0;
}
void logError( char const * message );
int main() // Compliant
try
{
// Program code
}⚠️ Rule 18.3.1 (There should be at least one exception handler to catch all otherwise unhandled exceptions)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 18.3.1 (There should be at least one exception handler to catch all otherwise unhandled exceptions) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 18.3.2Required · DecidablePDF example
예외는 const 참조(const lvalue reference)로 catch 한다Exceptions shall be caught by const lvalue reference
❌ 위반 예시Non-compliant example
catch ( std::runtime_error e ) // Non-compliant - slicing occurs
✅ 준수 예시Compliant example
catch ( std::exception const & e ) // Compliant - exception object is complete
⚠️ 예외를 값으로 잡으면 던져진 파생 예외 객체가 base 타입으로 복사되며 슬라이싱되어, 파생 클래스가 담고 있던 정보와 다형적 what() 동작을 잃는다. const 참조로 잡으면 복사 없이 다형성을 보존하고 불필요한 사본도 피한다.Catching by value copies the thrown derived exception into the base type, slicing off the derived information and polymorphic what() behaviour. Catching by const reference preserves polymorphism without a copy and avoids an unnecessary duplicate.
Rule 18.3.3Required · DecidablePDF example
Handlers for a function-try-block of a constructor or destructor shall not refer to non-static members from their class or its basesHandlers for a function-try-block of a constructor or destructor shall not refer to non-static members from their class or its bases
❌ 위반 예시Non-compliant example
try : x { mayThrow() }
{
}
catch ( ... )
{
if ( 0 == x ) // Non-compliant - x may not exist at this point
{
}
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 18.3.3 (Handlers for a function-try-block of a constructor or destructor shall not refer to non-static members from their class or its bases)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 18.3.3 (Handlers for a function-try-block of a constructor or destructor shall not refer to non-static members from their class or its bases) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 18.4.1Required · DecidablePDF example
예외를 던지지 않는 함수는 noexcept 로 표시하고 명세를 준수한다A function declared noexcept shall not exit via an exception
❌ 위반 예시Non-compliant example
C2( C2 && other ) {} // Non-compliant - move constructor
C2 & operator=( C2 && other ); // Non-compliant - move assignment
friend void swap( C2 &, C2 & ); // Non-compliant - function named swap
C2 c2; // Non-compliant - construction is non-local
~C3() noexcept( false ) {} // Non-compliant
class MyException : public std::exception // Non-compliant - implicit copy
void exit_handler1(); // Non-compliant - passed to atexit
f( [](){} ); // Non-compliant - function passed to extern "C"✅ 준수 예시Compliant example
C1(){} // Compliant - never used at non-local scope
~C1(){} // Compliant - noexcept by default
~C2() noexcept( true ) {} // Compliant
C3(){} // Compliant - c3 in foo not in non-local scope
static C3 c3; // Compliant - constructed on first call to foo
void exit_handler2() noexcept; // Compliant - also passed to atexit⚠️ noexcept 로 선언한 함수에서 예외가 빠져나가면 C++ 런타임은 즉시 std::terminate 를 호출해 프로그램을 강제 종료한다. noexcept 함수는 내부에서 모든 예외를 처리하거나, 예외가 나갈 수 있다면 noexcept 명세를 제거한다.If an exception escapes a function declared noexcept, the C++ runtime immediately calls std::terminate, forcibly ending the program. A noexcept function must handle all exceptions internally, or its noexcept specification must be removed if exceptions can escape.
Rule 18.5.1Required · DecidablePDF example
소멸자나 해제 연산에서 예외가 빠져나가지 않게 한다A destructor shall not exit via an exception
❌ 위반 예시Non-compliant example
throw std::exception {}; // Non-compliant - destructor is implicitly noexcept
throw std::exception {}; // Non-compliant✅ 준수 예시Compliant example
template< class T > // Compliant
⚠️ 예외로 인한 스택 풀기(unwinding) 도중 또 다른 예외가 소멸자에서 탈출하면 C++ 는 동시에 두 예외를 처리할 수 없어 std::terminate 를 호출한다. 소멸자는 noexcept 로 두고 내부에서 발생할 수 있는 예외를 try/catch 로 흡수(로깅 후 무시)한다.If, during stack unwinding caused by one exception, another escapes a destructor, C++ cannot handle two simultaneously and calls std::terminate. Make destructors noexcept and absorb any internal exceptions with try/catch (log and swallow).
Rule 18.5.2Advisory · DecidablePDF rule
프로그램 종료 함수를 사용하지 않아야 한다Program-terminating functions should not be used
❌ 위반 예시Non-compliant example
void load(const Config& c) {
if (!c.valid()) {
std::exit(1); // 스택 언와인딩·소멸자 호출 없이 즉시 종료
}
}✅ 준수 예시Compliant example
struct ConfigError {};
void load(const Config& c) {
if (!c.valid()) {
throw ConfigError{}; // 예외로 정상 언와인딩 → 소멸자가 자원 해제
}
}⚠️ abort/exit/_Exit/quick_exit/terminate 호출은 스택 언와인딩과 소멸자 호출을 건너뛰어, 잠긴 파일 등 자원을 비정상 상태로 남길 수 있다. 예외나 반환값으로 정상 흐름을 통해 종료해야 한다.Calling abort/exit/_Exit/quick_exit/terminate skips stack unwinding and destructors, potentially leaving resources (e.g. a locked file) in a bad state; signal termination via exceptions or return values instead.
M19섹션 19Section 19
Rule 19.0.1Required · DecidablePDF example
A line whose first token is # shall be a valid preprocessing directiveA line whose first token is # shall be a valid preprocessing directive
❌ 위반 예시Non-compliant example
#define AAA 2
int32_t foo()
{
int32_t x = 0;
#ifndef AAA
x = 1;
#else1 // Non-compliant
x = AAA;
#endif
return x;
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 19.0.1 (A line whose first token is # shall be a valid preprocessing directive)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.0.1 (A line whose first token is # shall be a valid preprocessing directive) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.0.2Required · DecidablePDF example
함수형 매크로보다 inline/constexpr 함수를 사용한다A function-like macro shall not be used where an inline or constexpr function can be used
❌ 위반 예시Non-compliant example
#define FUNC( X ) \
( ( X ) + ( X ) ) // Non-compliant
template< typename T >
constexpr auto func( T x ) // Possible alternative
{
return x + x;
}✅ 준수 예시Compliant example
#define ID( name ) \
constexpr auto name = #name; // Compliant - use of #
#define TAG( name ) \
class name##Tag {}; // Compliant - use of ##
#define LOG( message ) \
log( __func__, message ); // Compliant - use of __func__⚠️ 함수형 매크로는 인자를 본문에 그대로 펼쳐 i++ 같은 부작용을 여러 번 평가하고 타입 검사도 하지 못해, 미정의 동작과 진단되지 않는 버그를 만든다. inline·constexpr(템플릿) 함수는 동일한 성능에 인자를 한 번만 평가하고 타입 안전성까지 제공한다.A function-like macro pastes its argument into the body, evaluating side effects like i++ multiple times and skipping type checking, producing undefined behaviour and silent bugs. An inline/constexpr (template) function gives the same performance while evaluating the argument once and enforcing type safety.
Rule 19.0.3Advisory · DecidablePDF example
#include directives should only be preceded by preprocessor directives or comments#include directives should only be preceded by preprocessor directives or comments
❌ 위반 예시Non-compliant example
#include "f.h" // Non-compliant #include "e.h" // Non-compliant
✅ 준수 예시Compliant example
#include "a.h" // Compliant #include "b.h" // Compliant #include "c.h" // Compliant #include "d.h" // Compliant
⚠️ Rule 19.0.3 (#include directives should only be preceded by preprocessor directives or comments)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.0.3 (#include directives should only be preceded by preprocessor directives or comments) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.0.4Advisory · DecidablePDF example
#undef should only be used for macros defined previously in the same file#undef should only be used for macros defined previously in the same file
❌ 위반 예시Non-compliant example
#undef M // Non-compliant - defined in another file
✅ 준수 예시Compliant example
#undef ID // Compliant - defined in this file
⚠️ Rule 19.0.4 (#undef should only be used for macros defined previously in the same file)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.0.4 (#undef should only be used for macros defined previously in the same file) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.1.1Required · DecidablePDF example
#include 에는 올바른 헤더명 형식만 사용한다The #include directive shall be followed by a valid header name
❌ 위반 예시Non-compliant example
#if defined 1 // Non-compliant - 1 is not an #if FEATURE(X) // Non-compliant - defined resulting
✅ 준수 예시Compliant example
#if defined(x) && ( x != 0 ) // Compliant
⚠️ 매크로 확장으로 헤더명을 만들면 확장 결과가 올바른 <...> 또는 "..." 형식이 된다는 보장이 없어, 컴파일러·이식 환경마다 다르게 해석될 위험이 있다. #include 에는 헤더명을 직접 적어 형식을 고정한다.Generating a header name via macro expansion does not guarantee the result is a valid <...> or "..." form, risking different interpretations across compilers and ports. Write the header name directly in #include to fix the form.
Rule 19.1.2Required · DecidablePDF example
All #else, #elif and #endif preprocessor directives shall reside in the same file as the #if, #ifdef or #ifndef directive to which they are relatedAll #else, #elif and #endif preprocessor directives shall reside in the same file as the #if, #ifdef or #ifndef directive to which they are related
❌ 위반 예시Non-compliant example
#if 1 // Non-compliant
✅ 준수 예시Compliant example
#ifdef A // Compliant #if 1 // Compliant
⚠️ Rule 19.1.2 (All #else, #elif and #endif preprocessor directives shall reside in the same file as the #if, #ifdef or #ifndef directive to which they are related)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.1.2 (All #else, #elif and #endif preprocessor directives shall reside in the same file as the #if, #ifdef or #ifndef directive to which they are related) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.1.3Required · DecidablePDF example
All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be defined prior to evaluationAll identifiers used in the controlling expression of #if or #elif preprocessing directives shall be defined prior to evaluation
❌ 위반 예시Non-compliant example
#if M == 0 // Non-compliant
✅ 준수 예시Compliant example
#if defined( N ) // Compliant - N is not evaluated, even if not a macro #if N == 0 // Compliant - N is known to be defined at this point // Compliant - B is only evaluated in ( B == 0 ) if it is defined
⚠️ Rule 19.1.3 (All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be defined prior to evaluation)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.1.3 (All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be defined prior to evaluation) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.2.1Required · DecidablePDF example
Precautions shall be taken in order to prevent the contents of a header %le being included more than oncePrecautions shall be taken in order to prevent the contents of a header %le being included more than once
❌ 위반 예시Non-compliant example
// file.h #ifndef FILE_H // Non-compliant - no include guard in this file #define FILEH // <-- this does not #define FILE_H #endif
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 19.2.1 (Precautions shall be taken in order to prevent the contents of a header %le being included more than once)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.2.1 (Precautions shall be taken in order to prevent the contents of a header %le being included more than once) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.2.2Required · DecidablePDF example
The #include directive shall be followed by either a <filename> or "filename" sequenceThe #include directive shall be followed by either a <filename> or "filename" sequence
❌ 위반 예시Non-compliant example
#include another.h // Non-compliant #include FILENAME // Non-compliant #include BASE EXT // Non-compliant - expands to an invalid form
✅ 준수 예시Compliant example
#include <filename.h> // Compliant #include "filename.h" // Compliant #include "./include/cpu.h" // Compliant - filename may include a path #include HEADER // Compliant
⚠️ Rule 19.2.2 (The #include directive shall be followed by either a <filename> or "filename" sequence)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.2.2 (The #include directive shall be followed by either a <filename> or "filename" sequence) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.2.3Required · DecidablePDF example
The ' or " or \ characters and the /* or // character sequences shall not occur in a header %le nameThe ' or " or \ characters and the /* or // character sequences shall not occur in a header %le name
❌ 위반 예시Non-compliant example
#include "fi'le.h" // Non-compliant #include "path\file" // Non-compliant #include "path\\file" // Non-compliant
✅ 준수 예시Compliant example
#include "file.h" // Compliant #include "path/file" // Compliant
⚠️ Rule 19.2.3 (The ' or " or \ characters and the /* or // character sequences shall not occur in a header %le name)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.2.3 (The ' or " or \ characters and the /* or // character sequences shall not occur in a header %le name) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.3.1Advisory · DecidablePDF rule
# 및 ## 전처리기 연산자를 사용하지 않아야 한다The # and ## preprocessor operators should not be used
❌ 위반 예시Non-compliant example
#define NAME(x) #x // 스트링화(stringize) 연산자 #define JOIN(a,b) a##b // 토큰 결합(concatenation) 연산자 const char* s = NAME(value); int JOIN(foo, 1) = 0;
✅ 준수 예시Compliant example
// 전처리기 # / ## 대신 타입 안전한 언어 기능 사용 constexpr const char* s = "value"; int foo1 = 0; template <class T> const char* name(); // 필요 시 함수/템플릿으로 대체
⚠️ 여러 #/## 또는 혼합 사용 시 평가 순서가 unspecified 라 매크로 확장 결과를 예측하기 어렵고, ## 는 코드 가독성을 떨어뜨린다. constexpr·템플릿 등 언어 기능으로 대체한다.The evaluation order of multiple/mixed # and ## operators is unspecified, making macro expansion unpredictable, and ## hurts readability; replace with language features such as constexpr and templates.
Rule 19.3.2Required · DecidablePDF example
A macro parameter immediately following a # operator shall not be immediately followed by a ## operatorA macro parameter immediately following a # operator shall not be immediately followed by a ## operator
❌ 위반 예시Non-compliant example
#define D( x, y ) #x ## y // Non-compliant
✅ 준수 예시Compliant example
#define A( x ) #x // Compliant #define B( x, y ) x ## y // Compliant #define C( x, y ) x ## #y // Compliant
⚠️ Rule 19.3.2 (A macro parameter immediately following a # operator shall not be immediately followed by a ## operator)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.3.2 (A macro parameter immediately following a # operator shall not be immediately followed by a ## operator) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.3.3Required · DecidablePDF example
The argument to a mixed-use macro parameter shall not be subject to further expansionThe argument to a mixed-use macro parameter shall not be subject to further expansion
❌ 위반 예시Non-compliant example
int32_t scaled_AA = SCALE( AA ); // Non-compliant - AA is expanded further
✅ 준수 예시Compliant example
int32_t scaled_speed = SCALE( speed ); // Compliant - speed not expanded
⚠️ Rule 19.3.3 (The argument to a mixed-use macro parameter shall not be subject to further expansion)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.3.3 (The argument to a mixed-use macro parameter shall not be subject to further expansion) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.3.4Required · DecidablePDF example
함수형 매크로 매개변수는 괄호로 감싼다Parameters in a function-like macro shall be enclosed in parentheses
❌ 위반 예시Non-compliant example
#define M1( x, y ) ( x * y )
r = M1( 1 + 2, 3 ); // Non-compliant - x not parenthesized
// Expands as r = ( 1 + 2 * 3 );✅ 준수 예시Compliant example
#define PROP( Type, Name ) \
Type Name; \
Type get_##Name() { return Name; }
struct Student
{
PROP( vector< int32_t >, grades );
}⚠️ 함수형 매크로에서 매개변수와 전체 식을 괄호로 감싸지 않으면, 전개 시 호출부 표현식과 매크로 본문의 연산자 우선순위가 섞여 SCALE(a+b) 가 a + b*2 처럼 의도와 다른 식이 된다. 각 매개변수와 결과 전체를 괄호로 보호한다(다만 가능하면 inline 함수를 우선한다).Without parenthesizing the parameters and the whole expression, expansion mixes the caller’s expression with the macro body’s operator precedence, turning SCALE(a+b) into a + b*2. Protect each parameter and the entire result with parentheses (though an inline function is preferable).
Rule 19.3.5Required · DecidablePDF example
Tokens that look like a preprocessing directive shall not occur within a macro argumentTokens that look like a preprocessing directive shall not occur within a macro argument
❌ 위반 예시Non-compliant example
#ifdef SW // Non-compliant
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 19.3.5 (Tokens that look like a preprocessing directive shall not occur within a macro argument)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.3.5 (Tokens that look like a preprocessing directive shall not occur within a macro argument) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 19.6.1Advisory · DecidablePDF example
The #pragma directive and the _Pragma operator should not be usedThe #pragma directive and the _Pragma operator should not be used
❌ 위반 예시Non-compliant example
#pragma once // Non-compliant #define P( x ) _Pragma( #x ) // Non-compliant _Pragma( "once" ) // Non-compliant
⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 19.6.1 (The #pragma directive and the _Pragma operator should not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 19.6.1 (The #pragma directive and the _Pragma operator should not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
M21섹션 21Section 21
Rule 21.2.1Required · DecidablePDF example
<cstdio> 의 표준 입출력 기능을 사용하지 않는다The C Standard Library input/output functions shall not be used
❌ 위반 예시Non-compliant example
int32_t f( const char * numstr )
{
return atoi( numstr ); // Non-compliant
}✅ 준수 예시Compliant example
#include <iostream>
int main(){
int v = 42;
std::cout << "v=" << v << '\n'; // 타입 안전한 스트림
}⚠️ cstdio 의 printf 계열은 포맷 문자열과 인자의 타입 일치를 컴파일러가 강제하지 못해, 불일치 시 미정의 동작과 포맷 문자열 취약점을 부른다. 타입 안전한 C++ 스트림(std::cout)이나 검증된 전용 I/O 계층을 사용한다.The printf family in cstdio does not have the compiler enforce type agreement between the format string and arguments, so mismatches cause undefined behaviour and format-string vulnerabilities. Use type-safe C++ streams (std::cout) or a validated dedicated I/O layer.
Rule 21.2.2Required · DecidablePDF example
The string handling functions from <cstring>, <cstdlib>, <cwchar> and <cinttypes> shall not be usedThe string handling functions from <cstring>, <cstdlib>, <cwchar> and <cinttypes> shall not be used
❌ 위반 예시Non-compliant example
void f1( char * buffer, size_t bufferSize )
{
char const * str = "Msg";
if ( ( strlen( str ) + 1u ) < bufferSize ) // Non-compliant
{
( void ) strcpy( buffer, str ); // Non-compliant
}
}✅ 준수 예시Compliant example
void f2( char * buffer, size_t bufferSize )
{
std::string_view str = "Msg";
if ( str.size() + 1u < bufferSize )
{
str.copy( buffer, str.size() );
buffer[ str.size() ] = 0;
}
}⚠️ Rule 21.2.2 (The string handling functions from <cstring>, <cstdlib>, <cwchar> and <cinttypes> shall not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 21.2.2 (The string handling functions from <cstring>, <cstdlib>, <cwchar> and <cinttypes> shall not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 21.2.3Required · DecidablePDF rule
<cstdlib>의 system 함수를 사용하지 않아야 한다The library function system from <cstdlib> shall not be used
❌ 위반 예시Non-compliant example
#include <cstdlib>
void run(const std::string& name) {
std::system(("rm " + name).c_str()); // 셸 주입·미정의 동작 위험
}✅ 준수 예시Compliant example
#include <cstdio>
void run(const std::string& path) {
std::remove(path.c_str()); // 셸을 거치지 않는 표준 API 사용
}⚠️ system 은 미정의·구현 정의 동작을 가지며 명령 주입 등 보안 취약점의 흔한 원인이다(<stdlib.h> 의 system 에도 동일 적용). 셸을 거치지 않는 전용 API로 대체한다.system has undefined and implementation-defined behaviour and is a common source of security flaws such as command injection (the same applies to system from <stdlib.h>); use dedicated, non-shell APIs.
Rule 21.2.4Required · DecidablePDF example
The macro offsetof shall not be usedThe macro offsetof shall not be used
❌ 위반 예시Non-compliant example
struct A
{
int32_t i;
};
void f1()
{
offsetof( A, i ); // Non-compliant
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 21.2.4 (The macro offsetof shall not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 21.2.4 (The macro offsetof shall not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 21.6.1Advisory · DecidablePDF example
동적 메모리는 직접 new/delete 대신 스마트 포인터로 관리한다Dynamic memory should be managed with smart pointers rather than raw new/delete
❌ 위반 예시Non-compliant example
auto i = std::make_unique< int32_t >( 42 ); // Non-compliant
auto j = std::vector< int32_t > {}; // Non-compliant✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
struct Widget { int v{7}; };
static void use(){
auto w = std::make_unique<Widget>(); // 모든 경로에서 자동 해제
if (w->v == 0) { return; }
std::cout << w->v << '\n';
}
int main(){ use(); }⚠️ 명시적 new/delete 는 중간의 예외나 조기 반환 경로에서 delete 를 빠뜨리면 누수, 중복 실행하면 이중 해제가 되어 수명 관리 책임이 개발자에게 흩어진다. make_unique/make_shared 로 소유권을 스마트 포인터에 위임하면 모든 경로(예외 포함)에서 자동으로 해제된다.Explicit new/delete scatter lifetime responsibility onto the developer — a missed delete on an exception or early-return path leaks, and a duplicated one double-frees. Delegating ownership to make_unique/make_shared releases the object automatically on every path, including exceptions.
Rule 21.6.2Required · DecidablePDF example
delete 의 형태(배열/단일)를 new 의 형태와 일치시킨다The form of delete shall match the form of the corresponding new
❌ 위반 예시Non-compliant example
auto p1 = static_cast< A * >( malloc( sizeof( A ) ) ); // Non-compliant auto p2 = new A; // Non-compliant auto p4 = p3.release(); // Non-compliant void * iptr = mr.allocate( sizeof( A ) ); // Non-compliant delete p; // Non-compliant - undefined behaviour if p was allocated using new[]
✅ 준수 예시Compliant example
auto p3 = std::make_unique< A >(); // Compliant
⚠️ new[] 로 할당한 메모리는 delete[] 로, new 로 할당한 것은 delete 로 해제해야 하며, 형태가 어긋나면 배열 원소들의 소멸자 미호출이나 잘못된 해제 루틴 사용으로 미정의 동작이 된다. std::make_unique<T[]> 나 컨테이너로 올바른 해제를 자동화한다.Memory from new[] must be freed with delete[] and from new with delete; a form mismatch skips element destructors or uses the wrong deallocation routine — undefined behaviour. Automate correct deallocation with std::make_unique<T[]> or a container.
Rule 21.6.3Required · DecidablePDF example
Advanced memory management shall not be usedAdvanced memory management shall not be used
❌ 위반 예시Non-compliant example
struct X { int32_t a; };
int32_t g()
{
alignas( X ) std::byte mem[ sizeof( X ) ];
X * px = new( &mem ) X{ 1 }; // Non-compliant - placement new
px->~X(); // Non-compliant - explicit destructor call
new( px ) X { 2 }; // Non-compliant - placement new
return px->a ; // Undefined behaviour
}
struct A
{
void * operator new( size_t ); // Non-compliant
};✅ 준수 예시Compliant example
auto f() noexcept
{
return new( std::nothrow ) int{ 42 }; // Compliant
}⚠️ Rule 21.6.3 (Advanced memory management shall not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 21.6.3 (Advanced memory management shall not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 21.6.4Required · DecidablePDF example
If a project defines either a sized or unsized version of a global operator delete, then both shall be definedIf a project defines either a sized or unsized version of a global operator delete, then both shall be defined
✅ 준수 예시Compliant example
void operator delete( void * ptr ) noexcept
{
std::free( ptr );
}
void operator delete( void * ptr, std::size_t size ) noexcept
{
delete( ptr );
}⚠️ 이 규칙은 원문에 대응하는 위반 예제가 따로 실려 있지 않습니다. 준수 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired non-compliant example in the source standard. Use the compliant example and the notes below.
⚠️ Rule 21.6.4 (If a project defines either a sized or unsized version of a global operator delete, then both shall be defined)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 21.6.4 (If a project defines either a sized or unsized version of a global operator delete, then both shall be defined) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 21.6.5Required · DecidablePDF example
불완전(incomplete) 타입 포인터를 delete 하지 않는다A pointer to an incomplete type shall not be deleted
❌ 위반 예시Non-compliant example
{
delete pImpl; // Non-compliant - at the point of deletion, pImpl points
// to an object of incomplete class type.
}
};
// Header file
class Good
{
class Impl;
Impl * pImpl;✅ 준수 예시Compliant example
~Good();
};
// Implementation file
class Good::Impl
{
};
// Good::Impl is a complete type now
Good::~Good()
{
delete pImpl; // Compliant - at the point of deletion, pImpl points to
// a complete class type.
}⚠️ 불완전 타입(전방 선언만 된 타입) 포인터를 delete 하면 컴파일러가 소멸자와 객체 크기를 몰라 소멸자를 호출하지 않거나 잘못 해제해 누수·메모리 손상이 발생한다. 완전 정의가 보이는 위치에서 삭제하거나, 완전 타입에서 만든 전용 deleter 를 사용한다.Deleting a pointer to an incomplete type (only forward-declared) leaves the compiler unaware of the destructor and object size, so it skips the destructor or frees incorrectly — leaking or corrupting memory. Delete where the complete definition is visible, or use a dedicated deleter created in a complete-type context.
Rule 21.10.1Required · DecidablePDF example
<csetjmp> 의 setjmp/longjmp 를 사용하지 않는다The facilities provided by <csetjmp> shall not be used
❌ 위반 예시Non-compliant example
#include <cstdarg>
void h( va_list ap ) // Non-compliant
{
double y;
y = va_arg( ap, double ); // Non-compliant
}
void f( uint16_t n, ... )
{
uint32_t x;
va_list ap; // Non-compliant
va_start( ap, n ); // Non-compliant
x = va_arg( ap, uint32_t ); // Non-compliant
h( ap );
// Undefined behaviour - ap is indeterminate because va_arg used in h
x = va_arg( ap, uint32_t ); // Non-compliant
// Undefined behaviour - returns without using va_end
}✅ 준수 예시Compliant example
#include <stdexcept>
#include <iostream>
static void work(){ throw std::runtime_error("fail"); }
static void recover(){ std::cout << "recovered\n"; }
int main(){
try { work(); }
catch (const std::exception&) { recover(); } // 예외 — 스택 풀기로 소멸자 호출 보장
return 0;
}⚠️ longjmp 는 중간 스택 프레임의 자동 객체 소멸자를 호출하지 않은 채 점프하므로, RAII 로 관리되는 자원이 해제되지 않아 누수와 C++ 객체 모델 위반이 발생한다. 비국소 제어 이동이 필요하면 예외 처리를 사용해 스택 풀기 시 소멸자가 정상 호출되게 한다.longjmp jumps without invoking the destructors of automatic objects in intermediate frames, so RAII-managed resources are not released, causing leaks and violating the C++ object model. Use exceptions for non-local transfer so destructors run correctly during stack unwinding.
Rule 21.10.2Required · Decidable✓ compilablePDF rule
<csignal> 의 시그널 처리를 사용하지 않는다The signal handling facilities of <csignal> shall not be used
❌ 위반 예시Non-compliant example
#include <csignal>
#include <iostream>
static void handler(int){ /* 핸들러에서 할 수 있는 일이 매우 제한적 */ }
int main(){
std::signal(SIGINT, handler); // 비동기·구현정의 — 안전필수 C++ 에 부적합
std::cout << "running\n";
}✅ 준수 예시Compliant example
#include <iostream>
static bool stop_requested(){ return true; } // 협조적으로 검사하는 상태 플래그
static void step(){ /* 한 단계 처리 */ }
int main(){
while (!stop_requested()) { step(); } // 결정적·추적 가능한 폴링
std::cout << "stopped\n";
}⚠️ 시그널은 임의 시점에 비동기로 끼어들고 핸들러에서 호출 가능한 연산이 매우 제한적이며 동작이 구현정의라, C++ 객체·예외 모델과 충돌하고 안전필수 시스템에서 예측 불가하다. 종료·이벤트 요청은 상태 플래그를 협조적으로 폴링하는 결정적 메커니즘으로 처리한다.Signals interrupt asynchronously at arbitrary points, the operations callable in a handler are very limited, and behaviour is implementation-defined, clashing with the C++ object/exception model and being unpredictable in safety-critical systems. Handle shutdown/event requests via a deterministic mechanism that cooperatively polls a status flag.
Rule 21.10.3Required · DecidablePDF rule
<csignal> 표준 헤더가 제공하는 기능을 사용하지 않아야 한다The facilities provided by the standard header file <csignal> shall not be used
❌ 위반 예시Non-compliant example
#include <csignal>
volatile std::sig_atomic_t g_stop = 0;
void onSig(int) { g_stop = 1; } // 시그널 핸들러 내 동작 제약·미정의 위험
void setup() { std::signal(SIGINT, onSig); }✅ 준수 예시Compliant example
// 시그널 핸들링 대신 협조적 종료 플래그를 일반 제어 흐름으로 관리
#include <atomic>
std::atomic<bool> g_stop{false};
void request_stop() { g_stop.store(true); } // <csignal> 미사용⚠️ 부적절한 시그널 처리는 미정의·구현 정의 동작을 유발한다(<signal.h> 에도 동일 적용). 일반 제어 흐름으로 종료를 관리하라. (예외: 시그널을 끄기 위한 signal(x, SIG_IGN) 호출은 허용)Inappropriate signal handling causes undefined and implementation-defined behaviour (the same applies to <signal.h>); manage termination via normal control flow. (Exception: signal(x, SIG_IGN) to disable a signal is permitted.)
M22섹션 22Section 22
Rule 22.3.1Required · DecidablePDF example
errno 기반 오류 검출에 의존하지 않는다Reliance on errno-based error detection shall be avoided
❌ 위반 예시Non-compliant example
if ( i >= 0 )
{
assert( ( sizeof( int ) == 4 ) && "Bad size" ); // Non-compliant - constant
}✅ 준수 예시Compliant example
static_assert( ( sizeof( int ) == 4 ), "Bad size" ); // Rule does not apply
void f( int32_t i )
{
assert( i < 1000 ); // Compliant - not constant⚠️ 전역 변수 errno 는 어느 호출이 설정했는지 명확하지 않고, 멀티스레드·재진입 환경에서 다른 코드가 덮어쓸 수 있어 오류 출처를 흐린다. 오류는 반환값·std::optional·예외로 함수 인터페이스에서 명시적으로 전달해 호출자가 출처와 처리를 분명히 하게 한다.The global errno does not clearly indicate which call set it and can be overwritten by other code in multithreaded or reentrant contexts, obscuring the error’s origin. Convey errors explicitly through return values, std::optional, or exceptions in the function interface so the caller knows the source and handling.
Rule 22.4.1Required · DecidablePDF example
The literal value zero shall be the only value assigned to errnoThe literal value zero shall be the only value assigned to errno
❌ 위반 예시Non-compliant example
errno = 42; // Non-compliant - non-zero value errno = EINVAL; // Non-compliant - does not expand to literal '0' errno = success; // Non-compliant - must use literal '0'
✅ 준수 예시Compliant example
errno = OK; // Compliant - 'OK' expands to literal '0'
⚠️ Rule 22.4.1 (The literal value zero shall be the only value assigned to errno)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 22.4.1 (The literal value zero shall be the only value assigned to errno) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
M23섹션 23Section 23
Rule 23.11.1Advisory · DecidablePDF example
raw 포인터로 스마트 포인터를 중복 생성해 소유권을 이중으로 만들지 않는다A raw pointer shall not be used to construct multiple independent owning smart pointers
❌ 위반 예시Non-compliant example
auto f1()
{
auto * p1 = new A ();
auto p2 = std::make_unique< A >(); // make_unique may throw
return std::shared_ptr< A >( p1 ); // Non-compliant - memory leak if
} // make_unique throws
auto f2( std::unique_ptr< A > p )
{
auto q = p.get();
// ...
return std::unique_ptr< A >( q ); // Non-compliant - causes double delete
}
void f3( std::shared_ptr< A > a, std::shared_ptr< B > b );
void f4()
{
f3( std::shared_ptr< A >( new A() ),
std::shared_ptr< B >( new B() ) ); // Non-compliant - but well defined
} // in C++17✅ 준수 예시Compliant example
struct A { int8_t i; };
class B { };
void f0()
{
auto p = std::make_shared< A > (); // Compliant
int8_t * pi = &( p->i );
std::shared_ptr< int8_t > q ( p, pi ); // Does not apply - not taking ownership
}⚠️ 같은 raw 포인터로 서로 독립된 shared_ptr 를 만들면 각자 별도의 제어 블록(참조 카운트)을 가져, 둘이 각각 0이 될 때 같은 메모리를 두 번 해제하는 이중 해제가 발생한다. make_shared 로 한 번만 생성하고 복사로 소유권을 공유해 단일 제어 블록을 유지한다.Constructing independent shared_ptrs from the same raw pointer gives each its own control block (reference count), so when both reach zero the same memory is freed twice — a double free. Create once with make_shared and share ownership by copying to keep a single control block.
M24섹션 24Section 24
Rule 24.5.1Required · DecidablePDF example
<cstring> 의 경계 없는 문자열 함수를 사용하지 않는다The unbounded string functions of <cstring> shall not be used
❌ 위반 예시Non-compliant example
if ( std::isdigit( c ) ) {} // Non-compliant✅ 준수 예시Compliant example
if ( std::isdigit( a, std::locale {} ) ) {} // Compliant version of the above⚠️ strcpy/strcat 같은 경계 없는 함수는 대상 버퍼 크기를 모른 채 복사하므로, 원본이 대상보다 길면 인접 메모리를 덮어쓰는 버퍼 오버플로우(보안 결함의 주원인)를 일으킨다. std::string 은 길이를 스스로 관리해 오버플로우를 구조적으로 차단한다.Unbounded functions like strcpy/strcat copy without knowing the destination size, so a source longer than the destination overruns adjacent memory — a leading cause of security defects. std::string manages its own length, structurally preventing overflow.
Rule 24.5.2Required · DecidablePDF example
The C++ Standard Library functions memcpy, memmove and memcmp from <cstring> shall not be usedThe C++ Standard Library functions memcpy, memmove and memcmp from <cstring> shall not be used
❌ 위반 예시Non-compliant example
void f1( const uint8_t * src, uint8_t * dst, size_t len )
{
memmove( dst, src, len ); // Non-compliant
}
struct S
{
bool m1;
// There may be padding here
int64_t m2;
};
void f2( S s1, S s2 )
{
if ( memcmp( &s1, &s2, sizeof( S ) ) != 0 ) // Non-compliant
{
}
};
extern char buffer1[ 12 ];
extern char buffer2[ 12 ];
void f3()
{
strcpy( buffer1, "abc" ); // Indeterminate contents in elements 4 to 11
strcpy( buffer2, "abc" ); // Indeterminate contents in elements 4 to 11
if ( memcmp( buffer1, buffer2, sizeof( buffer1 ) ) != 0 ) // Non-compliant
{
}
}⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 24.5.2 (The C++ Standard Library functions memcpy, memmove and memcmp from <cstring> shall not be used)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 24.5.2 (The C++ Standard Library functions memcpy, memmove and memcmp from <cstring> shall not be used) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
M25섹션 25Section 25
Rule 25.5.1Required · DecidablePDF example
전역 로케일 변경 함수가 반환한 포인터를 보관해 재사용하지 않는다A pointer returned by a locale-changing function shall not be stored for later reuse
❌ 위반 예시Non-compliant example
void f1()
{
wchar_t c = L'\u2002'; // En-space
std::setlocale( LC_ALL, "ja_JP.utf8" ); // Non-compliant
if ( std::isspace( c ) ) {} // Uses global locale
}✅ 준수 예시Compliant example
#include <clocale>
#include <string>
#include <iostream>
static std::string current_locale_name(){
const char* p = std::setlocale(LC_ALL, nullptr);
return p ? std::string(p) : std::string(); // 값으로 즉시 복사 보관
}
int main(){
std::string saved = current_locale_name();
std::setlocale(LC_ALL, "POSIX");
std::cout << saved << '\n';
}⚠️ setlocale 등 로케일 변경 함수가 반환한 포인터는 다음 호출에서 내부 버퍼가 덮어써질 수 있어, 그 포인터를 보관했다 재사용하면 무관한 값을 읽게 된다. 필요한 값은 std::string 등으로 즉시 복사해 보관한다.A pointer returned by locale-changing functions like setlocale may be overwritten on the next call, so storing and reusing it later reads an unrelated value. Copy any needed value immediately into something like std::string.
Rule 25.5.2Mandatory · DecidablePDF example
The pointers returned by the C++ Standard Library functions localeconv, getenv, setlocale or strerror must only be used as if they have pointer to const-qualified typeThe pointers returned by the C++ Standard Library functions localeconv, getenv, setlocale or strerror must only be used as if they have pointer to const-qualified type
❌ 위반 예시Non-compliant example
void f1()
{
char * s1 = setlocale( LC_ALL, 0 ); // Non-compliant
struct lconv * conv = localeconv(); // Non-compliant
s1[ 1 ] = 'A'; // Undefined behaviour
conv->decimal_point = "^"; // Undefined behaviour
}
conv->grouping[ 2 ] = 'x'; // Non-compliant✅ 준수 예시Compliant example
setlocale( LC_ALL, 0 ) ); // Compliant - 2nd parameter to const struct lconv * conv = localeconv(); // Compliant const struct lconv * conv = localeconv(); // Compliant
⚠️ Rule 25.5.2 (The pointers returned by the C++ Standard Library functions localeconv, getenv, setlocale or strerror must only be used as if they have pointer to const-qualified type)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 25.5.2 (The pointers returned by the C++ Standard Library functions localeconv, getenv, setlocale or strerror must only be used as if they have pointer to const-qualified type) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 25.5.3Mandatory · UndecidablePDF example
The pointer returned by the C++ Standard Library functions asctime, ctime, gmtime, localtime, localeconv, getenv, setlocale or strerror must not be used following a subsequent call to the same functionThe pointer returned by the C++ Standard Library functions asctime, ctime, gmtime, localtime, localeconv, getenv, setlocale or strerror must not be used following a subsequent call to the same function
❌ 위반 예시Non-compliant example
std::cout << lc->int_curr_symbol; // Non-compliant - use after setlocale called
✅ 준수 예시Compliant example
std::cout << copy; // Compliant - copy made before call std::cout << res; // Compliant - no subsequent call before use
⚠️ Rule 25.5.3 (The pointer returned by the C++ Standard Library functions asctime, ctime, gmtime, localtime, localeconv, getenv, setlocale or strerror must not be used following a subsequent call to the same function)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 25.5.3 (The pointer returned by the C++ Standard Library functions asctime, ctime, gmtime, localtime, localeconv, getenv, setlocale or strerror must not be used following a subsequent call to the same function) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
M26섹션 26Section 26
Rule 26.3.1Required · DecidablePDF example
정렬/연관 컨테이너에 엄격 약순서를 만족하는 술어를 제공한다A comparator shall impose a strict weak ordering
❌ 위반 예시Non-compliant example
std::vector< bool > a; // Non-compliant - optimized storage
✅ 준수 예시Compliant example
std::vector< std::uint8_t > b; // Compliant std::vector< myBool > c; // Compliant
⚠️ std::sort 나 std::map 의 비교 술어는 엄격 약순서(strict weak ordering)를 요구하는데, <= 는 동치 원소에 대해서도 true 를 반환해 이 규약을 위반하여 범위를 벗어난 접근 등 미정의 동작을 일으킨다. 동치일 때 false 를 반환하는 < 형태의 술어를 제공한다.Comparators for std::sort or std::map require a strict weak ordering, but <= returns true even for equivalent elements, violating the contract and causing undefined behaviour such as out-of-range access. Provide a < -style comparator that returns false for equivalent elements.
M28섹션 28Section 28
Rule 28.3.1Required · UndecidablePDF example
Predicates shall not have persistent side eAectsPredicates shall not have persistent side eAects
❌ 위반 예시Non-compliant example
bool bar( std::vector< int32_t > & v, int32_t & count )
{
return std::any_of( v.begin(), v.end(),
[&count]( int32_t i ) // Non-compliant
{
if ( i == 3 )
{
++count; // Persistent side effect
return true;
}
return false;
} );
}
struct Comp
{
bool operator()( int32_t a, int32_t b ) // Non-compliant - not const
{
return a > b;
}
};
std::set< int32_t, Comp > mySet;⚠️ 이 규칙은 원문에 대응하는 준수 예제가 따로 실려 있지 않습니다. 위반 예시와 아래 설명으로 판단 기준을 익히세요.This rule has no paired compliant example in the source standard. Use the non-compliant example and the notes below.
⚠️ Rule 28.3.1 (Predicates shall not have persistent side eAects)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 28.3.1 (Predicates shall not have persistent side eAects) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 28.6.1Required · DecidablePDF example
The argument to std::move shall be a non-const lvalueThe argument to std::move shall be a non-const lvalue
❌ 위반 예시Non-compliant example
f1( std::move( s1 ) ); // Non-compliant - calls #2 f1( std::move( std::string( "abc" ) ) ); // Non-compliant - redundant move of
✅ 준수 예시Compliant example
f1( std::move( s2 ) ); // Compliant - calls #1
⚠️ Rule 28.6.1 (The argument to std::move shall be a non-const lvalue)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 28.6.1 (The argument to std::move shall be a non-const lvalue) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 28.6.2Required · DecidablePDF example
Forwarding references and std::forward shall be used togetherForwarding references and std::forward shall be used together
❌ 위반 예시Non-compliant example
f1( t1 ); // Non-compliant - calls #1
f1( std::forward< T2 >( t2 ) ); // Non-compliant - calls #2
f1( std::forward< T2 >( t1 ) ); // Non-compliant - wrong template parameter
f1( std::move( t1 ) ); // Non-compliant - calls #2
{ f1(t); }; // Non-compliant - calls #1✅ 준수 예시Compliant example
f1( std::forward< T1 >( t1 ) ); // Compliant - calls #1 (for #4) or #2 (for #3)
⚠️ Rule 28.6.2 (Forwarding references and std::forward shall be used together)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 28.6.2 (Forwarding references and std::forward shall be used together) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
Rule 28.6.3Required · DecidablePDF example
이동된(moved-from) 객체의 값에 의존하지 않는다The value of a moved-from object shall not be relied upon
❌ 위반 예시Non-compliant example
void d1 ( std::string const &, int32_t );
int32_t d2 ( std::string && );
void d3( std::string s )
{
d1( s, d2( std::move( s ) ) ); // Non-compliant
}✅ 준수 예시Compliant example
y = std::move( x ); // Compliant - no more uses of x
x = X{}; // Compliant - assigns to potentially⚠️ std::move 후의 원본 객체는 소멸·재대입은 안전하지만 그 값은 "유효하나 미지정(valid but unspecified)" 상태라, 그 값을 읽거나 의존하면 구현·타입마다 다른 비결정적 결과가 나온다. 이동된 객체를 다시 쓰려면 먼저 명확한 값을 대입한 뒤 사용한다.After std::move, the source object is safe to destroy or reassign, but its value is "valid but unspecified," so reading or depending on it yields non-deterministic, implementation- and type-dependent results. To reuse a moved-from object, assign it a definite value first.
Rule 28.6.4Required · DecidablePDF example
전달 참조(forwarding reference)는 std::forward 로 전달한다A forwarding reference shall be forwarded with std::forward
❌ 위반 예시Non-compliant example
std::unique( v1.begin(), v1.end() ); // Non-compliant empty( v3 ); // Non-compliant - result not used v3.empty(); // Non-compliant - result not used
✅ 준수 예시Compliant example
v2.end() ); // Compliant if ( !empty( v3 ) ) // Compliant
⚠️ 전달 참조 T&& 에 std::move 를 쓰면 인자가 lvalue 든 rvalue 든 무조건 이동시켜, 호출자가 계속 쓰려던 lvalue 객체까지 비워 버리는 훼손이 발생한다. std::forward<T> 는 원래 값 범주(lvalue/rvalue)를 보존해 rvalue 만 이동하고 lvalue 는 복사로 전달한다.Using std::move on a forwarding reference T&& moves the argument unconditionally whether it is an lvalue or rvalue, clobbering even an lvalue object the caller intended to keep. std::forward<T> preserves the original value category, moving only rvalues and copying lvalues.
M30섹션 30Section 30
Rule 30.0.1Required · Decidable✓ compilablePDF rule
C 표준 입출력(<cstdio>) 대신 C++ 문자열/스트림을 사용한다C Standard I/O shall be replaced by C++ strings/streams
❌ 위반 예시Non-compliant example
#include <cstdio>
#include <iostream>
int main(){
char buf[16];
int v = 1234567;
std::sprintf(buf, "%d", v); // 대상 크기 미검사 — 큰 값이면 오버플로우
std::cout << buf << '\n';
}✅ 준수 예시Compliant example
#include <string>
#include <iostream>
int main(){
int v = 1234567;
std::string s = std::to_string(v); // 길이를 자동 관리
std::cout << s << '\n';
}⚠️ sprintf 같은 cstdio 함수는 대상 버퍼 크기를 검사하지 않아 변환 결과가 길면 버퍼 오버플로우가 발생하고, 포맷-인자 타입 불일치 시 미정의 동작이 된다. std::to_string·std::string·스트림은 길이를 자동 관리하고 타입 안전해 이런 결함을 구조적으로 제거한다.cstdio functions like sprintf do not check the destination buffer size, so a long conversion overflows the buffer, and format/argument type mismatches cause undefined behaviour. std::to_string, std::string, and streams manage length automatically and are type-safe, structurally removing these defects.
Rule 30.0.2Required · UndecidablePDF example
Reads and writes on the same file stream shall be separated by a positioning operationReads and writes on the same file stream shall be separated by a positioning operation
❌ 위반 예시Non-compliant example
std::getline( f, s ); // Non-compliant - undefined behaviour
✅ 준수 예시Compliant example
std::getline(f, s); // Compliant - s holds "Hello world!"
⚠️ Rule 30.0.2 (Reads and writes on the same file stream shall be separated by a positioning operation)은 표준 원문을 근거로 수록한 MISRA 규칙입니다. 예제 코드를 기준으로 위반 조건과 준수 조건을 비교하며, 수업 전 정적분석 도구 결과와 함께 검증하세요.Rule 30.0.2 (Reads and writes on the same file stream shall be separated by a positioning operation) was added from the local PDF source. Compare the non-compliant and compliant examples, and verify them with static-analysis results before class delivery.
CERT C
SEI CERT C Coding Standard
Rules / RecommendationsRules / RecommendationsSeverity × Likelihood × Remediation → PrioritySeverity × Likelihood × Remediation → PriorityLevel L1 / L2 / L3Level L1 / L2 / L3
보안 취약점 예방에 초점을 둔 코딩 표준. 규칙 ID는 "섹션+번호-C"(예: INT30-C). 공식 사이트(cmu-sei.github.io) 대조로 ID 정확성 확인.A coding standard focused on preventing security vulnerabilities. Rule IDs use "section+number-C" (e.g. INT30-C). IDs verified against the official site (cmu-sei.github.io).
PRE전처리기Preprocessor
PRE30-CPRE · Rule · L1✓ compilableSEI index
토큰 연결로 식별자/보편 문자 이름을 조립하지 않는다Do not create identifiers or universal character names through token concatenation
❌ 위반 예시Non-compliant example
#include <stdio.h>
#define JOIN(a,b) a##b
int main(void){
int JOIN(co,unt) = 3; /* 토큰 결합으로 'count' 조립 — 깨지기 쉬움 */
printf("%d\n", count);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int count = 3; /* 완성된 식별자를 직접 사용 */
printf("%d\n", count);
return 0;
}⚠️ ## 로 식별자(또는 보편 문자 이름)를 조립하면 의도와 다른 토큰이 생기고 가독성이 떨어진다. 완성된 식별자를 직접 작성한다.Assembling identifiers (or universal character names) with ## yields fragile, hard-to-read code and can produce unintended tokens. Write completed identifiers directly.
PRE31-CPRE · Rule · L1✓ compilableSEI index
안전하지 않은 매크로의 인자에 부작용을 두지 않는다Avoid side effects in arguments to unsafe macros
❌ 위반 예시Non-compliant example
#include <stdio.h>
#define ABS(x) ((x) < 0 ? -(x) : (x))
int main(void){
int i = -3;
int y = ABS(i++); /* i 가 두 번 평가됨 */
printf("y=%d i=%d\n", y, i);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#define ABS(x) ((x) < 0 ? -(x) : (x))
int main(void){
int i = -3;
int t = i++; /* 부작용은 한 번만 */
int y = ABS(t);
printf("y=%d i=%d\n", y, i);
return 0;
}⚠️ 매크로가 인자를 여러 번 평가하면 부작용(증감·함수호출)이 중복 실행된다. 부작용은 매크로 밖에서 한 번만 수행한다.A macro may evaluate its argument multiple times, so side effects (increment, calls) run more than once. Perform side effects once, outside the macro.
PRE32-CPRE · Rule · L1✓ compilableSEI index
함수형 매크로 호출의 인자 안에서 전처리 지시문을 사용하지 않는다Do not use preprocessor directives in invocations of function-like macros
❌ 위반 예시Non-compliant example
#include <string.h>
#define COPY(d,s,n) memcpy((d),(s),(n))
int main(void){
char d[8];
/* 위반: 인자 안에서 크기를 #if 로 고른다(미정의). 아래는 동치의 위험 패턴 */
int n = 4;
#ifdef BIG
n = 8;
#endif
COPY(d, "abcd", (n>8?8:n));
return 0;
}✅ 준수 예시Compliant example
#include <string.h>
#define COPY(d,s,n) memcpy((d),(s),(n))
int main(void){
char d[8];
#ifdef BIG
int n = 8;
#else
int n = 4;
#endif
COPY(d, "abcd", n); /* 값을 먼저 정하고 매크로에 전달 */
return 0;
}⚠️ 함수형 매크로 인자 안의 #if 등은 미정의 동작이다. 조건부 컴파일로 값을 먼저 정한 뒤 매크로/함수에 전달한다.A #if directive inside a function-like macro argument is undefined behavior. Decide the value first with conditional compilation, then pass it to the macro.
PRE01-CEXP · Rule · SEISEI index
Use parentheses within macros around parameter namesUse parentheses within macros around parameter names
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE01-C * SEI official index entry: Use parentheses within macros around parameter names * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE01-C * SEI official index entry: Use parentheses within macros around parameter names * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE02-CEXP · Rule · SEISEI index
Macro replacement lists should be parenthesizedMacro replacement lists should be parenthesized
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE02-C * SEI official index entry: Macro replacement lists should be parenthesized * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE02-C * SEI official index entry: Macro replacement lists should be parenthesized * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE00-CPRE · Rec · L3✓ compilableSEI index
함수형 매크로보다 인라인/정적 함수를 선호한다Prefer inline or static functions to function-like macros
❌ 위반 예시Non-compliant example
#include <stdio.h>
#define MAX(a,b) ((a) > (b) ? (a) : (b))
int main(void){
int i = 2;
int m = MAX(i++, 5); /* 인자 다중 평가 */
printf("%d %d\n", m, i);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
static inline int imax(int a, int b){ return a > b ? a : b; }
int main(void){
int i = 2;
int m = imax(i++, 5); /* 인자 1회 평가, 타입 검사 */
printf("%d %d\n", m, i);
return 0;
}⚠️ 매크로는 타입 검사가 없고 인자를 다중 평가한다. inline 함수가 같은 성능에 타입 안전과 단일 평가를 보장한다.Macros have no type checking and evaluate arguments multiple times. An inline function gives the same performance with type safety and single evaluation.
PRE04-CPRE · Rec · SEISEI index
Do not reuse a standard header file nameDo not reuse a standard header file name
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE04-C * SEI official index entry: Do not reuse a standard header file name * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE04-C * SEI official index entry: Do not reuse a standard header file name * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE05-CPRE · Rec · SEISEI index
Understand macro replacement when concatenating tokens or performing stringificationUnderstand macro replacement when concatenating tokens or performing stringification
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE05-C * SEI official index entry: Understand macro replacement when concatenating tokens or performing stringification * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE05-C * SEI official index entry: Understand macro replacement when concatenating tokens or performing stringification * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE06-CPRE · Rec · SEISEI index
Enclose header files in an include guardEnclose header files in an include guard
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE06-C * SEI official index entry: Enclose header files in an include guard * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE06-C * SEI official index entry: Enclose header files in an include guard * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE07-CPRE · Rec · SEISEI index
Avoid using repeated question marksAvoid using repeated question marks
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE07-C * SEI official index entry: Avoid using repeated question marks * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE07-C * SEI official index entry: Avoid using repeated question marks * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE08-CPRE · Rec · SEISEI index
Guarantee that header file names are uniqueGuarantee that header file names are unique
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE08-C * SEI official index entry: Guarantee that header file names are unique * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE08-C * SEI official index entry: Guarantee that header file names are unique * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE08-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE08-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE09-CPRE · Rec · SEISEI index
Do not replace secure functions with deprecated or obsolescent functionsDo not replace secure functions with deprecated or obsolescent functions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE09-C * SEI official index entry: Do not replace secure functions with deprecated or obsolescent functions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE09-C * SEI official index entry: Do not replace secure functions with deprecated or obsolescent functions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE10-CPRE · Rec · L3✓ compilableSEI index
여러 문장을 담는 매크로는 do-while(0)으로 감싼다Wrap multi-statement macros in a do-while loop
❌ 위반 예시Non-compliant example
#include <stdio.h>
#define LOG(x) printf("%d\n", x); fflush(stdout)
int main(void){
int v = 1;
if (v) LOG(v); /* fflush 는 if 와 무관하게 항상 실행 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#define LOG(x) do { printf("%d\n", x); fflush(stdout); } while (0)
int main(void){
int v = 1;
if (v) { LOG(v); }
return 0;
}⚠️ 여러 문장 매크로를 나열하면 if/else 본문에서 일부만 묶여 의도와 다르게 동작한다. do{...}while(0)으로 단일 문장처럼 만든다.Listing multiple statements in a macro can bind only part of it to an if/else body. Wrap it in do{...}while(0) so it behaves as a single statement.
PRE11-CPRE · Rec · SEISEI index
Do not conclude macro definitions with a semicolonDo not conclude macro definitions with a semicolon
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE11-C * SEI official index entry: Do not conclude macro definitions with a semicolon * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE11-C * SEI official index entry: Do not conclude macro definitions with a semicolon * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE11-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE11-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE12-CPRE · Rec · SEISEI index
Do not define unsafe macrosDo not define unsafe macros
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE12-C * SEI official index entry: Do not define unsafe macros * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE12-C * SEI official index entry: Do not define unsafe macros * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE12-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE12-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
PRE13-CPRE · Rec · SEISEI index
Use the Standard predefined macros to test for versions and features.Use the Standard predefined macros to test for versions and features.
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for PRE13-C * SEI official index entry: Use the Standard predefined macros to test for versions and features. * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for PRE13-C * SEI official index entry: Use the Standard predefined macros to test for versions and features. * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ PRE13-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.PRE13-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL선언·초기화Declarations
DCL00-CDCL · Rec · L3✓ compilableSEI index
변경되지 않는 객체는 const 로 한정한다Const-qualify immutable objects
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int limit = 100; /* 이후 수정 없음에도 비-const */
printf("%d\n", limit);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
const int limit = 100; /* 변경 불가를 컴파일러가 강제 */
printf("%d\n", limit);
return 0;
}⚠️ 불변 객체를 const로 표시하지 않으면 실수로 수정되거나 의도가 흐려진다. const로 변경 불가를 강제한다.Not marking immutable objects const allows accidental modification and obscures intent. Let const enforce immutability.
DCL30-CDCL · Rule · L3✓ compilableSEI index
객체는 용도에 맞는 저장 기간으로 선언한다Declare objects with appropriate storage durations
❌ 위반 예시Non-compliant example
#include <stdio.h>
const char *get_name(void){
char buf[8];
snprintf(buf, sizeof buf, "node");
return buf; /* 자동 객체 주소 반환 — 수명 종료 */
}
int main(void){ printf("%s\n", get_name()); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
const char *get_name(void){
static const char name[] = "node";
return name; /* 정적 저장 기간 */
}
int main(void){ printf("%s\n", get_name()); return 0; }⚠️ 자동 저장 기간 객체의 주소를 함수 밖으로 반환하면 수명이 끝나 무효한 메모리를 가리킨다. 정적 저장 기간이나 호출자 버퍼를 쓴다.Returning the address of an automatic object outlives its lifetime and points to invalid memory. Use static storage or a caller-supplied buffer.
DCL31-CDCL · Rule · L3✓ compilableSEI index
식별자는 사용 전에 선언한다Declare identifiers before using them
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int r = scale(3); /* 선언 없이 호출 — 암시적 선언 */
printf("%d\n", r);
return 0;
}
int scale(int x){ return x * 2; }✅ 준수 예시Compliant example
#include <stdio.h>
int scale(int x); /* 사용 전 선언 */
int main(void){
int r = scale(3);
printf("%d\n", r);
return 0;
}
int scale(int x){ return x * 2; }⚠️ 선언 없는 사용은 타입을 잘못 가정해 인자/반환 손상을 일으킨다. 모든 식별자를 사용 전에 선언한다.Using an identifier without a prior declaration mis-assumes its type, corrupting arguments/returns. Declare every identifier before use.
DCL36-CDCL · Rule · L2SEI index
충돌하는 링크(linkage) 분류로 식별자를 선언하지 않는다Do not declare an identifier with conflicting linkage classifications
❌ 위반 예시Non-compliant example
/* a.c */ static int shared; /* 내부 링크(이 파일 전용) */ /* b.c */ extern int shared; /* 외부 링크로 같은 이름 참조 — 링크 분류 충돌, 미정의 동작 */
✅ 준수 예시Compliant example
/* shared.h */ extern int shared; /* 외부 링크 선언을 헤더에 단일화 */ /* shared.c */ #include "shared.h" int shared; /* 일관된 외부 링크 정의 */
⚠️ 같은 식별자를 한 곳에서는 static(내부 링크), 다른 곳에서는 extern(외부 링크)으로 모순되게 선언하면 어느 객체를 가리키는지 모호해져 미정의 동작이 된다. 공유 헤더에 단일 extern 선언을 두고 한 소스에서만 정의해 링크 분류를 일관되게 유지한다.Declaring the same identifier as static (internal linkage) in one place and extern (external linkage) in another is contradictory, making it ambiguous which object is referred to — undefined behaviour. Put a single extern declaration in a shared header and define it in exactly one source file to keep linkage consistent.
DCL37-CDCL · Rule · L1✓ compilableSEI index
예약된 식별자를 선언하거나 정의하지 않는다Do not declare or define reserved identifiers
❌ 위반 예시Non-compliant example
#include <stdio.h>
#define __MYMAX 100 /* 밑줄 두 개 시작 — 구현 예약 */
int _count = 0; /* 밑줄+소문자(파일 범위) 예약 */
int main(void){ _count = __MYMAX; printf("%d\n", _count); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
#define APP_MAX 100
int app_count = 0;
int main(void){ app_count = APP_MAX; printf("%d\n", app_count); return 0; }⚠️ 밑줄로 시작하거나 표준이 예약한 이름을 정의하면 구현 내부와 충돌해 미정의 동작이 된다. 비예약 이름을 쓴다.Defining names that begin with an underscore or are reserved by the standard collides with the implementation and is undefined. Use non-reserved names.
DCL38-CDCL · Rule · L1✓ compilableSEI index
유연 배열 멤버는 올바른 구문으로 선언한다Use the correct syntax when declaring a flexible array member
❌ 위반 예시Non-compliant example
#include <stdlib.h>
struct Buf { size_t n; char data[1]; }; /* [1] 트릭 — 경계 모호 */
int main(void){
struct Buf *b = malloc(sizeof *b + 10);
if (b){ b->n = 10; b->data[5] = 'x'; free(b); } /* 선언 크기 초과 접근 */
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
struct Buf { size_t n; char data[]; }; /* C99 유연 배열 멤버 */
int main(void){
size_t len = 10;
struct Buf *b = malloc(sizeof *b + len);
if (b){ b->n = len; b->data[5] = 'x'; free(b); }
return 0;
}⚠️ data[1] 같은 옛 트릭은 선언 크기와 실제 크기가 어긋나 경계 검사를 무력화한다. C99 유연 배열 멤버 구문을 쓴다.The old data[1] trick makes the declared size differ from the real size, defeating bounds analysis. Use the C99 flexible array member syntax.
DCL39-CDCL · Rec · L3✓ compilableSEI index
구조체 패딩을 통한 정보 유출을 피한다Avoid information leakage through structure padding
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <string.h>
struct S { char c; int v; }; /* c와 v 사이 패딩에 잔존 데이터 */
int main(void){
struct S s;
s.c = 'x'; s.v = 1; /* 패딩 미초기화 */
fwrite(&s, sizeof s, 1, stdout); /* 패딩 바이트 유출 가능 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <string.h>
struct S { char c; int v; };
int main(void){
struct S s;
memset(&s, 0, sizeof s); /* 패딩 포함 0으로 초기화 */
s.c = 'x'; s.v = 1;
fwrite(&s, sizeof s, 1, stdout);
return 0;
}⚠️ 구조체를 그대로 외부로 쓰면 초기화되지 않은 패딩 바이트의 잔존 데이터가 유출될 수 있다. 전체를 0으로 초기화한 뒤 채운다.Writing a struct verbatim can leak residual data in uninitialized padding bytes. Zero the whole object before populating it.
DCL40-CDCL · Rule · L2✓ compilableSEI index
같은 함수/객체에 호환되지 않는 선언을 만들지 않는다Do not create incompatible declarations of the same function or object
❌ 위반 예시Non-compliant example
#include <stdio.h>
int f(); /* 매개변수 미명세 — 정의와 호환 안 되는 느슨한 선언 */
int f(int x){ return x * 2; }
int main(void){ printf("%d\n", f(3)); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
int f(int x); /* 정의와 일치하는 프로토타입 */
int f(int x){ return x * 2; }
int main(void){ printf("%d\n", f(3)); return 0; }⚠️ 정의와 호환되지 않는(매개변수 미명세 등) 선언을 두면 잘못된 인자 개수·타입 호출을 컴파일러가 잡지 못한다. 정의와 일치하는 단일 프로토타입을 둔다.A declaration incompatible with the definition (e.g. unspecified parameters) lets wrong-arity/type calls slip past the compiler. Keep a single prototype matching the definition.
DCL41-CDCL · Rule · L3✓ compilableSEI index
switch 의 첫 case 이전에 변수를 선언하지 않는다Do not declare variables inside a switch before the first case label
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int x = 1;
switch (x){
int y = 5; /* 초기화가 실행되지 않음 */
case 1: printf("%d\n", y); break;
default: break;
}
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int x = 1;
int y = 5; /* switch 밖에서 초기화 */
switch (x){
case 1: printf("%d\n", y); break;
default: break;
}
return 0;
}⚠️ switch 첫 레이블 이전의 선언 초기화는 점프로 건너뛰어져 미초기화 값을 읽는다. 선언은 switch 밖이나 case 블록 안에 둔다.An initializer before the first switch label is skipped by the jump, leaving an uninitialized read. Declare outside the switch or inside a case block.
DCL09-CERR · Rule · SEISEI index
Declare functions that return errno with a return type of errno_tDeclare functions that return errno with a return type of errno_t
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL09-C * SEI official index entry: Declare functions that return errno with a return type of errno_t * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL09-C * SEI official index entry: Declare functions that return errno with a return type of errno_t * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL01-CDCL · Rec · SEISEI index
Do not reuse variable names in subscopesDo not reuse variable names in subscopes
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL01-C * SEI official index entry: Do not reuse variable names in subscopes * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL01-C * SEI official index entry: Do not reuse variable names in subscopes * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL02-CDCL · Rec · L2✓ compilableSEI index
시각적으로 구별되는 식별자를 사용한다Use visually distinct identifiers
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int rn = 1, rnn = 2; /* rn / rnn — 혼동 */
printf("%d\n", rn + rnn);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int row_count = 1, running_total = 2;
printf("%d\n", row_count + running_total);
return 0;
}⚠️ 철자가 비슷한 짧은 이름은 잘못된 변수 참조를 부른다. 의미가 드러나는 구별되는 이름을 쓴다.Short, similar-looking names invite referencing the wrong variable. Use distinct, meaningful names.
DCL03-CDCL · Rec · SEISEI index
Use a static assertion to test the value of a constant expressionUse a static assertion to test the value of a constant expression
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL03-C * SEI official index entry: Use a static assertion to test the value of a constant expression * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL03-C * SEI official index entry: Use a static assertion to test the value of a constant expression * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL03-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL03-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL04-CDCL · Rec · SEISEI index
Do not declare more than one variable per declarationDo not declare more than one variable per declaration
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL04-C * SEI official index entry: Do not declare more than one variable per declaration * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL04-C * SEI official index entry: Do not declare more than one variable per declaration * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL05-CDCL · Rec · SEISEI index
Use typedefs of non-pointer types onlyUse typedefs of non-pointer types only
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL05-C * SEI official index entry: Use typedefs of non-pointer types only * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL05-C * SEI official index entry: Use typedefs of non-pointer types only * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL06-CDCL · Rec · SEISEI index
Use meaningful symbolic constants to represent literal valuesUse meaningful symbolic constants to represent literal values
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL06-C * SEI official index entry: Use meaningful symbolic constants to represent literal values * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL06-C * SEI official index entry: Use meaningful symbolic constants to represent literal values * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL07-CDCL · Rec · SEISEI index
Include the appropriate type information in function declaratorsInclude the appropriate type information in function declarators
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL07-C * SEI official index entry: Include the appropriate type information in function declarators * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL07-C * SEI official index entry: Include the appropriate type information in function declarators * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL08-CDCL · Rec · SEISEI index
Properly encode relationships in constant definitionsProperly encode relationships in constant definitions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL08-C * SEI official index entry: Properly encode relationships in constant definitions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL08-C * SEI official index entry: Properly encode relationships in constant definitions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL08-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL08-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL10-CDCL · Rec · SEISEI index
Maintain the contract between the writer and caller of variadic functionsMaintain the contract between the writer and caller of variadic functions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL10-C * SEI official index entry: Maintain the contract between the writer and caller of variadic functions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL10-C * SEI official index entry: Maintain the contract between the writer and caller of variadic functions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL10-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL10-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL11-CDCL · Rec · SEISEI index
Understand the type issues associated with variadic functionsUnderstand the type issues associated with variadic functions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL11-C * SEI official index entry: Understand the type issues associated with variadic functions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL11-C * SEI official index entry: Understand the type issues associated with variadic functions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL11-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL11-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL12-CDCL · Rec · SEISEI index
Implement abstract data types using opaque typesImplement abstract data types using opaque types
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL12-C * SEI official index entry: Implement abstract data types using opaque types * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL12-C * SEI official index entry: Implement abstract data types using opaque types * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL12-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL12-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL13-CDCL · Rec · SEISEI index
Declare function parameters that are pointers to values not changed by the function as constDeclare function parameters that are pointers to values not changed by the function as const
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL13-C * SEI official index entry: Declare function parameters that are pointers to values not changed by the function as const * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL13-C * SEI official index entry: Declare function parameters that are pointers to values not changed by the function as const * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL13-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL13-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL15-CDCL · Rec · SEISEI index
Declare file-scope objects or functions that do not need external linkage as staticDeclare file-scope objects or functions that do not need external linkage as static
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL15-C * SEI official index entry: Declare file-scope objects or functions that do not need external linkage as static * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL15-C * SEI official index entry: Declare file-scope objects or functions that do not need external linkage as static * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL15-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL15-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL16-CDCL · Rec · SEISEI index
Use "L," not "l," to indicate a long valueUse "L," not "l," to indicate a long value
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL16-C * SEI official index entry: Use "L," not "l," to indicate a long value * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL16-C * SEI official index entry: Use "L," not "l," to indicate a long value * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL16-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL16-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL17-CDCL · Rec · SEISEI index
Beware of miscompiled volatile-qualified variablesBeware of miscompiled volatile-qualified variables
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL17-C * SEI official index entry: Beware of miscompiled volatile-qualified variables * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL17-C * SEI official index entry: Beware of miscompiled volatile-qualified variables * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL17-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL17-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL18-CDCL · Rec · L3✓ compilableSEI index
정수 상수를 0으로 시작(8진수)하지 않는다Do not begin integer constants with 0 (octal)
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int code = 013; /* 8진수 11, 의도는 13? */
printf("%d\n", code);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int code = 13; /* 10진수 */
printf("%d\n", code);
return 0;
}⚠️ 선행 0은 8진수로 해석되어 013이 11이 되는 등 의도와 다른 값이 된다. 10진/16진 표기를 쓴다.A leading 0 is interpreted as octal, so 013 becomes 11, not 13. Use decimal or hexadecimal notation.
DCL19-CDCL · Rec · SEISEI index
Minimize the scope of variables and functionsMinimize the scope of variables and functions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL19-C * SEI official index entry: Minimize the scope of variables and functions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL19-C * SEI official index entry: Minimize the scope of variables and functions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL19-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL19-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL20-CDCL · Rec · SEISEI index
Explicitly specify void when a function accepts no argumentsExplicitly specify void when a function accepts no arguments
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL20-C * SEI official index entry: Explicitly specify void when a function accepts no arguments * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL20-C * SEI official index entry: Explicitly specify void when a function accepts no arguments * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL20-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL20-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL21-CDCL · Rec · SEISEI index
Understand the storage of compound literalsUnderstand the storage of compound literals
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL21-C * SEI official index entry: Understand the storage of compound literals * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL21-C * SEI official index entry: Understand the storage of compound literals * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL21-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL21-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL22-CDCL · Rec · SEISEI index
Use volatile for data that cannot be cachedUse volatile for data that cannot be cached
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL22-C * SEI official index entry: Use volatile for data that cannot be cached * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL22-C * SEI official index entry: Use volatile for data that cannot be cached * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL22-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL22-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
DCL23-CDCL · Rec · SEISEI index
Guarantee that mutually visible identifiers are uniqueGuarantee that mutually visible identifiers are unique
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for DCL23-C * SEI official index entry: Guarantee that mutually visible identifiers are unique * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for DCL23-C * SEI official index entry: Guarantee that mutually visible identifiers are unique * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ DCL23-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.DCL23-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
POSPOSIXPOSIX
POS54-CPOS · Rule · L1✓ compilableSEI index
POSIX 라이브러리 함수의 오류를 검출하고 처리한다Detect and handle POSIX library errors
❌ 위반 예시Non-compliant example
#define _GNU_SOURCE
#include <fcntl.h>
#include <unistd.h>
int main(void){
char buf[64];
int fd = open("/nonexistent_xyz123", O_RDONLY);
read(fd, buf, sizeof buf); /* open 실패(-1)·read 오류 미검사 */
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <fcntl.h>
#include <unistd.h>
int main(void){
char buf[64];
int fd = open("/etc/hostname", O_RDONLY);
if (fd < 0) return -1;
ssize_t r = read(fd, buf, sizeof buf);
if (r < 0) { close(fd); return -1; }
close(fd);
return 0;
}⚠️ POSIX 함수의 -1/errno 반환을 무시하면 실패 상태로 계속 진행해 손상이 누적된다. 반환값을 검사하고 errno로 처리한다.Ignoring a POSIX function’s -1/errno return proceeds in a failed state and accumulates damage. Check the return value and handle errno.
POS30-CPOS · Rule · L1✓ compilableSEI index
readlink() 를 올바르게 사용한다(널 종료·버퍼 크기)Use the readlink() function properly
❌ 위반 예시Non-compliant example
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
int main(void){
char buf[64];
readlink("/proc/self/exe", buf, sizeof buf); /* 반환 무시 + 널 종료 안 함 + 잘림 가능 */
printf("%s\n", buf); /* 널 종료되지 않은 버퍼 출력 — 경계 밖 읽기 */
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
int main(void){
char buf[64];
ssize_t n = readlink("/proc/self/exe", buf, sizeof buf - 1); /* 널 자리 확보 */
if (n >= 0) {
buf[n] = '\0'; /* 반환 길이로 직접 널 종료 */
printf("%s\n", buf);
}
return 0;
}⚠️ readlink 는 대상 문자열에 널 종료 문자를 붙이지 않고, 버퍼가 작으면 조용히 잘라 쓰며 반환값으로만 실제 길이를 알린다. 따라서 반환값을 무시하거나 널 종료를 직접 하지 않으면 경계 밖 읽기·잘린 경로 사용 결함이 생긴다. 버퍼에 널 자리를 남기고, 반환 길이로 직접 널 종료한다.readlink does not null-terminate the target string, silently truncates if the buffer is small, and reports the actual length only via its return value. So ignoring the return value or not null-terminating yourself causes out-of-bounds reads or use of a truncated path. Reserve room for the terminator and null-terminate using the returned length.
POS04-CCON · Rule · SEISEI index
Avoid using PTHREAD_MUTEX_NORMAL type mutex locksAvoid using PTHREAD_MUTEX_NORMAL type mutex locks
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for POS04-C * SEI official index entry: Avoid using PTHREAD_MUTEX_NORMAL type mutex locks * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for POS04-C * SEI official index entry: Avoid using PTHREAD_MUTEX_NORMAL type mutex locks * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ POS04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.POS04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
POS44-CPOS · Rule · L1✓ compilableSEI index
스레드를 종료시키기 위해 시그널을 사용하지 않는다Do not use signals to terminate threads
❌ 위반 예시Non-compliant example
#include <pthread.h>
#include <signal.h>
static void *worker(void *p){ (void)p; for(;;){ } return NULL; }
int main(void){
pthread_t t; pthread_create(&t, NULL, worker, NULL);
pthread_kill(t, SIGTERM); /* 시그널로 스레드 강제 종료 — 잠금·자원 정리 안 됨 */
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
#include <stdatomic.h>
static atomic_int stop = 0;
static void *worker(void *p){ (void)p; while (!atomic_load(&stop)) { } return NULL; }
int main(void){
pthread_t t; pthread_create(&t, NULL, worker, NULL);
atomic_store(&stop, 1); /* 협조적 종료 플래그 */
pthread_join(t, NULL); /* 정상 종료를 기다림 */
return 0;
}⚠️ 시그널로 스레드를 강제 종료하면 그 스레드가 보유한 잠금·동적 자원이 정리되지 않은 채 사라져, 다른 스레드가 영원히 잠금을 기다리는 교착이나 메모리 누수가 발생한다. 협조적 종료 플래그를 두고 스레드가 안전한 지점에서 스스로 빠져나오게 한 뒤 join 으로 회수한다.Forcibly terminating a thread with a signal abandons the locks and dynamic resources it holds, causing deadlock (other threads waiting forever on a lock) or memory leaks. Use a cooperative stop flag so the thread exits itself at a safe point, then reap it with join.
POS47-CPOS · Rule · L2✓ compilableSEI index
비동기적으로 취소될 수 있는 스레드를 사용하지 않는다Do not use threads that can be canceled asynchronously
❌ 위반 예시Non-compliant example
#include <pthread.h>
static void *worker(void *p){
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); /* 임의 명령 사이에서 취소 가능 */
for(;;){ }
return p;
}
int main(void){
pthread_t t; pthread_create(&t, NULL, worker, NULL);
pthread_cancel(t); pthread_join(t, NULL);
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
static void *worker(void *p){
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); /* 취소 지점에서만 취소 */
for(;;){ pthread_testcancel(); } /* 안전한 취소 지점을 명시 */
return p;
}
int main(void){
pthread_t t; pthread_create(&t, NULL, worker, NULL);
pthread_cancel(t); pthread_join(t, NULL);
return 0;
}⚠️ 비동기 취소(PTHREAD_CANCEL_ASYNCHRONOUS)는 스레드를 임의의 명령 사이에서 즉시 멈춰, 자료구조 갱신 도중이거나 잠금을 쥔 상태에서 종료되어 불변식 손상·교착을 일으킨다. 지연 취소(DEFERRED)를 사용해 pthread_testcancel 같은 안전한 취소 지점에서만 취소되게 한다.Asynchronous cancellation (PTHREAD_CANCEL_ASYNCHRONOUS) stops a thread instantly between arbitrary instructions, possibly mid-update of a data structure or while holding a lock, corrupting invariants or deadlocking. Use deferred cancellation so the thread is canceled only at safe cancellation points like pthread_testcancel.
POS48-CPOS · Rule · L2✓ compilableSEI index
다른 스레드가 잠근(또는 잠기지 않은) 뮤텍스를 잠금 해제하지 않는다Do not unlock or destroy another POSIX thread’s mutex
❌ 위반 예시Non-compliant example
#include <pthread.h>
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int main(void){
pthread_mutex_unlock(&m); /* 잠그지 않은(소유하지 않은) 뮤텍스를 해제 — 미정의 동작 */
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int main(void){
pthread_mutex_lock(&m); /* 잠근 스레드가 */
/* 임계 구역 */
pthread_mutex_unlock(&m); /* 같은 스레드에서 직접 해제 */
return 0;
}⚠️ POSIX 뮤텍스는 소유 개념이 있어, 잠그지 않았거나 다른 스레드가 잠근 뮤텍스를 해제하면 미정의 동작이 되어 잠금 상태가 손상되고 경쟁이 노출된다. 뮤텍스는 그것을 잠근 바로 그 스레드가 같은 임계 구역에서 직접 해제한다.A POSIX mutex has ownership, so unlocking one that was not locked or was locked by a different thread is undefined behaviour that corrupts the lock state and exposes races. The thread that locked a mutex must unlock it itself within the same critical section.
POS49-CPOS · Rule · L2✓ compilableSEI index
인접 멤버에 서로 다른 스레드가 동시 접근할 때 동기화한다When data must be accessed by multiple threads, provide a mutex and guarantee no adjacent data is also accessed
❌ 위반 예시Non-compliant example
#include <pthread.h>
static struct { char a; char b; } s; /* 같은 워드에 인접한 멤버 */
static void *t1(void *p){ (void)p; s.a = 1; return NULL; }
static void *t2(void *p){ (void)p; s.b = 1; return NULL; } /* 다른 멤버지만 같은 메모리 단위 — 경쟁 가능 */
int main(void){
pthread_t a, b;
pthread_create(&a, NULL, t1, NULL); pthread_create(&b, NULL, t2, NULL);
pthread_join(a, NULL); pthread_join(b, NULL);
return s.a + s.b;
}✅ 준수 예시Compliant example
#include <pthread.h>
static struct { char a; char b; } s;
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static void *t1(void *p){ (void)p; pthread_mutex_lock(&m); s.a = 1; pthread_mutex_unlock(&m); return NULL; }
static void *t2(void *p){ (void)p; pthread_mutex_lock(&m); s.b = 1; pthread_mutex_unlock(&m); return NULL; }
int main(void){
pthread_t a, b;
pthread_create(&a, NULL, t1, NULL); pthread_create(&b, NULL, t2, NULL);
pthread_join(a, NULL); pthread_join(b, NULL);
return s.a + s.b;
}⚠️ CPU 는 메모리를 워드 단위로 읽고 쓰므로, 같은 워드 안에 인접한 별도 멤버(char a; char b;)라도 두 스레드가 각각 갱신하면 읽기-수정-쓰기 과정에서 한쪽 갱신이 사라지는 경쟁이 발생할 수 있다. 인접 멤버 접근을 같은 잠금으로 보호하거나 멤버를 캐시라인 단위로 분리한다.CPUs read and write memory in word units, so even separate adjacent members in the same word (char a; char b;) can race when two threads update them, losing one update in the read-modify-write. Protect adjacent-member access with the same lock, or separate the members onto distinct cache lines.
POS50-CPOS · Rule · L2✓ compilableSEI index
스레드 간 공유하는 POSIX 객체는 적절한 저장 기간으로 선언한다Declare objects shared between POSIX threads with appropriate storage durations
❌ 위반 예시Non-compliant example
#include <pthread.h>
static void *work(void *arg){ pthread_mutex_t *mp = arg; pthread_mutex_lock(mp); pthread_mutex_unlock(mp); return NULL; }
static pthread_t start(void){
pthread_mutex_t m; /* 자동 저장 기간 뮤텍스 */
pthread_mutex_init(&m, NULL);
pthread_t t;
pthread_create(&t, NULL, work, &m); /* start 종료 시 m 소멸 — 무효 객체 접근 */
return t;
}
int main(void){ pthread_t t = start(); pthread_join(t, NULL); return 0; }✅ 준수 예시Compliant example
#include <pthread.h>
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; /* 정적 저장 기간 */
static void *work(void *arg){ pthread_mutex_t *mp = arg; pthread_mutex_lock(mp); pthread_mutex_unlock(mp); return NULL; }
int main(void){
pthread_t t;
pthread_create(&t, NULL, work, &m);
pthread_join(t, NULL);
return 0;
}⚠️ 뮤텍스·조건변수 같은 POSIX 동기화 객체를 자동(지역) 저장 기간으로 선언해 다른 스레드와 공유하면, 그 객체를 만든 함수가 반환하는 순간 객체가 소멸해 공유 스레드가 무효 객체를 잠그려다 미정의 동작에 빠진다. 공유 동기화 객체는 정적 또는 동적 저장 기간으로 둔다.Declaring POSIX synchronization objects like mutexes or condition variables with automatic (local) storage duration and sharing them with other threads destroys the object when the creating function returns, so a sharing thread locks an invalid object — undefined behaviour. Give shared synchronization objects static or dynamic storage duration.
POS51-CPOS · Rule · L2✓ compilableSEI index
순환 대기로 인한 스레드 교착을 방지한다Avoid deadlock with POSIX threads by locking in a predefined order
❌ 위반 예시Non-compliant example
#include <pthread.h>
static pthread_mutex_t a = PTHREAD_MUTEX_INITIALIZER, b = PTHREAD_MUTEX_INITIALIZER;
static void *t2(void *p){ (void)p;
pthread_mutex_lock(&b); pthread_mutex_lock(&a); /* 반대 순서 — 순환 대기 교착 위험 */
pthread_mutex_unlock(&a); pthread_mutex_unlock(&b); return NULL; }
int main(void){
pthread_mutex_lock(&a); pthread_mutex_lock(&b);
pthread_mutex_unlock(&b); pthread_mutex_unlock(&a);
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
static pthread_mutex_t a = PTHREAD_MUTEX_INITIALIZER, b = PTHREAD_MUTEX_INITIALIZER;
static void *t2(void *p){ (void)p;
pthread_mutex_lock(&a); pthread_mutex_lock(&b); /* 전역 잠금 순서 a→b 로 통일 */
pthread_mutex_unlock(&b); pthread_mutex_unlock(&a); return NULL; }
int main(void){
pthread_mutex_lock(&a); pthread_mutex_lock(&b);
pthread_mutex_unlock(&b); pthread_mutex_unlock(&a);
return 0;
}⚠️ 스레드마다 두 뮤텍스를 잠그는 순서가 다르면(한쪽은 a→b, 다른 쪽은 b→a) 서로가 상대의 잠금을 기다리는 순환 대기 교착이 발생한다. 모든 스레드가 동일한 전역 잠금 순서(예: 항상 a→b)를 따르도록 강제해 순환을 끊는다.If threads lock two mutexes in different orders (one a→b, another b→a), each waits on the other’s lock — a circular-wait deadlock. Enforce a single global lock ordering (e.g., always a→b) across all threads to break the cycle.
POS53-CPOS · Rule · L2✓ compilableSEI index
조건 변수는 항상 같은 뮤텍스와 함께 사용한다Do not use more than one mutex for concurrent waiting operations on a condition variable
❌ 위반 예시Non-compliant example
#include <pthread.h>
static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER, m2 = PTHREAD_MUTEX_INITIALIZER;
static void wait_a(void){ pthread_mutex_lock(&m1); pthread_cond_wait(&cv, &m1); pthread_mutex_unlock(&m1); }
static void wait_b(void){ pthread_mutex_lock(&m2); pthread_cond_wait(&cv, &m2); pthread_mutex_unlock(&m2); }
int main(void){ (void)&wait_a; (void)&wait_b; return 0; } /* 같은 cv 에 서로 다른 뮤텍스 — 미정의 */✅ 준수 예시Compliant example
#include <pthread.h>
static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static void wait_for(void){ pthread_mutex_lock(&m); pthread_cond_wait(&cv, &m); pthread_mutex_unlock(&m); }
int main(void){ (void)&wait_for; return 0; } /* 항상 동일 뮤텍스(m) 사용 */⚠️ 하나의 조건 변수에 대해 서로 다른 뮤텍스로 동시에 대기하면, 조건 변수 내부의 대기 큐와 잠금 해제·재획득 규약이 깨져 미정의 동작이 된다. 한 조건 변수에는 항상 같은 뮤텍스를 짝지어 사용한다.Waiting on one condition variable with different mutexes concurrently breaks the condition variable’s internal wait queue and its unlock/re-acquire protocol — undefined behaviour. Always pair a condition variable with the same single mutex.
POS34-CPOS · Rule · L1✓ compilableSEI index
putenv() 에 자동(지역) 변수를 넘기지 않는다Do not call putenv() with a pointer to an automatic variable as the argument
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
void set_var(int v){
char buf[32];
snprintf(buf, sizeof buf, "K=%d", v);
putenv(buf); /* putenv 는 이 포인터를 보관 — 함수 종료 후 무효 메모리 */
}
int main(void){ set_var(7); return 0; }✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
char val[16];
snprintf(val, sizeof val, "%d", 7);
setenv("K", val, 1); /* setenv 는 값을 복사함 */
return 0;
}⚠️ putenv는 넘긴 메모리를 그대로 참조하므로, 지역 버퍼를 넘기면 함수 종료 후 환경이 무효 메모리를 가리킨다. 복사하는 setenv를 쓴다.putenv retains the pointer it is given, so passing a local buffer leaves the environment pointing at invalid memory after the function returns. Use setenv, which copies.
POS35-CPOS · Rule · L2✓ compilableSEI index
심볼릭 링크 확인 시 경쟁 조건을 피한다Avoid race conditions while checking for the existence of a symbolic link
❌ 위반 예시Non-compliant example
#define _GNU_SOURCE
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
int main(void){
const char *p = "/tmp/cert_demo_file";
struct stat st;
if (lstat(p, &st) == 0 && !S_ISLNK(st.st_mode)) {
int fd = open(p, O_RDONLY); /* 검사와 open 사이에 링크로 교체 가능(TOCTOU) */
if (fd >= 0) close(fd);
}
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <fcntl.h>
#include <unistd.h>
int main(void){
const char *p = "/tmp/cert_demo_file";
int fd = open(p, O_RDONLY | O_NOFOLLOW); /* 링크면 원자적으로 거부 */
if (fd >= 0) close(fd);
return 0;
}⚠️ lstat 검사와 open 사이에 경로가 심볼릭 링크로 교체되면 의도치 않은 파일이 열린다. O_NOFOLLOW로 원자적으로 링크를 거부한다.If the path is swapped to a symlink between the lstat check and the open, an unintended file is opened. Use O_NOFOLLOW to refuse symlinks atomically.
POS36-CPOS · Rule · L1✓ compilableSEI index
권한 포기(setuid/setgid)는 올바른 순서로 수행한다Observe correct revocation order while relinquishing privileges
❌ 위반 예시Non-compliant example
#define _GNU_SOURCE
#include <unistd.h>
int main(void){
/* 데모: 실제 권한 변경은 root 권한이 필요하므로 호출 순서만 예시 */
(void)setuid(1000); /* 사용자 권한을 먼저 버리면 그룹 권한을 버릴 권한이 사라짐 */
(void)setgid(1000); /* 이미 권한이 없어 실패할 수 있음 */
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <unistd.h>
int main(void){
(void)setgid(1000); /* 그룹(및 보조 그룹) 권한을 먼저 포기 */
(void)setuid(1000); /* 그 다음 사용자 권한 포기 */
return 0;
}⚠️ 사용자(uid) 권한을 먼저 포기하면 그룹(gid)·보조 그룹 권한을 변경할 권한까지 함께 사라져, 그룹 권한이 상승된 채로 남는 위험이 생긴다. 항상 그룹·보조 그룹 권한을 먼저 포기하고 사용자 권한을 나중에 포기해 모든 상승 권한이 확실히 내려가게 한다.Relinquishing user (uid) privileges first also removes the ability to change group (gid) and supplementary-group privileges, risking leaving elevated group privileges in place. Always drop group and supplementary-group privileges first and user privileges last, so all elevated privileges are reliably lowered.
POS37-CPOS · Rule · L1✓ compilableSEI index
권한 포기가 실제로 성공했는지 확인한다Ensure that privilege relinquishment is successful
❌ 위반 예시Non-compliant example
#define _GNU_SOURCE
#include <unistd.h>
static void do_work(void){ /* 권한이 필요한 작업 */ }
int main(void){
setuid(1000); /* 반환값 미검사 — 실패해도 상승 권한으로 계속 실행 */
do_work();
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <unistd.h>
#include <stdlib.h>
static void do_work(void){ /* 권한이 필요한 작업 */ }
int main(void){
if (setuid(1000) != 0) { _Exit(1); } /* 반환값 검사 */
if (getuid() != 1000) { _Exit(1); } /* 실제로 포기됐는지 재확인 */
do_work();
return 0;
}⚠️ setuid/setgid 호출이 실패해도 반환값을 무시하면 의도와 달리 상승된 권한이 그대로 유지된 채 위험한 작업을 수행하게 되어 권한 상승 취약점이 된다. 반환값을 검사하고, getuid/getgid 로 실제 권한이 의도대로 낮아졌는지까지 확인한다.Ignoring the return value of setuid/setgid when it fails lets the program run sensitive work with elevated privileges still intact — a privilege-escalation vulnerability. Check the return value and also verify with getuid/getgid that privileges were actually lowered as intended.
POS38-CPOS · Rule · L2✓ compilableSEI index
fork 후 파일 디스크립터 경쟁을 피한다Beware of race conditions when using fork and file descriptors
❌ 위반 예시Non-compliant example
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
int main(void){
int fd = open("/dev/null", O_WRONLY);
pid_t p = fork();
(void)p;
write(fd, "x", 1); /* 부모/자식이 같은 fd(오프셋 공유)에 동시 쓰기 — 데이터 섞임 */
if (fd >= 0) close(fd);
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
int main(void){
pid_t p = fork();
int fd = open("/dev/null", O_WRONLY); /* 부모·자식이 각자 fd 를 연다 */
if (fd >= 0) { write(fd, "x", 1); close(fd); }
(void)p;
return 0;
}⚠️ fork 전에 연 파일 디스크립터는 부모와 자식이 동일한 열린-파일 기술자(파일 오프셋)를 공유하므로, 둘이 동기화 없이 동시에 쓰면 오프셋 경쟁으로 데이터가 섞이거나 덮어써진다. 자식이 자체 디스크립터를 새로 열거나 명시적 동기화로 접근을 직렬화한다.A file descriptor opened before fork is shared by parent and child as the same open-file description (file offset), so concurrent writes without synchronization race on the offset, interleaving or overwriting data. Have the child open its own descriptor, or serialize access with explicit synchronization.
POS39-CPOS · Rule · L1✓ compilableSEI index
데이터 전송 시 올바른 바이트 순서(byte ordering)를 사용한다Use the correct byte ordering when transferring data between systems
❌ 위반 예시Non-compliant example
#include <stdint.h>
#include <stdio.h>
static uint32_t get_value(void){ return 0x01020304u; }
int main(void){
uint32_t v = get_value();
/* 호스트 바이트 순서 그대로 전송한다고 가정 — 엔디안이 다른 수신측에서 값이 뒤바뀜 */
printf("%02x %02x\n", (v >> 24) & 0xFF, v & 0xFF);
return 0;
}✅ 준수 예시Compliant example
#include <stdint.h>
#include <arpa/inet.h>
#include <stdio.h>
static uint32_t get_value(void){ return 0x01020304u; }
int main(void){
uint32_t net = htonl(get_value()); /* 네트워크 바이트 순서(빅엔디안)로 변환해 전송 */
/* 수신측은 ntohl 로 자신의 호스트 순서로 되돌린다 */
printf("%02x %02x\n", (net >> 24) & 0xFF, net & 0xFF);
return 0;
}⚠️ 엔디안이 서로 다른 호스트 사이에서 정수를 바이트 순서 변환 없이 그대로 전송하면, 수신측이 바이트를 반대로 해석해 0x01020304 가 0x04030201 처럼 뒤바뀐 값이 된다. 전송 전에 htonl/htons 로 네트워크 바이트 순서로 변환하고 수신측에서 ntohl/ntohs 로 되돌린다.Sending an integer between hosts of different endianness without byte-order conversion makes the receiver interpret the bytes reversed, turning 0x01020304 into 0x04030201. Convert to network byte order with htonl/htons before sending and back with ntohl/ntohs on receipt.
POS52-CPOS · Rule · L2✓ compilableSEI index
잠금을 보유한 채 블로킹 연산을 수행하지 않는다Do not perform operations that can block while holding a POSIX lock
❌ 위반 예시Non-compliant example
#include <pthread.h>
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static void blocking_io(void){ /* 오래 걸리는 I/O 라고 가정 */ }
static void update(void){ /* 공유 상태 갱신 */ }
int main(void){
pthread_mutex_lock(&m);
blocking_io(); /* 잠금을 쥔 채 블로킹 — 다른 스레드가 그 시간 내내 대기 */
update();
pthread_mutex_unlock(&m);
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static void blocking_io(void){ /* 오래 걸리는 I/O 라고 가정 */ }
static void update(void){ /* 공유 상태 갱신 */ }
int main(void){
blocking_io(); /* 블로킹은 잠금 밖에서 수행 */
pthread_mutex_lock(&m);
update(); /* 공유 상태 갱신만 짧게 잠금 */
pthread_mutex_unlock(&m);
return 0;
}⚠️ 잠금을 보유한 채 네트워크·디스크 I/O 같은 블로킹 연산을 하면, 그 잠금을 기다리는 다른 스레드들이 I/O 가 끝날 때까지 모두 멈춰 처리량이 급락하고 교착 위험이 커진다. 블로킹 연산은 잠금 밖에서 수행하고, 공유 상태를 실제로 갱신하는 짧은 구간만 잠근다.Performing a blocking operation such as network or disk I/O while holding a lock stalls every other thread waiting on that lock until the I/O completes, crashing throughput and raising deadlock risk. Do blocking operations outside the lock and hold it only for the short section that actually updates shared state.
POS05-CPRE · Rec · SEISEI index
Limit access to files by creating a jailLimit access to files by creating a jail
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for POS05-C * SEI official index entry: Limit access to files by creating a jail * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for POS05-C * SEI official index entry: Limit access to files by creating a jail * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ POS05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.POS05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
POS01-CPOS · Rec · SEISEI index
Check for the existence of links when dealing with filesCheck for the existence of links when dealing with files
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for POS01-C * SEI official index entry: Check for the existence of links when dealing with files * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for POS01-C * SEI official index entry: Check for the existence of links when dealing with files * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ POS01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.POS01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
POS02-CPOS · Rec · SEISEI index
Follow the principle of least privilegeFollow the principle of least privilege
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for POS02-C * SEI official index entry: Follow the principle of least privilege * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for POS02-C * SEI official index entry: Follow the principle of least privilege * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ POS02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.POS02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON동시성Concurrency
CON43-CCON · Rule · L2✓ compilableSEI index
멀티스레드에서 데이터 경쟁(data race)을 허용하지 않는다Do not allow data races in multithreaded code
❌ 위반 예시Non-compliant example
#include <pthread.h>
int shared = 0;
void *t(void *p){ (void)p; for (int i = 0; i < 100000; i++) shared++; return NULL; }
int main(void){
pthread_t a, b;
pthread_create(&a, NULL, t, NULL); pthread_create(&b, NULL, t, NULL);
pthread_join(a, NULL); pthread_join(b, NULL);
return shared & 0x7f; /* 보호 없는 공유 갱신 — 데이터 경쟁 */
}✅ 준수 예시Compliant example
#include <pthread.h>
int shared = 0;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
void *t(void *p){ (void)p;
for (int i = 0; i < 100000; i++){ pthread_mutex_lock(&m); shared++; pthread_mutex_unlock(&m); }
return NULL; }
int main(void){
pthread_t a, b;
pthread_create(&a, NULL, t, NULL); pthread_create(&b, NULL, t, NULL);
pthread_join(a, NULL); pthread_join(b, NULL);
return shared & 0x7f;
}⚠️ 동기화 없이 공유 변수를 여러 스레드가 갱신하면 데이터 경쟁으로 결과가 미정의가 된다. 뮤텍스나 원자 연산으로 보호한다.Updating a shared variable from multiple threads without synchronization is a data race with undefined results. Protect it with a mutex or atomics.
CON37-CCON · Rule · L2✓ compilableSEI index
멀티스레드 프로그램에서 signal() 을 호출하지 않는다Do not call signal() in a multithreaded program
❌ 위반 예시Non-compliant example
#include <signal.h>
#include <pthread.h>
static void handler(int s){ (void)s; }
static void *worker(void *p){ (void)p; return NULL; }
int main(void){
signal(SIGINT, handler); /* 멀티스레드에서 signal() 의 동작은 미정의 */
pthread_t t; pthread_create(&t, NULL, worker, NULL); pthread_join(t, NULL);
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <signal.h>
#include <pthread.h>
int main(void){
sigset_t set;
sigemptyset(&set); sigaddset(&set, SIGINT);
pthread_sigmask(SIG_BLOCK, &set, NULL); /* 모든 스레드에서 차단 후 */
int sig;
/* 전용 스레드에서 sigwait 로 동기 처리하는 모델(여기선 즉시 반환을 위해 호출만 예시) */
(void)sig;
return 0;
}⚠️ 멀티스레드 환경에서 signal() 로 설정한 핸들러가 어느 스레드에서 실행될지, 다른 스레드의 signal() 호출과 어떻게 상호작용할지는 표준이 정의하지 않아 동작이 미정의다. 시그널은 모든 스레드에서 차단한 뒤 전용 스레드에서 sigwait 로 동기적으로 처리하는 모델을 사용한다.In a multithreaded program, which thread runs a handler set by signal() and how it interacts with other threads’ signal() calls is undefined by the standard. Block signals in all threads and handle them synchronously in a dedicated thread with sigwait.
CON30-CCON · Rule · L2✓ compilableSEI index
스레드별 저장소(thread-specific storage)를 정리한다Clean up thread-specific storage
❌ 위반 예시Non-compliant example
#include <pthread.h>
#include <stdlib.h>
static pthread_key_t key;
int main(void){
pthread_key_create(&key, NULL); /* 소멸자(destructor) 미등록 — 스레드 종료 시 누수 */
pthread_setspecific(key, malloc(64));
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
#include <stdlib.h>
static pthread_key_t key;
int main(void){
pthread_key_create(&key, free); /* 소멸자 등록 — 스레드 종료 시 자동 해제 */
pthread_setspecific(key, malloc(64));
return 0;
}⚠️ 스레드별 저장소에 동적 할당한 값을 넣으면서 소멸자(정리 콜백)를 등록하지 않으면, 스레드가 종료될 때 그 값이 해제되지 않아 스레드마다 메모리가 누수된다. 키 생성 시 정리 함수(예: free)를 등록하거나 스레드 종료 전에 명시적으로 해제한다.Storing a dynamically allocated value in thread-specific storage without registering a destructor (cleanup callback) leaks that value when the thread exits, accumulating leaks per thread. Register a cleanup function (e.g., free) at key creation, or free it explicitly before the thread exits.
CON31-CCON · Rule · L2✓ compilableSEI index
잠긴 뮤텍스를 파괴하지 않는다Do not destroy a mutex while it is locked
❌ 위반 예시Non-compliant example
#include <pthread.h>
int main(void){
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&m);
pthread_mutex_destroy(&m); /* 잠긴 상태로 파괴 — 미정의 동작 */
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
int main(void){
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&m);
/* critical section */
pthread_mutex_unlock(&m);
pthread_mutex_destroy(&m); /* 해제 후 파괴 */
return 0;
}⚠️ 잠긴 뮤텍스를 파괴하면 미정의 동작과 교착이 발생한다. 파괴 전에 반드시 잠금을 해제한다.Destroying a locked mutex is undefined behavior and can deadlock. Always unlock before destroying.
CON32-CCON · Rule · L2✓ compilableSEI index
비트필드 접근 시 데이터 경쟁을 방지한다Prevent data races when accessing bit-fields from multiple threads
❌ 위반 예시Non-compliant example
#include <pthread.h>
static struct { unsigned a : 1; unsigned b : 1; } f;
static void *t1(void *p){ (void)p; f.a = 1; return NULL; } /* 서로 다른 비트지만 */
static void *t2(void *p){ (void)p; f.b = 1; return NULL; } /* 같은 메모리 워드 동시 갱신 — 경쟁 */
int main(void){
pthread_t a, b;
pthread_create(&a, NULL, t1, NULL); pthread_create(&b, NULL, t2, NULL);
pthread_join(a, NULL); pthread_join(b, NULL);
return f.a + f.b;
}✅ 준수 예시Compliant example
#include <pthread.h>
static struct { unsigned a : 1; unsigned b : 1; } f;
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static void *t1(void *p){ (void)p; pthread_mutex_lock(&m); f.a = 1; pthread_mutex_unlock(&m); return NULL; }
static void *t2(void *p){ (void)p; pthread_mutex_lock(&m); f.b = 1; pthread_mutex_unlock(&m); return NULL; }
int main(void){
pthread_t a, b;
pthread_create(&a, NULL, t1, NULL); pthread_create(&b, NULL, t2, NULL);
pthread_join(a, NULL); pthread_join(b, NULL);
return f.a + f.b;
}⚠️ 인접한 비트필드는 같은 메모리 워드(저장 단위)를 공유하므로, 서로 다른 비트를 갱신하더라도 두 스레드가 그 워드를 동시에 읽고-쓰면 한쪽 갱신이 다른 쪽에 덮어써지는 데이터 경쟁이 발생한다. 비트필드 접근을 같은 잠금으로 보호한다.Adjacent bit-fields share the same memory word (storage unit), so even when updating different bits, two threads reading and writing that word concurrently race — one update overwrites the other. Protect bit-field accesses with the same lock.
CON33-CCON · Rule · L2✓ compilableSEI index
라이브러리 함수 사용 시 경쟁 조건을 피한다Avoid race conditions when using library functions
❌ 위반 예시Non-compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char buf[] = "a,b,c";
char *t = strtok(buf, ","); /* 내부 정적 상태 공유 — 멀티스레드 비안전 */
while (t) { printf("%s\n", t); t = strtok(NULL, ","); }
return 0;
}✅ 준수 예시Compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char buf[] = "a,b,c";
char *save;
char *t = strtok_r(buf, ",", &save); /* 재진입(_r) 버전 */
while (t) { printf("%s\n", t); t = strtok_r(NULL, ",", &save); }
return 0;
}⚠️ strtok/rand/asctime 등 내부 정적 상태를 쓰는 함수는 멀티스레드에서 경쟁한다. 재진입(_r) 또는 스레드-안전 변형을 쓴다.Functions with internal static state (strtok/rand/asctime) race across threads. Use reentrant (_r) or thread-safe variants.
CON34-CCON · Rule · L2✓ compilableSEI index
스레드 간 공유 객체는 적절한 저장 기간으로 선언한다Declare objects shared between threads with appropriate storage durations
❌ 위반 예시Non-compliant example
#include <pthread.h>
static void *worker(void *arg){ int *p = arg; return (void *)(long)*p; }
static pthread_t spawn_with_local(void){
int local = 0; /* 자동 저장 기간 */
pthread_t t;
pthread_create(&t, NULL, worker, &local); /* 함수 종료 시 local 소멸 — 댕글링 공유 */
return t;
}
int main(void){ pthread_t t = spawn_with_local(); pthread_join(t, NULL); return 0; }✅ 준수 예시Compliant example
#include <pthread.h>
static int shared = 0; /* 정적 저장 기간 — 프로그램 수명 동안 유효 */
static void *worker(void *arg){ int *p = arg; return (void *)(long)*p; }
int main(void){
pthread_t t;
pthread_create(&t, NULL, worker, &shared);
pthread_join(t, NULL);
return 0;
}⚠️ 자동 저장 기간(지역) 객체의 주소를 다른 스레드와 공유하면, 그 객체를 만든 함수가 반환하는 순간 객체가 소멸해 공유 스레드가 댕글링 포인터를 참조하는 미정의 동작이 된다. 스레드 간 공유 객체는 정적 또는 동적 저장 기간으로 선언해 수명이 충분히 유지되게 한다.Sharing the address of an automatic (local) object with another thread makes it a dangling pointer the moment the creating function returns and the object is destroyed — undefined behaviour. Declare objects shared between threads with static or dynamic storage duration so their lifetime is long enough.
CON35-CCON · Rule · L2✓ compilableSEI index
정해진 순서로 잠가 교착(deadlock)을 방지한다Lock in a predefined order to avoid deadlock
❌ 위반 예시Non-compliant example
#include <pthread.h>
pthread_mutex_t A = PTHREAD_MUTEX_INITIALIZER, B = PTHREAD_MUTEX_INITIALIZER;
void *t2(void *p){ (void)p;
pthread_mutex_lock(&B); pthread_mutex_lock(&A); /* 반대 순서 — 교착 위험 */
pthread_mutex_unlock(&A); pthread_mutex_unlock(&B); return NULL; }
int main(void){
pthread_mutex_lock(&A); pthread_mutex_lock(&B);
pthread_mutex_unlock(&B); pthread_mutex_unlock(&A);
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
pthread_mutex_t A = PTHREAD_MUTEX_INITIALIZER, B = PTHREAD_MUTEX_INITIALIZER;
void *t2(void *p){ (void)p;
pthread_mutex_lock(&A); pthread_mutex_lock(&B); /* 모든 스레드 동일 순서 */
pthread_mutex_unlock(&B); pthread_mutex_unlock(&A); return NULL; }
int main(void){
pthread_mutex_lock(&A); pthread_mutex_lock(&B);
pthread_mutex_unlock(&B); pthread_mutex_unlock(&A);
return 0;
}⚠️ 스레드마다 잠금 순서가 다르면 서로의 잠금을 기다리는 교착이 생긴다. 전역적으로 일관된 잠금 순서를 정한다.Different lock orders across threads cause a deadlock where each waits on the other’s lock. Define a globally consistent lock ordering.
CON36-CCON · Rule · L2✓ compilableSEI index
조건 변수 대기는 루프로 감싼다Wrap condition-variable waits in a loop
❌ 위반 예시Non-compliant example
#include <pthread.h>
int ready = 0;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
void *w(void *p){ (void)p; pthread_mutex_lock(&m); ready = 1;
pthread_cond_signal(&cv); pthread_mutex_unlock(&m); return NULL; }
int main(void){
pthread_t th; pthread_create(&th, NULL, w, NULL);
pthread_mutex_lock(&m);
if (!ready) pthread_cond_wait(&cv, &m); /* if — 가짜 깨어남 처리 못함 */
pthread_mutex_unlock(&m);
pthread_join(th, NULL);
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
int ready = 0;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
void *w(void *p){ (void)p; pthread_mutex_lock(&m); ready = 1;
pthread_cond_signal(&cv); pthread_mutex_unlock(&m); return NULL; }
int main(void){
pthread_t th; pthread_create(&th, NULL, w, NULL);
pthread_mutex_lock(&m);
while (!ready) pthread_cond_wait(&cv, &m); /* while — 조건 재확인 */
pthread_mutex_unlock(&m);
pthread_join(th, NULL);
return 0;
}⚠️ 조건 변수는 가짜 깨어남(spurious wakeup)이 발생할 수 있어 if로는 조건이 거짓인데 진행한다. while 루프로 조건을 재확인한다.Condition variables can wake spuriously, so an if lets execution proceed while the predicate is still false. Re-check the predicate in a while loop.
CON38-CCON · Rule · L2✓ compilableSEI index
조건 변수 사용 시 스레드 안전성과 진행성(liveness)을 지킨다Preserve thread safety and liveness when using condition variables
❌ 위반 예시Non-compliant example
#include <pthread.h>
static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
int main(void){
pthread_cond_signal(&cv); /* 잠금·술어 설정 없이 신호 — 대기 스레드 없으면 신호 유실 */
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
static int ready = 0;
int main(void){
pthread_mutex_lock(&m);
ready = 1; /* 잠금 안에서 술어를 갱신하고 */
pthread_cond_broadcast(&cv); /* 모든 대기자에게 신호(유실·기아 방지) */
pthread_mutex_unlock(&m);
return 0;
}⚠️ 조건 변수에 잠금과 술어(예: ready) 설정 없이 신호만 보내면, 아직 대기에 들어가지 않은 스레드가 신호를 놓쳐(신호 유실) 영원히 깨어나지 못하는 진행성 결함이 생긴다. 잠금 안에서 술어를 갱신한 뒤 신호(필요 시 broadcast)를 보내고, 대기 측은 while 술어 루프로 재확인한다.Signaling a condition variable without holding the lock and setting a predicate (e.g., ready) lets a thread not yet waiting miss the signal (lost wakeup), a liveness defect where it never wakes. Update the predicate under the lock before signaling (broadcast if needed), and have waiters re-check in a while-predicate loop.
CON39-CCON · Rule · L2✓ compilableSEI index
이미 join/detach 한 스레드를 다시 join/detach 하지 않는다Do not join or detach a thread that was previously joined or detached
❌ 위반 예시Non-compliant example
#include <pthread.h>
void *worker(void *p){ (void)p; return NULL; }
int main(void){
pthread_t t;
pthread_create(&t, NULL, worker, NULL);
pthread_join(t, NULL);
pthread_join(t, NULL); /* 이미 join 된 스레드 재join — 미정의 동작 */
return 0;
}✅ 준수 예시Compliant example
#include <pthread.h>
void *worker(void *p){ (void)p; return NULL; }
int main(void){
pthread_t t;
pthread_create(&t, NULL, worker, NULL);
int joined = 0;
if (!joined) { pthread_join(t, NULL); joined = 1; } /* 한 번만 회수 */
(void)joined;
return 0;
}⚠️ 이미 회수된 스레드 핸들을 다시 join/detach하면 미정의 동작이다. 상태를 추적해 한 번만 수행한다.Joining or detaching an already-reaped thread handle is undefined behavior. Track the state and do it exactly once.
CON40-CCON · Rule · L2✓ compilableSEI index
한 표현식에서 원자 변수를 두 번 참조하지 않는다Do not refer to an atomic variable twice in an expression
❌ 위반 예시Non-compliant example
#include <stdatomic.h>
int main(void){
atomic_int a = 0;
a = a + 1; /* 읽기+쓰기 두 연산 — 사이에 경쟁, 원자성 깨짐 */
return atomic_load(&a);
}✅ 준수 예시Compliant example
#include <stdatomic.h>
int main(void){
atomic_int a = 0;
atomic_fetch_add(&a, 1); /* 단일 원자 RMW 연산 */
return atomic_load(&a);
}⚠️ 원자 변수를 같은 식에서 읽고 다시 쓰면 두 연산 사이에 경쟁이 생겨 원자성이 깨진다. 원자 RMW 연산을 사용한다.Reading then writing an atomic variable in the same expression opens a race between the two operations. Use an atomic read-modify-write operation.
CON41-CCON · Rule · L2✓ compilableSEI index
가짜 실패가 가능한 원자 연산은 루프로 감싼다Wrap functions that can fail spuriously in a loop
❌ 위반 예시Non-compliant example
#include <stdatomic.h>
int main(void){
atomic_int v = 0;
int expected = 0;
atomic_compare_exchange_weak(&v, &expected, 5); /* weak 은 가짜 실패 가능 — 한 번으론 보장 못함 */
return atomic_load(&v);
}✅ 준수 예시Compliant example
#include <stdatomic.h>
int main(void){
atomic_int v = 0;
int expected = 0;
while (!atomic_compare_exchange_weak(&v, &expected, 5)) {
/* 가짜 실패 시 expected 가 갱신되므로 루프로 재시도 */
}
return atomic_load(&v);
}⚠️ atomic_compare_exchange_weak 같은 연산은 값이 일치해도 하드웨어 사정으로 가짜 실패(spurious failure)할 수 있어, 한 번 호출로는 교환 성공을 보장하지 못한다. 성공할 때까지 루프로 감싸 재시도하고(strong 변형이 적합한 경우엔 그쪽을 쓴다), 매 반복에서 expected 갱신을 활용한다.Operations like atomic_compare_exchange_weak may fail spuriously due to hardware reasons even when the values match, so a single call does not guarantee the exchange. Wrap it in a retry loop until it succeeds (or use the strong variant when appropriate), making use of the updated expected each iteration.
CON42-CCON · Rule · SEISEI index
Don't allow attackers to influence environment variables that control concurrency parametersDon't allow attackers to influence environment variables that control concurrency parameters
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON42-C * SEI official index entry: Don't allow attackers to influence environment variables that control concurrency parameters * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON42-C * SEI official index entry: Don't allow attackers to influence environment variables that control concurrency parameters * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON42-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON42-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON04-CCON · Rule · SEISEI index
Join or detach threads even if their exit status is unimportantJoin or detach threads even if their exit status is unimportant
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON04-C * SEI official index entry: Join or detach threads even if their exit status is unimportant * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON04-C * SEI official index entry: Join or detach threads even if their exit status is unimportant * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON09-CDCL · Rec · SEISEI index
Avoid the ABA problem when using lock-free algorithmsAvoid the ABA problem when using lock-free algorithms
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON09-C * SEI official index entry: Avoid the ABA problem when using lock-free algorithms * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON09-C * SEI official index entry: Avoid the ABA problem when using lock-free algorithms * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON01-CCON · Rec · SEISEI index
Acquire and release synchronization primitives in the same module, at the same level of abstractionAcquire and release synchronization primitives in the same module, at the same level of abstraction
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON01-C * SEI official index entry: Acquire and release synchronization primitives in the same module, at the same level of abstraction * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON01-C * SEI official index entry: Acquire and release synchronization primitives in the same module, at the same level of abstraction * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON02-CCON · Rec · SEISEI index
Do not use volatile as a synchronization primitiveDo not use volatile as a synchronization primitive
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON02-C * SEI official index entry: Do not use volatile as a synchronization primitive * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON02-C * SEI official index entry: Do not use volatile as a synchronization primitive * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON03-CCON · Rec · SEISEI index
Ensure visibility when accessing shared variablesEnsure visibility when accessing shared variables
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON03-C * SEI official index entry: Ensure visibility when accessing shared variables * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON03-C * SEI official index entry: Ensure visibility when accessing shared variables * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON03-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON03-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON05-CCON · Rec · SEISEI index
Do not perform operations that can block while holding a lockDo not perform operations that can block while holding a lock
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON05-C * SEI official index entry: Do not perform operations that can block while holding a lock * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON05-C * SEI official index entry: Do not perform operations that can block while holding a lock * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON06-CCON · Rec · SEISEI index
Ensure that every mutex outlives the data it protectsEnsure that every mutex outlives the data it protects
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON06-C * SEI official index entry: Ensure that every mutex outlives the data it protects * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON06-C * SEI official index entry: Ensure that every mutex outlives the data it protects * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON07-CCON · Rec · SEISEI index
Ensure that compound operations on shared variables are atomicEnsure that compound operations on shared variables are atomic
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON07-C * SEI official index entry: Ensure that compound operations on shared variables are atomic * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON07-C * SEI official index entry: Ensure that compound operations on shared variables are atomic * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CON08-CCON · Rec · SEISEI index
Do not assume that a group of calls to independently atomic methods is atomicDo not assume that a group of calls to independently atomic methods is atomic
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for CON08-C * SEI official index entry: Do not assume that a group of calls to independently atomic methods is atomic * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for CON08-C * SEI official index entry: Do not assume that a group of calls to independently atomic methods is atomic * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ CON08-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.CON08-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP표현식Expressions
EXP30-CEXP · Rule · L2✓ compilableSEI index
부작용의 평가 순서에 의존하지 않는다Do not depend on the order of evaluation for side effects
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int a[4] = {0};
int i = 0;
a[i] = i++; /* i 사용과 증가 순서 미명세 */
printf("%d %d\n", a[0], i);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int a[4] = {0};
int i = 0;
a[i] = i;
i++; /* 부작용 분리 */
printf("%d %d\n", a[0], i);
return 0;
}⚠️ 한 표현식에서 같은 객체를 수정·사용하면 평가 순서에 따라 결과가 달라진다. 부작용을 분리해 순서를 결정한다.Modifying and reading the same object in one expression makes the result order-dependent. Separate the side effect to fix the order.
EXP32-CEXP · Rule · L1✓ compilableSEI index
volatile 객체를 비-volatile 참조로 접근하지 않는다Do not access a volatile object through a nonvolatile reference
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
volatile int reg = 1;
int *p = (int *)® /* volatile 의미 상실 */
printf("%d\n", *p);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
volatile int reg = 1;
volatile int *p = ®
printf("%d\n", *p);
return 0;
}⚠️ volatile 객체를 비-volatile 포인터로 접근하면 컴파일러가 접근을 최적화로 제거·재배치해 하드웨어 동작이 깨진다. 한정자를 보존한다.Accessing a volatile object through a nonvolatile pointer lets the compiler optimize away or reorder accesses, breaking hardware semantics. Preserve the qualifier.
EXP33-CEXP · Rule · L3✓ compilableSEI index
초기화되지 않은 메모리를 읽지 않는다Do not read uninitialized memory
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int a[3] = {1,2,3};
int sum; /* 미초기화 */
for (int i = 0; i < 3; i++) sum += a[i];
printf("%d\n", sum);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int a[3] = {1,2,3};
int sum = 0;
for (int i = 0; i < 3; i++) sum += a[i];
printf("%d\n", sum);
return 0;
}⚠️ 미초기화 객체의 값은 불확정이라 읽으면 미정의 동작과 비결정적 결과를 낳는다. 사용 전 초기화한다.An uninitialized object holds an indeterminate value; reading it is undefined and nondeterministic. Initialize before use.
EXP34-CEXP · Rule · L1✓ compilableSEI index
널 포인터를 역참조하지 않는다Do not dereference null pointers
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <stdlib.h>
int main(void){
int *p = malloc(sizeof *p);
*p = 5; /* malloc 실패(NULL) 미검사 */
printf("%d\n", *p);
free(p);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdlib.h>
int main(void){
int *p = malloc(sizeof *p);
if (p == NULL) return 1;
*p = 5;
printf("%d\n", *p);
free(p);
return 0;
}⚠️ 널 포인터 역참조는 크래시나 미정의 동작을 일으킨다. 역참조 전에 NULL 여부를 확인한다.Dereferencing a null pointer causes a crash or undefined behavior. Check for NULL before dereferencing.
EXP35-CEXP · Rule · L1✓ compilableSEI index
임시(temporary) 수명 객체를 수정하거나 그 수명 밖에서 접근하지 않는다Do not modify objects with temporary lifetime
❌ 위반 예시Non-compliant example
#include <stdio.h>
struct S { int a[4]; };
static struct S f(void){ struct S s = {{0,0,0,0}}; return s; }
int main(void){
int *p = f().a; /* 임시 객체의 멤버 배열 주소 — 전체 식이 끝나면 임시 소멸 */
*p = 1; /* 소멸한 임시에 접근 — 미정의 동작 */
printf("%d\n", *p);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
struct S { int a[4]; };
static struct S f(void){ struct S s = {{0,0,0,0}}; return s; }
int main(void){
struct S s = f(); /* 임시를 지속 객체에 복사해 보관 */
s.a[0] = 1;
printf("%d\n", s.a[0]);
return 0;
}⚠️ 함수가 값으로 반환한 구조체는 임시 수명 객체라 그것을 포함한 전체 식이 끝나는 즉시 소멸하므로, 그 내부 배열·멤버의 주소를 보관했다 접근·수정하면 사라진 객체를 가리키는 미정의 동작이 된다. 반환값을 지속 수명 객체에 복사한 뒤 다룬다.A struct returned by value has temporary lifetime and is destroyed as soon as the full expression containing it ends, so storing and then accessing/modifying the address of its array or member dereferences a vanished object — undefined behaviour. Copy the return value into an object of persistent lifetime first.
EXP36-CEXP · Rule · L1✓ compilableSEI index
포인터를 더 엄격히 정렬된 타입으로 캐스트하지 않는다Do not cast pointers into more strictly aligned pointer types
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <string.h>
int main(void){
char buf[16] = {0};
int *p = (int *)&buf[1]; /* 정렬 위반 가능 */
*p = 42;
printf("%d\n", *p);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <string.h>
int main(void){
char buf[16] = {0};
int v = 42;
memcpy(&buf[1], &v, sizeof v); /* 정렬 무관 */
memcpy(&v, &buf[1], sizeof v);
printf("%d\n", v);
return 0;
}⚠️ 정렬 요건이 더 큰 타입으로 포인터를 캐스트해 접근하면 일부 플랫폼에서 폴트나 미정의 동작이 난다. memcpy로 정렬 비의존 접근을 한다.Casting to a more strictly aligned type and dereferencing can fault or be undefined on some platforms. Use memcpy for alignment-independent access.
EXP37-CEXP · Rule · L1✓ compilableSEI index
함수는 올바른 개수·타입의 인자로 호출한다Call functions with the correct number and type of arguments
❌ 위반 예시Non-compliant example
#include <stdio.h>
int add(int a, int b){ return a + b; }
int main(void){
int (*fp)(int) = (int (*)(int))add; /* 잘못된 시그니처로 호출 */
printf("%d\n", fp(3));
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int add(int a, int b){ return a + b; }
int main(void){
int (*fp)(int,int) = add;
printf("%d\n", fp(3, 4));
return 0;
}⚠️ 선언과 다른 시그니처로 함수를 호출하면 인자 전달이 어긋나 미정의 동작이 된다. 정확한 프로토타입대로 호출한다.Calling a function through a mismatched signature misaligns argument passing and is undefined. Call with the exact prototype.
EXP39-CEXP · Rule · L2✓ compilableSEI index
호환되지 않는 타입의 포인터로 변수에 접근하지 않는다Do not access a variable through a pointer of an incompatible type
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
float f = 3.14f;
unsigned u = *(unsigned *)&f; /* 엄격 별칭 위반 */
printf("%u\n", u);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <string.h>
int main(void){
float f = 3.14f;
unsigned u;
memcpy(&u, &f, sizeof u); /* 안전한 재해석 */
printf("%u\n", u);
return 0;
}⚠️ 엄격 별칭 규칙을 어기고 다른 타입 포인터로 접근하면 최적화와 충돌해 미정의 동작이 된다. memcpy로 안전하게 재해석한다.Violating strict aliasing by accessing through an incompatible pointer conflicts with optimization and is undefined. Reinterpret safely via memcpy.
EXP40-CEXP · Rule · L1✓ compilableSEI index
const 로 선언된 객체를 수정하지 않는다Do not modify constant objects
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
const int k = 5;
int *p = (int *)&k;
*p = 9; /* const 객체 수정 — 미정의 */
printf("%d\n", k);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int k = 5; /* 수정이 필요하면 비-const */
k = 9;
printf("%d\n", k);
return 0;
}⚠️ const 객체를 캐스트로 우회해 수정하면 미정의 동작이다. 수정이 필요한 객체는 처음부터 비-const로 선언한다.Modifying a const object by casting away const is undefined. Declare objects that must change as non-const from the start.
EXP42-CEXP · Rule · L2✓ compilableSEI index
구조체를 통째로 비교해 패딩 데이터까지 비교하지 않는다Do not compare padding data
❌ 위반 예시Non-compliant example
#include <string.h>
#include <stdio.h>
struct P { char c; int v; }; /* c 와 v 사이에 패딩 바이트 존재 가능 */
int main(void){
struct P a, b;
memset(&a, 0, sizeof a); a.c = 'x'; a.v = 1;
b.c = 'x'; b.v = 1; /* 패딩 바이트는 불확정 */
if (memcmp(&a, &b, sizeof a) == 0) printf("equal\n");
else printf("differ (padding)\n"); /* 논리적으로 같아도 패딩 때문에 다를 수 있음 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
struct P { char c; int v; };
int main(void){
struct P a = { 'x', 1 };
struct P b = { 'x', 1 };
if (a.c == b.c && a.v == b.v) printf("equal\n"); /* 멤버별 비교 */
else printf("differ\n");
return 0;
}⚠️ memcmp 로 구조체 전체를 비교하면 멤버 사이·끝에 채워지는 불확정 패딩 바이트까지 비교되어, 모든 멤버 값이 같아도 패딩 차이로 다르다고 판정될 수 있다. 의미 있는 동등성은 멤버별 비교로 판정한다.Comparing a whole struct with memcmp also compares the indeterminate padding bytes inserted between and after members, so two structs with identical member values can be judged different due to padding. Determine meaningful equality by comparing members individually.
EXP43-CEXP · Rule · L2✓ compilableSEI index
restrict 한정 포인터로 미정의 동작을 일으키지 않는다Avoid undefined behavior when using restrict-qualified pointers
❌ 위반 예시Non-compliant example
#include <stdio.h>
static void add(int *restrict a, const int *restrict b, int n){
for (int i = 0; i < n; i++) { a[i] += b[i]; } /* a, b 가 별칭 없음을 약속 */
}
int main(void){
int buf[4] = {1, 2, 3, 4};
add(buf, buf, 4); /* 같은 배열을 둘 다 전달 — restrict 약속 위반, 미정의 동작 */
printf("%d\n", buf[0]);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
static void add(int *a, const int *b, int n){ /* restrict 미사용 — 별칭 허용 */
for (int i = 0; i < n; i++) { a[i] += b[i]; }
}
int main(void){
int buf[4] = {1, 2, 3, 4};
add(buf, buf, 4); /* 겹쳐도 정의된 동작 */
printf("%d\n", buf[0]);
return 0;
}⚠️ restrict 는 해당 포인터들이 같은 메모리를 가리키지 않는다는 약속을 컴파일러에 주어 최적화를 허용하는데, 실제로 겹치는 포인터를 넘기면 그 약속이 깨져 진단 없는 미정의 동작이 된다. 별칭 가능성이 있는 인터페이스에서는 restrict 를 사용하지 않는다.restrict promises the compiler that the pointers do not alias, enabling optimizations, but passing overlapping pointers breaks that promise — undiagnosed undefined behaviour. Do not use restrict in interfaces where aliasing is possible.
EXP44-CEXP · Rule · L3✓ compilableSEI index
sizeof 피연산자의 부작용에 의존하지 않는다Do not rely on side effects in operands to sizeof
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int a[5] = {0};
int i = 0;
size_t n = sizeof(a[i++]); /* i 증가 안 됨 */
printf("%zu %d\n", n, i);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int a[5] = {0};
int i = 0;
size_t n = sizeof(a[0]);
i++;
printf("%zu %d\n", n, i);
return 0;
}⚠️ sizeof 의 피연산자(가변길이 배열 제외)는 평가되지 않아 부작용이 발생하지 않는다. 의도한 부작용은 별도 문장으로 수행한다.The operand of sizeof (except VLAs) is not evaluated, so side effects do not occur. Perform intended side effects in a separate statement.
EXP45-CEXP · Rule · L3✓ compilableSEI index
선택문의 조건에서 대입을 수행하지 않는다Do not perform assignments in selection statements
❌ 위반 예시Non-compliant example
#include <stdio.h>
int compute(void){ return 7; }
int main(void){
int x;
if (x = compute()){ printf("%d\n", x); } /* == 오타 혼동 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int compute(void){ return 7; }
int main(void){
int x = compute();
if (x != 0){ printf("%d\n", x); }
return 0;
}⚠️ 조건식 안의 대입은 비교(==) 오타와 혼동되며 의도가 불명확하다. 대입과 조건 검사를 분리한다.An assignment inside a condition is confused with an == typo and obscures intent. Separate the assignment from the test.
EXP46-CEXP · Rule · L3✓ compilableSEI index
불리언 성격의 피연산자에 비트 연산자를 쓰지 않는다Do not use a bitwise operator with a Boolean-like operand
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int a = 1, b = 1, c = 0, d = 0;
if ((a == b) & (c == d)){ printf("hit\n"); } /* & : 단락 없음 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int a = 1, b = 1, c = 0, d = 0;
if ((a == b) && (c == d)){ printf("hit\n"); }
return 0;
}⚠️ 논리 비교 결과에 비트 &/|를 쓰면 단락 평가가 사라지고 의도가 흐려진다. 논리 연산에는 &&/||를 쓴다.Using bitwise &/| on comparison results loses short-circuiting and obscures intent. Use &&/|| for logical operations.
EXP47-CEXP · Rule · L1✓ compilableSEI index
va_arg 를 잘못된 타입으로 호출하지 않는다Do not call va_arg with an argument of the incorrect type
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <stdarg.h>
long sum(int n, ...){
va_list ap; va_start(ap, n);
long s = 0;
for (int i = 0; i < n; i++) s += va_arg(ap, long); /* 실제는 int 전달 */
va_end(ap);
return s;
}
int main(void){ printf("%ld\n", sum(2, 1, 2)); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdarg.h>
long sum(int n, ...){
va_list ap; va_start(ap, n);
long s = 0;
for (int i = 0; i < n; i++) s += va_arg(ap, int); /* 전달 타입과 일치 */
va_end(ap);
return s;
}
int main(void){ printf("%ld\n", sum(2, 1, 2)); return 0; }⚠️ va_arg에 실제 전달된 타입과 다른 타입을 지정하면 잘못된 비트를 읽어 미정의 동작이 된다. 전달 타입과 정확히 일치시킨다.Specifying a va_arg type different from what was passed reads the wrong bits and is undefined. Match the promoted type exactly.
EXP00-CEXP · Rec · SEISEI index
Use parentheses for precedence of operationUse parentheses for precedence of operation
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP00-C * SEI official index entry: Use parentheses for precedence of operation * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP00-C * SEI official index entry: Use parentheses for precedence of operation * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP02-CEXP · Rec · SEISEI index
Be aware of the short-circuit behavior of the logical AND and OR operatorsBe aware of the short-circuit behavior of the logical AND and OR operators
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP02-C * SEI official index entry: Be aware of the short-circuit behavior of the logical AND and OR operators * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP02-C * SEI official index entry: Be aware of the short-circuit behavior of the logical AND and OR operators * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP03-CEXP · Rec · SEISEI index
Do not assume the size of a structure is the sum of the sizes of its membersDo not assume the size of a structure is the sum of the sizes of its members
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP03-C * SEI official index entry: Do not assume the size of a structure is the sum of the sizes of its members * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP03-C * SEI official index entry: Do not assume the size of a structure is the sum of the sizes of its members * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP03-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP03-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP05-CEXP · Rec · SEISEI index
Do not cast away a const qualificationDo not cast away a const qualification
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP05-C * SEI official index entry: Do not cast away a const qualification * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP05-C * SEI official index entry: Do not cast away a const qualification * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP07-CEXP · Rec · SEISEI index
Do not diminish the benefits of constants by assuming their values in expressionsDo not diminish the benefits of constants by assuming their values in expressions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP07-C * SEI official index entry: Do not diminish the benefits of constants by assuming their values in expressions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP07-C * SEI official index entry: Do not diminish the benefits of constants by assuming their values in expressions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP08-CEXP · Rec · SEISEI index
Ensure pointer arithmetic is used correctlyEnsure pointer arithmetic is used correctly
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP08-C * SEI official index entry: Ensure pointer arithmetic is used correctly * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP08-C * SEI official index entry: Ensure pointer arithmetic is used correctly * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP08-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP08-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP09-CEXP · Rec · SEISEI index
Use sizeof to determine the size of a type or variableUse sizeof to determine the size of a type or variable
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP09-C * SEI official index entry: Use sizeof to determine the size of a type or variable * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP09-C * SEI official index entry: Use sizeof to determine the size of a type or variable * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP10-CEXP · Rec · SEISEI index
Do not depend on the order of evaluation of subexpressions or the order in which side effects take placeDo not depend on the order of evaluation of subexpressions or the order in which side effects take place
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP10-C * SEI official index entry: Do not depend on the order of evaluation of subexpressions or the order in which side effects take place * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP10-C * SEI official index entry: Do not depend on the order of evaluation of subexpressions or the order in which side effects take place * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP10-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP10-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP11-CEXP · Rec · SEISEI index
Do not make assumptions regarding the layout of structures with bit-fieldsDo not make assumptions regarding the layout of structures with bit-fields
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP11-C * SEI official index entry: Do not make assumptions regarding the layout of structures with bit-fields * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP11-C * SEI official index entry: Do not make assumptions regarding the layout of structures with bit-fields * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP11-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP11-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP12-CEXP · Rec · L2✓ compilableSEI index
함수의 반환값을 무시하지 않는다Do not ignore values returned by functions
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
char buf[4];
snprintf(buf, sizeof buf, "%d", 12345); /* 절단 여부 무시 */
printf("%s\n", buf);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
char buf[4];
int need = snprintf(buf, sizeof buf, "%d", 12345);
if (need < 0 || (size_t)need >= sizeof buf) printf("truncated\n");
printf("%s\n", buf);
return 0;
}⚠️ 반환값을 무시하면 부분 실패·오류·절단을 감지하지 못한다. 의미 있는 반환값은 검사하거나 명시적으로 버린다.Ignoring a return value hides partial failure, errors, or truncation. Check meaningful return values or explicitly discard them.
EXP13-CEXP · Rec · SEISEI index
Treat relational and equality operators as if they were nonassociativeTreat relational and equality operators as if they were nonassociative
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP13-C * SEI official index entry: Treat relational and equality operators as if they were nonassociative * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP13-C * SEI official index entry: Treat relational and equality operators as if they were nonassociative * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP13-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP13-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP14-CEXP · Rec · SEISEI index
Beware of integer promotion when performing bitwise operations on integer types smaller than intBeware of integer promotion when performing bitwise operations on integer types smaller than int
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP14-C * SEI official index entry: Beware of integer promotion when performing bitwise operations on integer types smaller than int * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP14-C * SEI official index entry: Beware of integer promotion when performing bitwise operations on integer types smaller than int * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP14-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP14-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP15-CEXP · Rec · SEISEI index
Do not place a semicolon on the same line as an if, for, or while statementDo not place a semicolon on the same line as an if, for, or while statement
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP15-C * SEI official index entry: Do not place a semicolon on the same line as an if, for, or while statement * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP15-C * SEI official index entry: Do not place a semicolon on the same line as an if, for, or while statement * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP15-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP15-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP16-CEXP · Rec · SEISEI index
Do not compare function pointers to constant valuesDo not compare function pointers to constant values
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP16-C * SEI official index entry: Do not compare function pointers to constant values * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP16-C * SEI official index entry: Do not compare function pointers to constant values * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP16-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP16-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP19-CEXP · Rec · SEISEI index
Use braces for the body of an if, for, or while statementUse braces for the body of an if, for, or while statement
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP19-C * SEI official index entry: Use braces for the body of an if, for, or while statement * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP19-C * SEI official index entry: Use braces for the body of an if, for, or while statement * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP19-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP19-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
EXP20-CEXP · Rec · SEISEI index
Perform explicit tests to determine success, true and false, and equalityPerform explicit tests to determine success, true and false, and equality
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for EXP20-C * SEI official index entry: Perform explicit tests to determine success, true and false, and equality * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for EXP20-C * SEI official index entry: Perform explicit tests to determine success, true and false, and equality * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ EXP20-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.EXP20-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FLP부동소수Floating Point
FLP01-CEXP · Rule · SEISEI index
Take care in rearranging floating-point expressionsTake care in rearranging floating-point expressions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FLP01-C * SEI official index entry: Take care in rearranging floating-point expressions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FLP01-C * SEI official index entry: Take care in rearranging floating-point expressions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FLP01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FLP01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FLP30-CFLP · Rule · L3✓ compilableSEI index
부동소수형을 루프 카운터로 사용하지 않는다Do not use floating-point variables as loop counters
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int cnt = 0;
for (float x = 0.0f; x != 1.0f; x += 0.1f){ if (++cnt > 100) break; }
printf("%d\n", cnt); /* 오차로 1.0 정확히 안 맞음 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int cnt = 0;
for (int i = 0; i < 10; i++){ float x = (float)i / 10.0f; (void)x; cnt++; }
printf("%d\n", cnt);
return 0;
}⚠️ 부동소수 카운터는 표현 오차로 종료 조건을 정확히 만족하지 못해 무한 루프가 될 수 있다. 정수로 반복하고 실수는 파생한다.A floating-point counter may never exactly meet the termination test due to rounding, risking an infinite loop. Iterate with an integer and derive the float.
FLP32-CFLP · Rule · L2✓ compilableSEI index
수학 함수의 도메인/범위 오류를 예방하거나 검출한다Prevent or detect domain and range errors in math functions
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <math.h>
int main(void){
double x = -4.0;
double r = sqrt(x); /* x<0 → NaN */
printf("%f\n", r);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <math.h>
int main(void){
double x = -4.0;
if (x < 0.0){ printf("domain\n"); return 1; }
printf("%f\n", sqrt(x));
return 0;
}⚠️ 정의역을 벗어난 인자(예: sqrt의 음수)는 도메인 오류·NaN을 만든다. 호출 전 인자 범위를 검사하거나 오류 플래그를 확인한다.Out-of-domain arguments (e.g. negative to sqrt) cause domain errors/NaN. Check the argument range before calling, or inspect the error flags.
FLP34-CFLP · Rule · L2✓ compilableSEI index
부동소수 변환은 대상 타입 범위 안에서만 수행한다Ensure that floating-point conversions are within range of the new type
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
double d = 1e18;
int n = (int)d; /* int 범위 초과 — 미정의 */
printf("%d\n", n);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <limits.h>
int main(void){
double d = 1e18;
if (d < (double)INT_MIN || d > (double)INT_MAX){ printf("range\n"); return 1; }
printf("%d\n", (int)d);
return 0;
}⚠️ 대상 정수 타입 범위를 벗어난 부동소수를 변환하면 미정의 동작이 된다. 변환 전에 범위를 검사한다.Converting a floating-point value outside the target integer range is undefined. Check the range before converting.
FLP36-CFLP · Rule · L2✓ compilableSEI index
정수를 부동소수로 변환할 때 정밀도 손실에 주의한다Preserve precision when converting integral values to floating-point type
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
long big = 16777217L; /* 2^24 + 1 */
float f = (float)big; /* float 가수는 24비트 — 가장 가까운 값으로 반올림되어 값 변형 */
printf("%ld -> %.0f\n", big, (double)f); /* 16777217 -> 16777216 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
long big = 16777217L;
double d = (double)big; /* double 가수는 53비트 — 이 값을 정확히 표현 */
printf("%ld -> %.0f\n", big, d);
return 0;
}⚠️ 부동소수형의 가수(mantissa) 비트 수보다 큰 정수를 변환하면 정확히 표현할 수 없어 가장 가까운 표현값으로 반올림되어 값이 조용히 달라진다(float 는 약 2^24, double 은 약 2^53 초과부터). 정수 범위를 담을 수 있는 충분한 정밀도의 부동소수형을 사용한다.Converting an integer larger than the floating type’s mantissa width cannot be represented exactly and is silently rounded to the nearest value (beyond about 2^24 for float, 2^53 for double). Use a floating type with enough precision to hold the integer range.
FLP37-CFLP · Rule · L2✓ compilableSEI index
부동소수 객체의 비트 표현으로 동등성을 비교하지 않는다Do not use object representations to compare floating-point values
❌ 위반 예시Non-compliant example
#include <string.h>
#include <stdio.h>
int main(void){
double x = 0.0;
double y = -0.0; /* +0.0 와 -0.0 은 값은 같지만 비트 표현이 다름 */
if (memcmp(&x, &y, sizeof x) == 0) printf("equal\n");
else printf("differ (bit pattern)\n"); /* 값은 같은데 다르다고 판정 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
double x = 0.0;
double y = -0.0;
if (x == y) printf("equal\n"); /* 값 비교 — +0.0 == -0.0 은 참 */
else printf("differ\n");
return 0;
}⚠️ 부동소수는 +0.0/-0.0 처럼 값이 같아도 비트 표현이 다르거나, NaN 처럼 같은 비트라도 같지 않은 경우가 있어 memcmp(비트 비교)로는 수학적 동등성을 올바로 판정하지 못한다. 부동소수는 == 같은 값 비교(또는 허용 오차 비교)를 사용한다.Floating-point values can have equal values with different bit patterns (+0.0/-0.0) or equal bit patterns that are not equal (NaN), so memcmp (bitwise) cannot correctly judge mathematical equality. Compare floating-point with value comparison (==) or a tolerance comparison.
FLP03-CFLP · Rec · L2✓ compilableSEI index
부동소수 연산 오류를 검출하고 처리한다Detect and handle floating-point errors
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
double a = 1.0, b = 0.0;
double r = a / b; /* inf — 미검사로 전파 */
printf("%f\n", r);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
int main(void){
feclearexcept(FE_ALL_EXCEPT);
double a = 1.0, b = 0.0;
double r = a / b;
if (fetestexcept(FE_DIVBYZERO | FE_INVALID)){ printf("fp error\n"); return 1; }
printf("%f\n", r);
return 0;
}⚠️ 부동소수 예외(0 나눗셈·무효 연산)를 무시하면 NaN/Inf가 후속 계산에 전파된다. fenv로 예외 플래그를 확인해 처리한다.Ignoring floating-point exceptions (divide-by-zero, invalid) lets NaN/Inf propagate. Check the fenv exception flags and handle them.
FLP00-CFLP · Rec · SEISEI index
Understand the limitations of floating-point numbersUnderstand the limitations of floating-point numbers
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FLP00-C * SEI official index entry: Understand the limitations of floating-point numbers * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FLP00-C * SEI official index entry: Understand the limitations of floating-point numbers * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FLP00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FLP00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FLP02-CFLP · Rec · SEISEI index
Avoid using floating-point numbers when precise computation is neededAvoid using floating-point numbers when precise computation is needed
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FLP02-C * SEI official index entry: Avoid using floating-point numbers when precise computation is needed * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FLP02-C * SEI official index entry: Avoid using floating-point numbers when precise computation is needed * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FLP02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FLP02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FLP04-CFLP · Rec · SEISEI index
Check floating-point inputs for exceptional valuesCheck floating-point inputs for exceptional values
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FLP04-C * SEI official index entry: Check floating-point inputs for exceptional values * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FLP04-C * SEI official index entry: Check floating-point inputs for exceptional values * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FLP04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FLP04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FLP05-CFLP · Rec · SEISEI index
Do not use denormalized numbersDo not use denormalized numbers
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FLP05-C * SEI official index entry: Do not use denormalized numbers * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FLP05-C * SEI official index entry: Do not use denormalized numbers * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FLP05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FLP05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FLP06-CFLP · Rec · SEISEI index
Convert integers to floating point for floating-point operationsConvert integers to floating point for floating-point operations
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FLP06-C * SEI official index entry: Convert integers to floating point for floating-point operations * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FLP06-C * SEI official index entry: Convert integers to floating point for floating-point operations * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FLP06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FLP06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FLP07-CFLP · Rec · SEISEI index
Cast the return value of a function that returns a floating-point typeCast the return value of a function that returns a floating-point type
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FLP07-C * SEI official index entry: Cast the return value of a function that returns a floating-point type * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FLP07-C * SEI official index entry: Cast the return value of a function that returns a floating-point type * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FLP07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FLP07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ERR오류 처리Error Handling
ERR34-CERR · Rule · L3✓ compilableSEI index
문자열을 숫자로 변환할 때 오류를 검출한다Detect errors when converting a string to a number
❌ 위반 예시Non-compliant example
#include <stdlib.h>
int main(void){
int n = atoi("abc"); /* 변환 실패와 정상 0 을 구분 못함 */
return n;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <errno.h>
int main(void){
char s[] = "42";
errno = 0;
char *end;
long v = strtol(s, &end, 10);
if (end == s || *end != '\0' || errno == ERANGE) return -1;
return (int)v;
}⚠️ atoi는 변환 실패와 정상 0을 구분하지 못한다. strtol과 end 포인터·errno로 변환 성공 여부를 명확히 판정한다.atoi cannot distinguish a failed conversion from a valid 0. Use strtol with the end pointer and errno to determine success unambiguously.
ERR32-CERR · Rule · L2✓ compilableSEI index
errno 의 불확정 값에 의존하지 않는다Do not rely on indeterminate values of errno
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
int main(void){
double d = atof("abc"); /* atof 는 errno 를 설정하지 않음 */
if (errno) printf("error\n"); /* 무관한 errno 값을 봄 */
return (int)d;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
int main(void){
char s[] = "3.14";
errno = 0;
char *end;
double d = strtod(s, &end);
if (end == s || errno != 0) { printf("error\n"); return -1; }
return (int)d;
}⚠️ errno를 설정하지 않는 함수(atof 등) 뒤에 errno를 검사하면 무관한 값을 본다. errno를 설정하도록 명세된 함수와 함께 사용한다.Checking errno after a function that does not set it (e.g., atof) reads an unrelated value. Use functions specified to set errno (e.g., strtod).
ERR30-CERR · Rule · L2✓ compilableSEI index
errno 기반 함수는 호출 전 errno=0, 호출 후 검사한다Set errno to zero before, and check it after, calling errno-setting functions
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
int main(void){
long v = strtol("123", NULL, 10);
if (errno) printf("error\n"); /* 이전 errno 잔존 가능 — 오인 */
return (int)v;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
int main(void){
errno = 0;
long v = strtol("123", NULL, 10);
if (errno != 0) { printf("error\n"); return -1; }
return (int)v;
}⚠️ 호출 전에 errno를 0으로 두지 않으면 이전 오류를 현재 오류로 오인한다. 호출 직전 0으로 설정하고 직후에 검사한다.If errno is not cleared before the call, a stale error is mistaken for a current one. Set it to zero immediately before and check immediately after.
ERR33-CERR · Rule · L2✓ compilableSEI index
표준 라이브러리 함수의 오류를 검출하고 처리한다Detect and handle standard library errors
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
char buf[64];
FILE *f = fopen("/nonexistent_xyz123", "r");
fread(buf, 1, sizeof buf, f); /* fopen 실패·부분 읽기 미검사 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
char buf[64];
FILE *f = fopen("/etc/hostname", "r");
if (!f) return -1;
size_t r = fread(buf, 1, sizeof buf, f);
if (r < sizeof buf && ferror(f)) { fclose(f); return -1; }
fclose(f);
return 0;
}⚠️ 라이브러리 함수의 실패 표시(NULL·반환값·ferror)를 무시하면 잘못된 상태로 진행한다. 명세된 오류 표시를 검사해 처리한다.Ignoring a library function’s failure indication (NULL, return value, ferror) proceeds in a bad state. Check the specified error indicator and handle it.
ERR07-CEXP · Rec · SEISEI index
Prefer functions that support error checking over equivalent functions that don'tPrefer functions that support error checking over equivalent functions that don't
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ERR07-C * SEI official index entry: Prefer functions that support error checking over equivalent functions that don't * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ERR07-C * SEI official index entry: Prefer functions that support error checking over equivalent functions that don't * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ERR07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ERR07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ERR00-CERR · Rec · SEISEI index
Adopt and implement a consistent and comprehensive error-handling policyAdopt and implement a consistent and comprehensive error-handling policy
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ERR00-C * SEI official index entry: Adopt and implement a consistent and comprehensive error-handling policy * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ERR00-C * SEI official index entry: Adopt and implement a consistent and comprehensive error-handling policy * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ERR00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ERR00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ERR01-CERR · Rec · SEISEI index
Use ferror() rather than errno to check for FILE stream errorsUse ferror() rather than errno to check for FILE stream errors
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ERR01-C * SEI official index entry: Use ferror() rather than errno to check for FILE stream errors * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ERR01-C * SEI official index entry: Use ferror() rather than errno to check for FILE stream errors * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ERR01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ERR01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ERR02-CERR · Rec · SEISEI index
Avoid in-band error indicatorsAvoid in-band error indicators
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ERR02-C * SEI official index entry: Avoid in-band error indicators * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ERR02-C * SEI official index entry: Avoid in-band error indicators * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ERR02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ERR02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ERR04-CERR · Rec · SEISEI index
Choose an appropriate termination strategyChoose an appropriate termination strategy
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ERR04-C * SEI official index entry: Choose an appropriate termination strategy * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ERR04-C * SEI official index entry: Choose an appropriate termination strategy * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ERR04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ERR04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ERR05-CERR · Rec · SEISEI index
Application-independent code should provide error detection without dictating error handlingApplication-independent code should provide error detection without dictating error handling
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ERR05-C * SEI official index entry: Application-independent code should provide error detection without dictating error handling * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ERR05-C * SEI official index entry: Application-independent code should provide error detection without dictating error handling * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ERR05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ERR05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ERR06-CERR · Rec · SEISEI index
Understand the termination behavior of assert() and abort()Understand the termination behavior of assert() and abort()
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ERR06-C * SEI official index entry: Understand the termination behavior of assert() and abort() * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ERR06-C * SEI official index entry: Understand the termination behavior of assert() and abort() * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ERR06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ERR06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT정수Integers
INT30-CINT · Rule · L2✓ compilableSEI index
부호 없는 정수 연산이 래핑되지 않도록 보장한다Ensure that unsigned integer operations do not wrap
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <limits.h>
int main(void){
unsigned a = UINT_MAX, b = 2;
unsigned s = a + b; /* 래핑 */
printf("%u\n", s);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <limits.h>
int main(void){
unsigned a = UINT_MAX, b = 2;
if (a > UINT_MAX - b){ printf("overflow\n"); return 1; }
printf("%u\n", a + b);
return 0;
}⚠️ 부호 없는 덧셈은 오버플로우 시 조용히 모듈로 래핑되어 길이·인덱스 계산을 망가뜨린다. 연산 전에 래핑 조건을 검사한다.Unsigned addition silently wraps modulo on overflow, corrupting size/index math. Check the wrap condition before the operation.
INT31-CINT · Rule · L2✓ compilableSEI index
정수 변환이 데이터를 잃거나 잘못 해석하지 않도록 한다Ensure that integer conversions do not lose or misinterpret data
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
long big = 300;
unsigned char b = (unsigned char)big; /* 300 → 44 절단 */
printf("%u\n", b);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
long big = 300;
if (big < 0 || big > 255){ printf("range\n"); return 1; }
unsigned char b = (unsigned char)big;
printf("%u\n", b);
return 0;
}⚠️ 넓은 정수를 좁은 타입으로 변환하면 값이 잘리거나 부호가 뒤바뀐다. 변환 전에 대상 타입 범위를 검사한다.Converting a wide integer to a narrow type truncates or flips sign. Check the target type range before converting.
INT32-CINT · Rule · L2✓ compilableSEI index
부호 있는 정수 연산이 오버플로우되지 않도록 보장한다Ensure that signed integer operations do not result in overflow
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <limits.h>
int main(void){
int a = INT_MAX, b = 2;
int p = a * b; /* signed 오버플로우 — 미정의 */
printf("%d\n", p);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <limits.h>
int main(void){
int a = INT_MAX, b = 2;
if (a != 0 && (b > INT_MAX / a || b < INT_MIN / a)){ printf("overflow\n"); return 1; }
printf("%d\n", a * b);
return 0;
}⚠️ 부호 있는 정수 오버플로우는 미정의 동작이다. 곱셈·덧셈 전에 피연산자로 한계를 나눠 오버플로우 가능성을 검사한다.Signed integer overflow is undefined behavior. Before multiplying/adding, divide the limits by an operand to test for overflow.
INT33-CINT · Rule · L2✓ compilableSEI index
나눗셈/나머지 연산에서 0으로 나누지 않는다Ensure that division and remainder operations do not result in divide-by-zero
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int total = 10, count = 0;
int q = total / count; /* 0 나눗셈 */
printf("%d\n", q);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int total = 10, count = 0;
if (count == 0){ printf("div by zero\n"); return 1; }
printf("%d\n", total / count);
return 0;
}⚠️ 0으로 나누거나 나머지를 구하면 미정의 동작(대개 크래시)이 된다. 나누기 전에 분모가 0이 아님을 확인한다.Dividing or taking remainder by zero is undefined (usually a crash). Verify the divisor is nonzero first.
INT34-CINT · Rule · L2✓ compilableSEI index
음수나 비트폭 이상으로 시프트하지 않는다Do not shift by a negative count or a count greater than or equal to the width
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
unsigned v = 1u;
int n = 40;
unsigned r = v << n; /* 32비트를 40 시프트 — 미정의 */
printf("%u\n", r);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <limits.h>
int main(void){
unsigned v = 1u;
int n = 40;
if (n < 0 || n >= (int)(sizeof(unsigned) * CHAR_BIT)){ printf("bad shift\n"); return 1; }
printf("%u\n", v << n);
return 0;
}⚠️ 시프트량이 음수이거나 피연산자 비트폭 이상이면 결과가 미정의다. 시프트 전에 0..(폭-1) 범위를 보장한다.A shift count that is negative or >= the operand width is undefined. Ensure the count is within 0..(width-1) before shifting.
INT35-CINT · Rule · L1✓ compilableSEI index
정수 정밀도(precision)를 올바르게 사용한다Use correct integer precisions
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
unsigned bits = sizeof(unsigned) * 8; /* CHAR_BIT==8 가정 */
printf("%u\n", bits);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <limits.h>
int main(void){
unsigned bits = sizeof(unsigned) * CHAR_BIT;
printf("%u\n", bits);
return 0;
}⚠️ 바이트가 항상 8비트라고 가정하면 비표준 플랫폼에서 정밀도 계산이 틀어진다. CHAR_BIT로 실제 비트 수를 구한다.Assuming a byte is always 8 bits breaks precision math on unusual platforms. Use CHAR_BIT for the real bit count.
INT36-CINT · Rule · L1✓ compilableSEI index
포인터와 정수를 변환할 때 주의한다Converting a pointer to integer or integer to pointer
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int x = 0;
void *ptr = &x;
unsigned int n = (unsigned int)(unsigned long)ptr; /* 포인터가 더 넓으면 상위 비트 절단 */
void *back = (void *)(unsigned long)n; /* 복원 시 잘못된 주소가 될 수 있음 */
printf("%p\n", back);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdint.h>
int main(void){
int x = 0;
void *ptr = &x;
uintptr_t n = (uintptr_t)ptr; /* 포인터를 온전히 담는 타입 */
void *back = (void *)n; /* 정확히 복원 */
printf("%d\n", back == ptr);
return 0;
}⚠️ 포인터를 그것보다 좁은 정수형으로 변환하면 상위 비트가 잘려, 다시 포인터로 복원할 때 원래와 다른 주소가 되어 잘못된 메모리 접근으로 이어진다. 포인터↔정수 변환이 불가피하면 포인터를 온전히 담도록 정의된 uintptr_t/intptr_t 를 사용한다.Converting a pointer to an integer narrower than it truncates the high bits, so restoring it to a pointer yields a different address and wrong memory access. When pointer/integer conversion is unavoidable, use uintptr_t/intptr_t, defined to hold a pointer in full.
INT07-CSTR · Rule · SEISEI index
Use only explicitly signed or unsigned char type for numeric valuesUse only explicitly signed or unsigned char type for numeric values
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT07-C * SEI official index entry: Use only explicitly signed or unsigned char type for numeric values * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT07-C * SEI official index entry: Use only explicitly signed or unsigned char type for numeric values * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT01-CMEM · Rule · SEISEI index
Use size_t for all integer values representing the size of an objectUse size_t for all integer values representing the size of an object
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT01-C * SEI official index entry: Use size_t for all integer values representing the size of an object * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT01-C * SEI official index entry: Use size_t for all integer values representing the size of an object * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT00-CINT · Rec · SEISEI index
Understand the data model used by your implementation(s)Understand the data model used by your implementation(s)
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT00-C * SEI official index entry: Understand the data model used by your implementation(s) * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT00-C * SEI official index entry: Understand the data model used by your implementation(s) * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT04-CINT · Rec · SEISEI index
Enforce limits on integer values originating from tainted sourcesEnforce limits on integer values originating from tainted sources
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT04-C * SEI official index entry: Enforce limits on integer values originating from tainted sources * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT04-C * SEI official index entry: Enforce limits on integer values originating from tainted sources * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT05-CINT · Rec · SEISEI index
Do not use input functions to convert character data if they cannot handle all possible inputsDo not use input functions to convert character data if they cannot handle all possible inputs
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT05-C * SEI official index entry: Do not use input functions to convert character data if they cannot handle all possible inputs * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT05-C * SEI official index entry: Do not use input functions to convert character data if they cannot handle all possible inputs * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT08-CINT · Rec · SEISEI index
Verify that all integer values are in rangeVerify that all integer values are in range
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT08-C * SEI official index entry: Verify that all integer values are in range * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT08-C * SEI official index entry: Verify that all integer values are in range * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT08-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT08-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT09-CINT · Rec · SEISEI index
Ensure enumeration constants map to unique valuesEnsure enumeration constants map to unique values
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT09-C * SEI official index entry: Ensure enumeration constants map to unique values * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT09-C * SEI official index entry: Ensure enumeration constants map to unique values * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT10-CINT · Rec · SEISEI index
Do not assume a positive remainder when using the % operatorDo not assume a positive remainder when using the % operator
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT10-C * SEI official index entry: Do not assume a positive remainder when using the % operator * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT10-C * SEI official index entry: Do not assume a positive remainder when using the % operator * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT10-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT10-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT12-CINT · Rec · SEISEI index
Do not make assumptions about the type of a plain int bit-field when used in an expressionDo not make assumptions about the type of a plain int bit-field when used in an expression
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT12-C * SEI official index entry: Do not make assumptions about the type of a plain int bit-field when used in an expression * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT12-C * SEI official index entry: Do not make assumptions about the type of a plain int bit-field when used in an expression * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT12-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT12-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT13-CINT · Rec · SEISEI index
Use bitwise operators only on unsigned operandsUse bitwise operators only on unsigned operands
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT13-C * SEI official index entry: Use bitwise operators only on unsigned operands * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT13-C * SEI official index entry: Use bitwise operators only on unsigned operands * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT13-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT13-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT14-CINT · Rec · SEISEI index
Avoid performing bitwise and arithmetic operations on the same dataAvoid performing bitwise and arithmetic operations on the same data
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT14-C * SEI official index entry: Avoid performing bitwise and arithmetic operations on the same data * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT14-C * SEI official index entry: Avoid performing bitwise and arithmetic operations on the same data * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT14-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT14-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT15-CINT · Rec · SEISEI index
Use intmax_t or uintmax_t for formatted IO on programmer-defined integer typesUse intmax_t or uintmax_t for formatted IO on programmer-defined integer types
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT15-C * SEI official index entry: Use intmax_t or uintmax_t for formatted IO on programmer-defined integer types * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT15-C * SEI official index entry: Use intmax_t or uintmax_t for formatted IO on programmer-defined integer types * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT15-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT15-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT16-CINT · Rec · SEISEI index
Do not make assumptions about representation of signed integersDo not make assumptions about representation of signed integers
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT16-C * SEI official index entry: Do not make assumptions about representation of signed integers * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT16-C * SEI official index entry: Do not make assumptions about representation of signed integers * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT16-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT16-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT17-CINT · Rec · SEISEI index
Define integer constants in an implementation-independent mannerDefine integer constants in an implementation-independent manner
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT17-C * SEI official index entry: Define integer constants in an implementation-independent manner * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT17-C * SEI official index entry: Define integer constants in an implementation-independent manner * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT17-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT17-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
INT18-CINT · Rec · L3✓ compilableSEI index
정수 표현식은 충분히 큰 타입에서 평가한다Evaluate integer expressions in a larger size
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <stdint.h>
int main(void){
uint16_t a = 60000, b = 10000;
uint32_t s = a + b; /* 16비트로 계산 후 확장? (승격 덕에 안전하나 의도 명확화) */
uint16_t bad = (uint16_t)(a + b); /* 좁은 폭으로 절단 */
printf("%u %u\n", s, bad);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdint.h>
int main(void){
uint16_t a = 60000, b = 10000;
uint32_t s = (uint32_t)a + b; /* 32비트로 평가 */
printf("%u\n", s);
return 0;
}⚠️ 좁은 타입끼리 계산 후 좁은 타입에 담으면 오버플로우가 숨는다. 평가 전에 충분히 큰 타입으로 승격한다.Computing in a narrow type and storing back narrowly hides overflow. Promote to a sufficiently large type before evaluating.
INT02-CINT · Rec · SEISEI index
Understand integer conversion rulesUnderstand integer conversion rules
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for INT02-C * SEI official index entry: Understand integer conversion rules * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for INT02-C * SEI official index entry: Understand integer conversion rules * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ INT02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.INT02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO입출력Input/Output
FIO09-CINT · Rule · SEISEI index
Be careful with binary data when transferring data across systemsBe careful with binary data when transferring data across systems
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO09-C * SEI official index entry: Be careful with binary data when transferring data across systems * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO09-C * SEI official index entry: Be careful with binary data when transferring data across systems * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO47-CFIO · Rule · L1✓ compilableSEI index
유효한 포맷 문자열을 사용한다(인자와 변환 지정자 일치)Use valid format strings
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
long v = 10;
printf("%d\n", v); /* %d 에 long — 불일치 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
long v = 10;
printf("%ld\n", v);
return 0;
}⚠️ 변환 지정자와 인자 타입이 어긋나면 잘못된 크기로 읽어 미정의 동작·정보 유출이 된다. 지정자와 인자 타입을 정확히 맞춘다.A conversion specifier mismatched to the argument type reads the wrong size and is undefined. Match specifiers to argument types exactly.
FIO20-CSTR · Rule · SEISEI index
Avoid unintentional truncation when using fgets() or fgetws()Avoid unintentional truncation when using fgets() or fgetws()
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO20-C * SEI official index entry: Avoid unintentional truncation when using fgets() or fgetws() * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO20-C * SEI official index entry: Avoid unintentional truncation when using fgets() or fgetws() * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO20-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO20-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO30-CFIO · Rule · L1✓ compilableSEI index
사용자 입력을 포맷 문자열에 직접 사용하지 않는다Exclude user input from format strings
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
const char *user = "%x %x %n";
printf(user); /* 포맷 문자열 인젝션 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
const char *user = "%x %x %n";
printf("%s", user); /* 입력은 인자로 */
return 0;
}⚠️ 사용자 입력을 포맷 문자열로 쓰면 %n/%s 등으로 메모리 읽기·쓰기 공격이 가능하다. 항상 고정 포맷("%s")에 인자로 전달한다.Using user input as a format string enables memory read/write attacks via %n/%s. Always pass it as an argument to a fixed "%s" format.
FIO40-CFIO · Rule · L3✓ compilableSEI index
fgets/fgetws 실패 시 대상 문자열을 재설정한다Reset strings on fgets() or fgetws() failure
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
char buf[64];
FILE *f = fopen("/nonexistent_xyz123", "r");
if (fgets(buf, sizeof buf, f ? f : stdin) == NULL) {
printf("[%s]\n", buf); /* 실패 후 buf 는 불확정 — 그대로 사용하면 오동작 */
}
if (f) fclose(f);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
char buf[64] = "";
FILE *f = fopen("/nonexistent_xyz123", "r");
if (f == NULL || fgets(buf, sizeof buf, f) == NULL) {
buf[0] = '\0'; /* 실패 시 빈 문자열로 재설정 */
printf("read failed\n");
} else {
printf("[%s]\n", buf);
}
if (f) fclose(f);
return 0;
}⚠️ fgets 가 실패(오류·EOF)를 NULL 로 알릴 때 대상 버퍼의 내용은 불확정이므로, 그대로 출력·파싱하면 이전 데이터나 쓰레기 값을 처리하게 된다. 실패 시 버퍼를 빈 문자열로 재설정한 뒤 오류 경로를 처리한다.When fgets reports failure (error or EOF) by returning NULL, the destination buffer contents are indeterminate, so using them directly processes stale or garbage data. Reset the buffer to an empty string on failure and then handle the error path.
FIO32-CFIO · Rule · L2✓ compilableSEI index
장치 특수 파일(device file)에 일반 파일 연산을 가정하지 않는다Do not perform operations on devices that are only appropriate for files
❌ 위반 예시Non-compliant example
#define _GNU_SOURCE
#include <stdio.h>
static void read_all(FILE *f){ char b[16]; (void)fread(b, 1, sizeof b, f); }
int main(void){
const char *user_path = "/dev/zero"; /* 사용자 입력이 장치 파일일 수 있음 */
FILE *f = fopen(user_path, "r");
if (f) { read_all(f); fclose(f); } /* 일반 파일 가정 — 블로킹/무한 입력 위험 */
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/stat.h>
int main(void){
const char *path = "/etc/hostname";
struct stat st;
if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) { /* 일반 파일인지 확인 후 열기 */
FILE *f = fopen(path, "r");
if (f) fclose(f);
}
return 0;
}⚠️ 사용자가 준 경로가 /dev/* 같은 장치 특수 파일을 가리키면, 일반 파일이라는 가정으로 읽기·시킹을 하다가 무한 블로킹이나 예기치 않은 동작(DoS)에 빠질 수 있다. 열기 전에 stat 으로 일반 파일(S_ISREG)인지 확인한다.If a user-supplied path points to a device special file like /dev/*, assuming it is a regular file and reading/seeking it can cause indefinite blocking or unexpected behaviour (DoS). Check with stat that it is a regular file (S_ISREG) before opening.
FIO34-CFIO · Rule · L1✓ compilableSEI index
입력 문자와 EOF/WEOF 를 구분한다Distinguish between characters read and EOF or WEOF
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
char c; /* char로 받으면 EOF 구분 실패 */
int count = 0;
while ((c = getchar()) != EOF){ if (++count > 3) break; }
printf("%d\n", count);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int c;
int count = 0;
while ((c = getchar()) != EOF){ if (++count > 3) break; }
printf("%d\n", count);
return 0;
}⚠️ getchar 반환을 char에 담으면 0xFF 문자와 EOF가 구분되지 않아 루프가 잘못 종료·무한 반복한다. 반환값은 int로 받는다.Storing getchar in a char conflates byte 0xFF with EOF, breaking the loop. Capture the return value as int.
FIO37-CFIO · Rule · L2✓ compilableSEI index
fgets 성공 시 비어있지 않은 결과를 가정하지 않는다Do not assume that fgets() returns a nonempty string on success
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <string.h>
int main(void){
char line[16] = "";
if (fgets(line, sizeof line, stdin)){
line[strlen(line) - 1] = '\0'; /* 빈 줄이면 인덱스 -1 */
}
printf("[%s]\n", line);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <string.h>
int main(void){
char line[16] = "";
if (fgets(line, sizeof line, stdin)){
size_t n = strlen(line);
if (n > 0 && line[n-1] == '\n') line[n-1] = '\0';
}
printf("[%s]\n", line);
return 0;
}⚠️ 성공한 fgets라도 내용이 비어 있을 수 있어 strlen-1 같은 접근이 경계를 벗어난다. 길이를 확인하고 안전하게 인덱싱한다.Even a successful fgets may yield an empty string, so strlen-1 indexing underflows. Check the length and index safely.
FIO38-CFIO · Rule · L1✓ compilableSEI index
FILE 객체를 복사하지 않는다Do not copy a FILE object
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
FILE f2 = *stdin; /* FILE 객체를 값으로 복사 — 내부 상태가 어긋나 미정의 동작 */
char buf[8];
(void)fread(buf, 1, sizeof buf, &f2);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *f = stdin; /* 항상 FILE 포인터로만 다룸 */
char buf[8];
(void)fread(buf, 1, sizeof buf, f);
return 0;
}⚠️ FILE 객체는 버퍼 포인터·위치·오류 플래그 등 내부 상태를 담고 구현이 그 주소를 추적하므로, 값으로 복사하면 복사본과 원본의 상태가 어긋나 미정의 동작이 된다. 스트림은 언제나 FILE 포인터로만 참조·전달한다.A FILE object holds internal state (buffer pointers, position, error flags) and the implementation tracks its address, so copying it by value desynchronizes the copy and the original — undefined behaviour. Always reference and pass streams only through a FILE pointer.
FIO39-CFIO · Rule · L1✓ compilableSEI index
위치 지정 없이 입력과 출력을 번갈아 하지 않는다Do not alternately input and output from a stream without an intervening flush or positioning call
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
FILE *f = tmpfile();
if (!f) return 1;
fprintf(f, "42 ");
int x = 0;
fscanf(f, "%d", &x); /* 출력→입력 전환 사이에 위치 지정/flush 없음 — 미정의 동작 */
fclose(f);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *f = tmpfile();
if (!f) return 1;
fprintf(f, "42 ");
fflush(f);
fseek(f, 0, SEEK_SET); /* 전환 사이에 위치 지정으로 버퍼 상태 정리 */
int x = 0;
fscanf(f, "%d", &x);
fclose(f);
return 0;
}⚠️ 갱신(읽기/쓰기 겸용) 모드 스트림에서 fflush 나 fseek/fsetpos 같은 위치 지정 없이 출력 직후 입력으로(또는 그 반대로) 전환하면, 내부 버퍼 상태가 정의되지 않아 미정의 동작이 된다. 입출력 전환 사이에 flush 나 위치 지정 호출을 둔다.On an update-mode (read/write) stream, switching from output to input (or vice versa) without an intervening fflush or positioning call (fseek/fsetpos) leaves the internal buffer state undefined — undefined behaviour. Place a flush or positioning call between input and output.
FIO41-CFIO · Rule · L1✓ compilableSEI index
부작용이 있는 표현식을 getc/putc 등의 스트림 인자로 넘기지 않는다Do not call getc(), putc(), getwc(), or putwc() with a stream argument that has side effects
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
FILE *files[2] = { stdin, stdin };
int i = 0;
int c = getc(files[i++]); /* getc 가 매크로면 스트림 인자(i++)를 여러 번 평가 */
printf("i=%d\n", i); /* i 가 의도보다 더 증가할 수 있음 */
(void)c;
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *files[2] = { stdin, stdin };
int i = 0;
FILE *f = files[i++]; /* 부작용을 먼저 분리해 변수에 담음 */
int c = getc(f);
printf("i=%d\n", i);
(void)c;
return 0;
}⚠️ getc/putc 는 성능을 위해 매크로로 구현될 수 있고, 그 경우 스트림 인자를 본문에서 여러 번 평가하므로 i++ 같은 부작용이 의도보다 여러 번 일어난다. 부작용 있는 표현식은 먼저 변수에 담아 그 변수를 인자로 전달한다.getc/putc may be implemented as macros for speed, in which case the stream argument is evaluated multiple times in the body, so a side effect like i++ happens more times than intended. Evaluate the side-effecting expression into a variable first and pass that variable.
FIO42-CFIO · Rule · L2✓ compilableSEI index
더 이상 필요 없는 파일은 닫는다Close files when they are no longer needed
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
FILE *f = fopen("/tmp/x.txt", "w");
if (f){ fputs("hi", f); } /* fclose 누락 — 핸들 누수 */
printf("done\n");
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *f = fopen("/tmp/x.txt", "w");
if (!f) return 1;
fputs("hi", f);
fclose(f);
printf("done\n");
return 0;
}⚠️ 열린 파일을 닫지 않으면 디스크립터 누수로 결국 자원이 고갈된다. 사용이 끝나면 모든 경로에서 fclose한다.Not closing files leaks descriptors until resources are exhausted. fclose on every path once you are done.
FIO44-CFIO · Rule · L2✓ compilableSEI index
fsetpos 에는 fgetpos 가 반환한 값만 사용한다Only use values for fsetpos() that are returned from fgetpos()
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <string.h>
int main(void){
FILE *f = tmpfile();
if (!f) return 1;
fprintf(f, "hello");
fpos_t pos;
memset(&pos, 0, sizeof pos); /* fgetpos 가 만든 값이 아닌 임의 값 */
fsetpos(f, &pos); /* 임의 fpos_t 사용 — 미정의 동작 */
fclose(f);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *f = tmpfile();
if (!f) return 1;
fpos_t pos;
fgetpos(f, &pos); /* 같은 스트림에서 위치를 얻고 */
fprintf(f, "hello");
fsetpos(f, &pos); /* 그 값으로만 복원 */
fclose(f);
return 0;
}⚠️ fpos_t 는 구현 정의 불투명 타입이라 fgetpos 로 얻은 값만 의미가 있는데, 임의로 만든 값을 fsetpos 에 넘기면 정의되지 않은 위치로 해석되어 미정의 동작이 된다. 같은 스트림에서 fgetpos 로 얻은 위치 값만 fsetpos 에 사용한다.fpos_t is an implementation-defined opaque type whose values are meaningful only when produced by fgetpos, so passing a hand-crafted value to fsetpos is interpreted as an undefined position — undefined behaviour. Use only position values obtained from fgetpos on the same stream.
FIO45-CFIO · Rule · L3✓ compilableSEI index
파일 접근에서 TOCTOU 경쟁 조건을 피한다Avoid TOCTOU race conditions while accessing files
❌ 위반 예시Non-compliant example
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(void){
const char *p = "/tmp/x.txt";
if (access(p, W_OK) == 0){ /* 검사 */
int fd = open(p, O_WRONLY); /* 사용 — 사이에 교체 가능 */
if (fd >= 0) close(fd);
}
printf("done\n");
return 0;
}✅ 준수 예시Compliant example
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(void){
const char *p = "/tmp/x.txt";
int fd = open(p, O_WRONLY | O_CREAT | O_EXCL, 0600); /* 검사+사용 원자화 */
if (fd >= 0) close(fd);
printf("done\n");
return 0;
}⚠️ access 후 open 사이에 파일이 심볼릭 링크 등으로 교체되면 권한 우회가 일어난다(TOCTOU). 검사-사용을 원자적 open 플래그로 결합한다.Between access and open the file can be swapped (e.g. a symlink), bypassing checks (TOCTOU). Combine check and use with atomic open flags.
FIO46-CFIO · Rule · L2✓ compilableSEI index
닫힌 파일에 접근하지 않는다Do not access a closed file
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
FILE *f = tmpfile();
if (!f) return 1;
fclose(f);
fprintf(f, "x"); /* 닫은 뒤 사용 — 미정의 동작 */
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
FILE *f = tmpfile();
if (!f) return 1;
fprintf(f, "x"); /* 닫기 전에 모든 사용을 완료 */
fclose(f);
f = NULL; /* 닫은 뒤 포인터를 무효화 */
return 0;
}⚠️ fclose 이후의 FILE 포인터는 더 이상 유효한 스트림을 가리키지 않으므로, 그 포인터로 입출력을 하면 해제된 자원에 접근하는 미정의 동작이 된다. 모든 사용을 닫기 전에 끝내고, 닫은 뒤에는 포인터를 NULL 로 무효화해 재사용을 차단한다.After fclose, a FILE pointer no longer refers to a valid stream, so doing I/O through it accesses a released resource — undefined behaviour. Complete all use before closing and null out the pointer afterward to prevent reuse.
FIO01-CFIO · Rule · SEISEI index
Be careful using functions that use file names for identificationBe careful using functions that use file names for identification
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO01-C * SEI official index entry: Be careful using functions that use file names for identification * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO01-C * SEI official index entry: Be careful using functions that use file names for identification * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO02-CFIO · Rec · L2✓ compilableSEI index
경로 이름을 정규화(canonicalize)한 뒤 사용한다Canonicalize path names originating from tainted sources
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <string.h>
int main(void){
const char *user = "../etc/passwd";
char path[256];
snprintf(path, sizeof path, "/data/%s", user); /* ../ 경로 이탈 */
printf("%s\n", path);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
const char *user = "report.txt";
char joined[256], resolved[4096];
snprintf(joined, sizeof joined, "/data/%s", user);
if (realpath(joined, resolved) && strncmp(resolved, "/data/", 6) == 0){
printf("%s\n", resolved);
} else {
printf("rejected\n");
}
return 0;
}⚠️ 정규화하지 않은 경로는 ../ 를 통한 디렉터리 이탈에 악용된다. realpath로 정규화하고 허용된 기준 디렉터리 내인지 확인한다.Un-canonicalized paths are exploited for directory traversal via ../. Canonicalize with realpath and verify the result stays under the allowed base.
FIO03-CFIO · Rule · SEISEI index
Do not make assumptions about fopen() and file creationDo not make assumptions about fopen() and file creation
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO03-C * SEI official index entry: Do not make assumptions about fopen() and file creation * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO03-C * SEI official index entry: Do not make assumptions about fopen() and file creation * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO03-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO03-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO05-CFIO · Rule · SEISEI index
Identify files using multiple file attributesIdentify files using multiple file attributes
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO05-C * SEI official index entry: Identify files using multiple file attributes * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO05-C * SEI official index entry: Identify files using multiple file attributes * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO06-CFIO · Rule · SEISEI index
Create files with appropriate access permissionsCreate files with appropriate access permissions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO06-C * SEI official index entry: Create files with appropriate access permissions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO06-C * SEI official index entry: Create files with appropriate access permissions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO08-CFIO · Rule · SEISEI index
Take care when calling remove() on an open fileTake care when calling remove() on an open file
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO08-C * SEI official index entry: Take care when calling remove() on an open file * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO08-C * SEI official index entry: Take care when calling remove() on an open file * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO08-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO08-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO10-CFIO · Rule · SEISEI index
Take care when using the rename() functionTake care when using the rename() function
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO10-C * SEI official index entry: Take care when using the rename() function * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO10-C * SEI official index entry: Take care when using the rename() function * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO10-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO10-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO11-CFIO · Rule · SEISEI index
Take care when specifying the mode parameter of fopen()Take care when specifying the mode parameter of fopen()
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO11-C * SEI official index entry: Take care when specifying the mode parameter of fopen() * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO11-C * SEI official index entry: Take care when specifying the mode parameter of fopen() * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO11-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO11-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO13-CFIO · Rule · SEISEI index
Never push back anything other than one read characterNever push back anything other than one read character
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO13-C * SEI official index entry: Never push back anything other than one read character * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO13-C * SEI official index entry: Never push back anything other than one read character * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO13-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO13-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO14-CFIO · Rule · SEISEI index
Understand the difference between text mode and binary mode with file streamsUnderstand the difference between text mode and binary mode with file streams
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO14-C * SEI official index entry: Understand the difference between text mode and binary mode with file streams * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO14-C * SEI official index entry: Understand the difference between text mode and binary mode with file streams * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO14-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO14-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO15-CFIO · Rule · SEISEI index
Ensure that file operations are performed in a secure directoryEnsure that file operations are performed in a secure directory
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO15-C * SEI official index entry: Ensure that file operations are performed in a secure directory * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO15-C * SEI official index entry: Ensure that file operations are performed in a secure directory * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO15-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO15-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO17-CFIO · Rule · SEISEI index
Do not rely on an ending null character when using fread()Do not rely on an ending null character when using fread()
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO17-C * SEI official index entry: Do not rely on an ending null character when using fread() * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO17-C * SEI official index entry: Do not rely on an ending null character when using fread() * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO17-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO17-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO18-CFIO · Rule · SEISEI index
Never expect fwrite() to terminate the writing process at a null characterNever expect fwrite() to terminate the writing process at a null character
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO18-C * SEI official index entry: Never expect fwrite() to terminate the writing process at a null character * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO18-C * SEI official index entry: Never expect fwrite() to terminate the writing process at a null character * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO18-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO18-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO19-CFIO · Rule · SEISEI index
Do not use fseek() and ftell() to compute the size of a regular fileDo not use fseek() and ftell() to compute the size of a regular file
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO19-C * SEI official index entry: Do not use fseek() and ftell() to compute the size of a regular file * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO19-C * SEI official index entry: Do not use fseek() and ftell() to compute the size of a regular file * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO19-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO19-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO21-CFIO · Rule · SEISEI index
Do not create temporary files in shared directoriesDo not create temporary files in shared directories
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO21-C * SEI official index entry: Do not create temporary files in shared directories * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO21-C * SEI official index entry: Do not create temporary files in shared directories * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO21-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO21-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO22-CFIO · Rule · SEISEI index
Close files before spawning processesClose files before spawning processes
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO22-C * SEI official index entry: Close files before spawning processes * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO22-C * SEI official index entry: Close files before spawning processes * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO22-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO22-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO23-CFIO · Rule · SEISEI index
Do not exit with unflushed data in stdout or stderrDo not exit with unflushed data in stdout or stderr
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO23-C * SEI official index entry: Do not exit with unflushed data in stdout or stderr * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO23-C * SEI official index entry: Do not exit with unflushed data in stdout or stderr * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO23-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO23-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
FIO24-CFIO · Rule · SEISEI index
Do not open a file that is already openDo not open a file that is already open
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for FIO24-C * SEI official index entry: Do not open a file that is already open * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for FIO24-C * SEI official index entry: Do not open a file that is already open * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ FIO24-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.FIO24-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ARR배열Arrays
ARR30-CARR · Rule · L1✓ compilableSEI index
배열 범위를 벗어난 포인터/첨자를 만들거나 사용하지 않는다Do not form or use out-of-bounds pointers or array subscripts
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int a[10] = {0};
int i = 12; /* 외부 입력 가정 */
a[i] = 1; /* 범위 밖 쓰기 */
printf("%d\n", a[0]);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int a[10] = {0};
int i = 12;
if (i >= 0 && i < 10) a[i] = 1;
printf("%d\n", a[0]);
return 0;
}⚠️ 범위를 벗어난 배열 접근은 메모리 손상·정보 유출을 일으킨다. 인덱스를 0..size-1로 검증한 뒤 접근한다.Out-of-bounds array access corrupts memory or leaks data. Validate the index against 0..size-1 before access.
ARR32-CARR · Rule · L1✓ compilableSEI index
가변 길이 배열(VLA) 크기 인자가 유효 범위인지 보장한다Ensure size arguments for variable-length arrays are in a valid range
❌ 위반 예시Non-compliant example
#include <stdio.h>
static void f(int n){
int buf[n]; /* n이 음수/과대면 미정의·스택 폭주 */
buf[0] = n;
printf("%d\n", buf[0]);
}
int main(void){ f(8); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
static void f(int n){
if (n <= 0 || n > 1024) return;
int buf[n];
buf[0] = n;
printf("%d\n", buf[0]);
}
int main(void){ f(8); return 0; }⚠️ VLA 크기가 음수이거나 지나치게 크면 미정의 동작이나 스택 고갈이 발생한다. 크기를 양수·상한 이내로 검증한다.A VLA size that is negative or excessively large causes undefined behavior or stack exhaustion. Validate it as positive and bounded.
ARR36-CARR · Rule · L2✓ compilableSEI index
관련 없는 포인터를 빼거나 비교하지 않는다Do not subtract or compare two pointers that do not refer to the same array
❌ 위반 예시Non-compliant example
#include <stdio.h>
#include <stddef.h>
int main(void){
int x[4], y[4];
ptrdiff_t d = &x[3] - &y[0]; /* 다른 배열 — 미정의 */
printf("%td\n", d);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <stddef.h>
int main(void){
int x[4];
ptrdiff_t d = &x[3] - &x[0]; /* 같은 배열 내 */
printf("%td\n", d);
return 0;
}⚠️ 서로 다른 배열에 속한 포인터의 뺄셈/비교 결과는 미정의다. 같은 배열의 원소들 사이에서만 연산한다.Subtracting or comparing pointers into different arrays is undefined. Operate only between elements of the same array.
ARR37-CARR · Rule · L1✓ compilableSEI index
배열이 아닌 객체를 가리키는 포인터에 정수를 더하거나 빼지 않는다Do not add or subtract an integer to a pointer to a non-array object
❌ 위반 예시Non-compliant example
#include <stdio.h>
struct P { int x; int y; };
int main(void){
struct P p = { 1, 2 };
int *q = &p.x + 1; /* 단일 멤버를 1-원소 배열처럼 취급 — 그 객체 범위를 벗어남(미정의) */
printf("%d\n", *q);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
struct P { int x; int y; };
int main(void){
struct P p = { 1, 2 };
int *q = &p.y; /* 의도한 멤버의 주소를 직접 사용 */
printf("%d\n", *q);
return 0;
}⚠️ 포인터 산술은 배열 안에서만 정의되므로, 단일(비배열) 객체나 구조체 멤버의 주소에 +1 을 하면 그 객체의 범위를 벗어나 미정의 동작이 된다(멤버 사이의 패딩·재배치 가정도 깨진다). 다른 멤버가 필요하면 그 멤버의 주소를 직접 취한다.Pointer arithmetic is defined only within an array, so adding 1 to the address of a single (non-array) object or struct member goes outside that object — undefined behaviour (and assumes member layout/padding that is not guaranteed). Take the address of the desired member directly instead.
ARR38-CARR · Rule · L1✓ compilableSEI index
라이브러리 함수가 무효한 포인터를 만들지 않도록 인자를 보장한다Guarantee that library functions do not form invalid pointers
❌ 위반 예시Non-compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char d[8];
size_t len = 16;
memcpy(d, "0123456789abcdef", len); /* d 경계 초과 */
printf("%c\n", d[0]);
return 0;
}✅ 준수 예시Compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char d[8];
size_t len = 16;
if (len <= sizeof d){ memcpy(d, "01234567", len); }
printf("ok\n");
return 0;
}⚠️ 길이 인자가 버퍼 크기를 초과하면 memcpy 등이 경계를 넘는 무효 포인터로 쓴다. 호출 전에 길이가 버퍼 범위 내인지 확인한다.A length argument exceeding the buffer makes memcpy write through an out-of-bounds pointer. Check the length against the buffer size first.
ARR39-CARR · Rule · L1✓ compilableSEI index
스케일된 정수를 포인터에 더하거나 빼지 않는다Do not add or subtract a scaled integer to a pointer
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int a[4] = {0,1,2,3};
int *p = a;
p = (int *)((char *)p + 2 * sizeof(int)); /* 수동 스케일 — 오류 유발 */
printf("%d\n", *p);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int a[4] = {0,1,2,3};
int *p = a;
p = p + 2; /* 요소 단위 산술 */
printf("%d\n", *p);
return 0;
}⚠️ 바이트 단위로 직접 스케일한 포인터 산술은 이중 스케일·정렬 오류를 부른다. 요소 타입 단위의 포인터 산술을 사용한다.Manually byte-scaling a pointer invites double-scaling and misalignment. Use element-typed pointer arithmetic.
ARR00-CARR · Rec · SEISEI index
Understand how arrays workUnderstand how arrays work
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ARR00-C * SEI official index entry: Understand how arrays work * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ARR00-C * SEI official index entry: Understand how arrays work * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ARR00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ARR00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ARR01-CARR · Rec · L2✓ compilableSEI index
배열 크기를 구할 때 포인터에 sizeof 를 적용하지 않는다Do not apply the sizeof operator to a pointer when taking the size of an array
❌ 위반 예시Non-compliant example
#include <stdio.h>
static void f(int a[]){
size_t n = sizeof(a) / sizeof(a[0]); /* a는 포인터 — n 틀림 */
printf("%zu\n", n);
}
int main(void){ int v[5]; f(v); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
static void f(const int *a, size_t n){
for (size_t i = 0; i < n; i++){ (void)a[i]; }
printf("%zu\n", n);
}
int main(void){ int v[5] = {0}; f(v, 5); return 0; }⚠️ 함수 인자로 전달된 배열은 포인터로 붕괴하므로 sizeof로 요소 수를 구하면 틀린다. 요소 수를 별도 인자로 전달한다.An array argument decays to a pointer, so sizeof gives the wrong element count. Pass the element count as a separate argument.
ARR02-CARR · Rec · SEISEI index
Explicitly specify array bounds, even if implicitly defined by an initializerExplicitly specify array bounds, even if implicitly defined by an initializer
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ARR02-C * SEI official index entry: Explicitly specify array bounds, even if implicitly defined by an initializer * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ARR02-C * SEI official index entry: Explicitly specify array bounds, even if implicitly defined by an initializer * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ARR02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ARR02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM메모리 관리Memory
MEM33-CMEM · Rule · L2✓ compilableSEI index
유연 배열 멤버를 가진 구조체는 동적으로 할당·복사한다Allocate and copy structures containing a flexible array member dynamically
❌ 위반 예시Non-compliant example
#include <stdio.h>
struct Buf { size_t n; char d[]; }; /* 유연 배열 멤버 */
int main(void){
struct Buf b; /* 자동 객체로 선언 — d 를 위한 공간이 전혀 없음 */
b.n = 1;
b.d[0] = 'x'; /* 할당되지 않은 영역에 쓰기 — 미정의 동작·손상 */
printf("%zu\n", b.n);
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
struct Buf { size_t n; char d[]; };
int main(void){
size_t len = 8;
struct Buf *b = malloc(sizeof *b + len); /* 헤더 + 배열 공간을 함께 할당 */
if (b == NULL) return 1;
b->n = len;
b->d[0] = 'x';
printf("%c\n", b->d[0]);
free(b);
return 0;
}⚠️ 유연 배열 멤버(char d[])는 구조체 크기에 포함되지 않아, 자동·정적 객체로 선언하면 그 배열을 위한 실제 메모리가 전혀 확보되지 않은 채 접근하게 되어 인접 메모리를 손상시킨다. sizeof(구조체)+배열길이 만큼 동적 할당해 멤버 공간을 확보하고, 복사도 그 크기대로 한다.A flexible array member (char d[]) is not counted in the struct size, so declaring the struct as an automatic or static object accesses an array with no memory reserved, corrupting adjacent memory. Allocate sizeof(struct)+array-length dynamically to reserve the member’s space, and copy by that size.
MEM30-CMEM · Rule · L1✓ compilableSEI index
해제된 메모리에 접근하지 않는다(use-after-free)Do not access freed memory
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
int *p = malloc(sizeof *p);
if (!p) return 1;
free(p);
*p = 7; /* 해제 후 사용 */
printf("%d\n", *p);
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
int *p = malloc(sizeof *p);
if (!p) return 1;
*p = 7;
printf("%d\n", *p);
free(p);
p = NULL; /* 즉시 무효화 */
return 0;
}⚠️ 해제된 메모리를 읽거나 쓰면 힙 손상·정보 유출·임의 코드 실행으로 이어질 수 있다. 해제 직후 포인터를 NULL로 무효화한다.Reading or writing freed memory can lead to heap corruption, info leaks, or code execution. Null the pointer immediately after freeing.
MEM31-CMEM · Rule · L1✓ compilableSEI index
동적으로 할당된 메모리는 정확히 한 번만 해제한다Free dynamically allocated memory exactly once
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
int *p = malloc(sizeof *p);
int err = 1;
free(p);
if (err) free(p); /* 이중 해제 */
printf("done\n");
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
int *p = malloc(sizeof *p);
free(p);
p = NULL;
free(p); /* NULL free는 무해 */
printf("done\n");
return 0;
}⚠️ 같은 메모리를 두 번 해제하면 힙 메타데이터가 손상되어 악용 가능한 취약점이 된다. 해제 후 NULL로 두어 이중 해제를 막는다.Freeing the same memory twice corrupts heap metadata into an exploitable bug. Null the pointer after freeing to prevent double-free.
MEM34-CMEM · Rule · L1✓ compilableSEI index
동적으로 할당된 메모리만 해제한다Only free memory allocated dynamically
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
char buf[32];
char *p = buf;
free(p); /* 자동 객체 해제 — 미정의 */
printf("done\n");
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
char *p = malloc(32);
if (p){ free(p); } /* 할당된 시작 포인터만 해제 */
printf("done\n");
return 0;
}⚠️ 정적/자동 객체나 배열 중간 포인터를 free하면 힙 손상·미정의 동작이 된다. malloc 계열로 받은 시작 포인터만 해제한다.Freeing a static/automatic object or mid-array pointer corrupts the heap. Only free the start pointer returned by malloc-family functions.
MEM35-CMEM · Rule · L2✓ compilableSEI index
객체에 충분한 메모리를 할당한다(곱셈 오버플로우 주의)Allocate sufficient memory for an object (beware multiplication overflow)
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
size_t n = 1000000000UL;
int *a = malloc(n * sizeof(int)); /* n*size 오버플로우 가능 */
if (a){ a[0] = 1; free(a); }
printf("done\n");
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
int main(void){
size_t n = 1000000000UL;
if (n > SIZE_MAX / sizeof(int)){ printf("too big\n"); return 1; }
int *a = malloc(n * sizeof(int));
if (a){ a[0] = 1; free(a); }
return 0;
}⚠️ 요소 수×크기 계산이 오버플로우하면 실제보다 작은 버퍼가 할당되어 힙 오버플로우가 난다. 곱셈 전에 오버플로우를 검사한다.If count×size overflows, a too-small buffer is allocated and overflowed. Check for multiplication overflow before allocating.
MEM36-CMEM · Rule · L2✓ compilableSEI index
realloc 로 과도 정렬(over-aligned) 객체의 정렬을 잃지 않는다Do not modify the alignment of objects by calling realloc()
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
void *p = aligned_alloc(64, 64); /* 64바이트 정렬 요청 */
if (p == NULL) return 1;
void *q = realloc(p, 128); /* realloc 은 기본 정렬만 보장 — 64바이트 정렬이 깨질 수 있음 */
if (q == NULL) { free(p); return 1; }
printf("%d\n", ((size_t)q % 64) == 0);
free(q);
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void){
void *p = aligned_alloc(64, 64);
if (p == NULL) return 1;
void *q = aligned_alloc(64, 128); /* 정렬을 유지한 새 블록 할당 */
if (q == NULL) { free(p); return 1; }
memcpy(q, p, 64); free(p); /* 복사 후 이전 블록 해제 */
printf("%d\n", ((size_t)q % 64) == 0);
free(q);
return 0;
}⚠️ realloc 은 malloc 과 동일한 기본 정렬만 보장하므로, aligned_alloc 등으로 과도 정렬한 객체를 realloc 하면 반환 블록의 정렬이 요구 정렬보다 약해져 SIMD·하드웨어 접근에서 오류가 난다. 정렬이 필요하면 새 정렬 블록을 할당해 복사하고 이전 블록을 해제한다.realloc only guarantees the same default alignment as malloc, so reallocating an over-aligned object (from aligned_alloc) can return a block whose alignment is weaker than required, faulting SIMD or hardware access. When alignment matters, allocate a new aligned block, copy, and free the old one.
MEM00-CMEM · Rec · SEISEI index
Allocate and free memory in the same module, at the same level of abstractionAllocate and free memory in the same module, at the same level of abstraction
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MEM00-C * SEI official index entry: Allocate and free memory in the same module, at the same level of abstraction * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MEM00-C * SEI official index entry: Allocate and free memory in the same module, at the same level of abstraction * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MEM00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MEM00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM01-CMEM · Rec · L2✓ compilableSEI index
free 직후 포인터에 새 값(NULL)을 즉시 저장한다Store a new value in pointers immediately after free()
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
struct N { int *data; };
int main(void){
struct N n;
n.data = malloc(sizeof(int));
free(n.data); /* 댕글링 상태로 남음 */
printf("%p\n", (void *)n.data);
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
struct N { int *data; };
int main(void){
struct N n;
n.data = malloc(sizeof(int));
free(n.data);
n.data = NULL; /* 즉시 무효화 */
printf("%p\n", (void *)n.data);
return 0;
}⚠️ 해제 후 그대로 둔 포인터는 댕글링 상태로 남아 후속 사용·이중 해제 위험이 된다. 해제 직후 NULL을 대입한다.A pointer left as-is after free remains dangling, risking later use or double-free. Assign NULL right after freeing.
MEM02-CMEM · Rec · SEISEI index
Immediately cast the result of a memory allocation function call into a pointer to the allocated typeImmediately cast the result of a memory allocation function call into a pointer to the allocated type
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MEM02-C * SEI official index entry: Immediately cast the result of a memory allocation function call into a pointer to the allocated type * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MEM02-C * SEI official index entry: Immediately cast the result of a memory allocation function call into a pointer to the allocated type * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MEM02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MEM02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM03-CMEM · Rec · SEISEI index
Clear sensitive information stored in reusable resourcesClear sensitive information stored in reusable resources
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MEM03-C * SEI official index entry: Clear sensitive information stored in reusable resources * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MEM03-C * SEI official index entry: Clear sensitive information stored in reusable resources * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MEM03-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MEM03-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM04-CMEM · Rec · L2✓ compilableSEI index
길이 0 할당에 주의한다Beware of zero-length allocations
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
size_t len = 0;
char *p = malloc(len); /* NULL 또는 0바이트 반환 가능 */
p[0] = 'x'; /* 역참조 위험 */
free(p);
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
size_t len = 0;
if (len == 0){ printf("empty\n"); return 0; }
char *p = malloc(len);
if (p){ p[0] = 'x'; free(p); }
return 0;
}⚠️ malloc(0)은 NULL이나 역참조 불가한 포인터를 반환할 수 있다. 0 길이를 별도 처리하고 반환값을 항상 검사한다.malloc(0) may return NULL or a non-dereferenceable pointer. Handle zero length separately and always check the result.
MEM05-CMEM · Rec · SEISEI index
Avoid large stack allocationsAvoid large stack allocations
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MEM05-C * SEI official index entry: Avoid large stack allocations * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MEM05-C * SEI official index entry: Avoid large stack allocations * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MEM05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MEM05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM06-CMEM · Rec · SEISEI index
Ensure that sensitive data is not written out to diskEnsure that sensitive data is not written out to disk
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MEM06-C * SEI official index entry: Ensure that sensitive data is not written out to disk * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MEM06-C * SEI official index entry: Ensure that sensitive data is not written out to disk * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MEM06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MEM06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM07-CMEM · Rec · SEISEI index
Ensure that the arguments to calloc(), when multiplied, do not wrapEnsure that the arguments to calloc(), when multiplied, do not wrap
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MEM07-C * SEI official index entry: Ensure that the arguments to calloc(), when multiplied, do not wrap * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MEM07-C * SEI official index entry: Ensure that the arguments to calloc(), when multiplied, do not wrap * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MEM07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MEM07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM10-CMEM · Rec · SEISEI index
Define and use a pointer validation functionDefine and use a pointer validation function
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MEM10-C * SEI official index entry: Define and use a pointer validation function * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MEM10-C * SEI official index entry: Define and use a pointer validation function * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MEM10-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MEM10-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM11-CMEM · Rec · SEISEI index
Do not assume infinite heap spaceDo not assume infinite heap space
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MEM11-C * SEI official index entry: Do not assume infinite heap space * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MEM11-C * SEI official index entry: Do not assume infinite heap space * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MEM11-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MEM11-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MEM12-CMEM · Rec · L3✓ compilableSEI index
다중 자원 정리는 goto 체인 등으로 누수 없이 처리한다Consider using a goto chain to clean up multiple resources without leaks
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
char *a = malloc(8);
char *b = malloc(8);
if (!b){ return 1; } /* a 누수 */
free(a); free(b);
printf("ok\n");
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
int rc = 1;
char *a = malloc(8);
if (!a) goto done;
char *b = malloc(8);
if (!b) goto free_a;
rc = 0;
free(b);
free_a:
free(a);
done:
printf("rc=%d\n", rc);
return rc;
}⚠️ 중간 실패 시 앞서 획득한 자원을 해제하지 않으면 누수가 쌓인다. 역순 정리(goto 체인 등)로 모든 경로에서 해제를 보장한다.Failing midway without releasing earlier resources leaks them. Use reverse-order cleanup (e.g. a goto chain) to free on every path.
STR문자·문자열Strings
STR11-CARR · Rule · SEISEI index
Do not specify the bound of a character array initialized with a string literalDo not specify the bound of a character array initialized with a string literal
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR11-C * SEI official index entry: Do not specify the bound of a character array initialized with a string literal * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR11-C * SEI official index entry: Do not specify the bound of a character array initialized with a string literal * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR11-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR11-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
STR31-CSTR · Rule · L1✓ compilableSEI index
문자열 저장 공간에 널 종료자 자리를 보장한다Guarantee that storage for strings has room for the null terminator
❌ 위반 예시Non-compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char d[8];
strcpy(d, "12345678"); /* 8자 + 널 = 9바이트 필요 */
printf("%s\n", d);
return 0;
}✅ 준수 예시Compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char d[9];
const char *src = "12345678";
strncpy(d, src, sizeof d - 1);
d[sizeof d - 1] = '\0';
printf("%s\n", d);
return 0;
}⚠️ 널 종료자 공간을 빠뜨리면 한 바이트 오버플로우와 종료되지 않은 문자열이 생긴다. 버퍼에 내용+널 자리를 확보하고 명시적으로 종료한다.Omitting room for the null terminator causes a one-byte overflow and an unterminated string. Reserve content+null space and terminate explicitly.
STR30-CSTR · Rule · L1✓ compilableSEI index
문자열 리터럴을 수정하려 하지 않는다Do not attempt to modify string literals
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
char *s = (char *)"hello";
s[0] = 'H'; /* 리터럴 수정 — 미정의 */
printf("%s\n", s);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
char s[] = "hello"; /* 수정 가능한 배열 복사본 */
s[0] = 'H';
printf("%s\n", s);
return 0;
}⚠️ 문자열 리터럴은 읽기 전용일 수 있어 수정 시 미정의 동작이다. 수정이 필요하면 배열로 복사해 다룬다.String literals may be read-only, so modifying them is undefined. Copy into an array when modification is needed.
STR32-CSTR · Rule · L1✓ compilableSEI index
널 종료되지 않은 문자 시퀀스를 문자열 인자로 넘기지 않는다Do not pass a non-null-terminated character sequence to a library function expecting a string
❌ 위반 예시Non-compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char buf[4];
memcpy(buf, "abcd", 4); /* 널 없음 */
printf("%zu\n", strlen(buf)); /* 경계 초과 읽기 */
return 0;
}✅ 준수 예시Compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char buf[5];
memcpy(buf, "abcd", 4);
buf[4] = '\0';
printf("%zu\n", strlen(buf));
return 0;
}⚠️ 널 종료가 없는 버퍼를 strlen/printf 등에 넘기면 메모리를 넘어 읽는다. 문자열 함수에 넘기기 전에 널 종료를 보장한다.Passing a non-terminated buffer to strlen/printf reads past memory. Ensure null termination before calling string functions.
STR34-CSTR · Rule · L2✓ compilableSEI index
문자를 더 큰 정수로 변환하기 전에 unsigned char 로 캐스트한다Cast characters to unsigned char before converting to larger integer sizes
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
char c = (char)0xFF;
int v = c; /* 음수 char가 부호 확장 */
printf("%d\n", v);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
char c = (char)0xFF;
int v = (unsigned char)c; /* 0..255 로 해석 */
printf("%d\n", v);
return 0;
}⚠️ 부호 있는 char를 더 큰 정수로 바로 변환하면 음수가 부호 확장되어 의도치 않은 큰 값이 된다. unsigned char로 먼저 캐스트한다.Converting a signed char directly sign-extends negatives into a large value. Cast to unsigned char first.
STR37-CSTR · Rule · L1✓ compilableSEI index
문자 처리 함수 인자는 unsigned char 로 표현 가능해야 한다Arguments to character-handling functions must be representable as an unsigned char
❌ 위반 예시Non-compliant example
#include <ctype.h>
#include <stdio.h>
int main(void){
char c = (char)0xC0;
if (isalpha(c)){ printf("alpha\n"); } /* 음수면 미정의 */
return 0;
}✅ 준수 예시Compliant example
#include <ctype.h>
#include <stdio.h>
int main(void){
char c = (char)0xC0;
if (isalpha((unsigned char)c)){ printf("alpha\n"); }
else printf("not\n");
return 0;
}⚠️ is*/to* 함수에 음수(EOF 외)를 넘기면 미정의 동작이다. unsigned char로 캐스트해 유효 범위를 보장한다.Passing a negative value (other than EOF) to is*/to* functions is undefined. Cast to unsigned char to guarantee a valid range.
STR38-CSTR · Rule · L1✓ compilableSEI index
좁은 문자열과 넓은 문자열/함수를 혼동하지 않는다Do not confuse narrow and wide character strings and functions
❌ 위반 예시Non-compliant example
#include <string.h>
#include <wchar.h>
#include <stdio.h>
int main(void){
wchar_t w[8];
strcpy((char *)w, "hi"); /* 넓은 버퍼에 좁은 복사 */
printf("%ls\n", w);
return 0;
}✅ 준수 예시Compliant example
#include <wchar.h>
#include <stdio.h>
int main(void){
wchar_t w[8];
wcscpy(w, L"hi"); /* 넓은 문자열 함수 */
printf("%ls\n", w);
return 0;
}⚠️ 좁은/넓은 문자 함수를 섞으면 요소 크기 차이로 데이터가 손상된다. 문자 폭에 맞는 함수와 리터럴을 사용한다.Mixing narrow and wide character functions corrupts data due to element-size differences. Use functions and literals matching the character width.
STR00-CSTR · Rec · SEISEI index
Represent characters using an appropriate typeRepresent characters using an appropriate type
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR00-C * SEI official index entry: Represent characters using an appropriate type * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR00-C * SEI official index entry: Represent characters using an appropriate type * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
STR01-CSTR · Rec · SEISEI index
Adopt and implement a consistent plan for managing stringsAdopt and implement a consistent plan for managing strings
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR01-C * SEI official index entry: Adopt and implement a consistent plan for managing strings * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR01-C * SEI official index entry: Adopt and implement a consistent plan for managing strings * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
STR02-CSTR · Rec · SEISEI index
Sanitize data passed to complex subsystemsSanitize data passed to complex subsystems
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR02-C * SEI official index entry: Sanitize data passed to complex subsystems * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR02-C * SEI official index entry: Sanitize data passed to complex subsystems * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
STR03-CSTR · Rec · L2✓ compilableSEI index
널 종료 문자열을 의도치 않게 잘라내지 않는다Do not inadvertently truncate a null-terminated byte string
❌ 위반 예시Non-compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char d[8];
strncpy(d, "12345678", sizeof d); /* 정확히 8자면 널 없음 */
printf("%zu\n", strlen(d)); /* 종료 안 됨 */
return 0;
}✅ 준수 예시Compliant example
#include <string.h>
#include <stdio.h>
int main(void){
char d[8];
strncpy(d, "12345678", sizeof d - 1);
d[sizeof d - 1] = '\0';
printf("%zu\n", strlen(d));
return 0;
}⚠️ strncpy는 한도까지 채우면 널을 붙이지 않아 종료되지 않은 문자열이 남는다. 마지막 바이트를 널로 명시 설정한다.strncpy does not append a null when it fills the limit, leaving an unterminated string. Set the last byte to null explicitly.
STR04-CSTR · Rec · SEISEI index
Use plain char for characters in the basic character setUse plain char for characters in the basic character set
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR04-C * SEI official index entry: Use plain char for characters in the basic character set * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR04-C * SEI official index entry: Use plain char for characters in the basic character set * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
STR05-CSTR · Rec · SEISEI index
Use pointers to const when referring to string literalsUse pointers to const when referring to string literals
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR05-C * SEI official index entry: Use pointers to const when referring to string literals * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR05-C * SEI official index entry: Use pointers to const when referring to string literals * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
STR06-CSTR · Rec · SEISEI index
Do not assume that strtok() leaves the parse string unchangedDo not assume that strtok() leaves the parse string unchanged
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR06-C * SEI official index entry: Do not assume that strtok() leaves the parse string unchanged * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR06-C * SEI official index entry: Do not assume that strtok() leaves the parse string unchanged * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
STR09-CSTR · Rec · SEISEI index
Don't assume numeric values for expressions with type plain characterDon't assume numeric values for expressions with type plain character
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR09-C * SEI official index entry: Don't assume numeric values for expressions with type plain character * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR09-C * SEI official index entry: Don't assume numeric values for expressions with type plain character * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
STR10-CSTR · Rec · SEISEI index
Do not concatenate different type of string literalsDo not concatenate different type of string literals
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for STR10-C * SEI official index entry: Do not concatenate different type of string literals * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for STR10-C * SEI official index entry: Do not concatenate different type of string literals * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ STR10-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.STR10-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ENV환경Environment
ENV30-CENV · Rule · L1✓ compilableSEI index
getenv 가 반환한 객체를 수정하지 않는다Do not modify the object referenced by the return value of getenv
❌ 위반 예시Non-compliant example
#include <stdlib.h>
int main(void){
char *home = getenv("HOME");
if (home) home[0] = '/'; /* getenv 결과를 직접 수정 — 미정의 동작 */
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <string.h>
int main(void){
const char *home = getenv("HOME");
char copy[256] = "";
if (home) { strncpy(copy, home, sizeof copy - 1); copy[sizeof copy - 1] = '\0'; }
if (copy[0]) copy[0] = '/'; /* 복사본을 수정 */
return 0;
}⚠️ getenv가 가리키는 문자열을 수정하면 미정의 동작이며 환경이 손상될 수 있다. 복사본을 만들어 수정한다.Modifying the string returned by getenv is undefined behavior and may corrupt the environment. Copy it first and modify the copy.
ENV31-CENV · Rule · L2✓ compilableSEI index
환경을 무효화할 수 있는 연산 후의 환경 포인터를 신뢰하지 않는다Do not rely on an environment pointer following an operation that may invalidate it
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
char *p = getenv("PATH");
setenv("PATH", "/tmp", 1); /* p 를 무효화할 수 있음 */
if (p) printf("%s\n", p); /* p 가 댕글링일 수 있음 */
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void){
char buf[512] = "";
char *p = getenv("PATH");
if (p) { strncpy(buf, p, sizeof buf - 1); buf[sizeof buf - 1] = '\0'; }
setenv("PATH", "/tmp", 1);
printf("%s\n", buf); /* 변경 전 복사해 둔 값 사용 */
return 0;
}⚠️ setenv/putenv 등은 이전에 받은 환경 포인터를 무효화할 수 있다. 변경 전에 필요한 값을 복사해 둔다.setenv/putenv can invalidate a previously obtained environment pointer. Copy any needed value before modifying the environment.
ENV32-CENV · Rule · L2✓ compilableSEI index
atexit 등록 핸들러는 정상적으로 반환해야 한다All exit handlers must return normally
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <setjmp.h>
static jmp_buf env;
static void cleanup(void){ longjmp(env, 1); } /* 종료 핸들러가 반환하지 않고 점프 — 미정의 */
int main(void){
atexit(cleanup);
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
static void free_resources(void){ printf("cleanup done\n"); }
static void cleanup(void){ free_resources(); } /* 작업 후 정상 반환 */
int main(void){
atexit(cleanup);
return 0;
}⚠️ atexit 으로 등록한 종료 핸들러가 longjmp 로 점프하거나 exit 를 다시 호출하는 등 정상적으로 반환하지 않으면, 종료 처리 순서가 깨져 미정의 동작이 된다. 종료 핸들러는 자원 정리 같은 작업을 마친 뒤 호출자에게 정상적으로 반환한다.If an atexit-registered handler does not return normally — e.g., it longjmps or calls exit again — the exit-processing sequence is broken, causing undefined behaviour. An exit handler should finish its work (such as resource cleanup) and return normally to its caller.
ENV33-CENV · Rule · L1✓ compilableSEI index
system() 을 호출하지 않는다Do not call system()
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
const char *dir = "/tmp";
char cmd[128];
snprintf(cmd, sizeof cmd, "ls %s", dir);
system(cmd); /* 셸을 거침 — 입력에 메타문자가 섞이면 명령 주입 */
return 0;
}✅ 준수 예시Compliant example
#define _GNU_SOURCE
#include <spawn.h>
#include <unistd.h>
#include <sys/wait.h>
extern char **environ;
int main(void){
const char *dir = "/tmp";
char *const argv[] = { "/bin/ls", (char *)dir, NULL };
pid_t pid;
if (posix_spawn(&pid, "/bin/ls", NULL, NULL, argv, environ) == 0)
waitpid(pid, NULL, 0); /* 셸을 거치지 않고 인자 분리 전달 */
return 0;
}⚠️ system은 셸을 거쳐 명령을 실행하므로 입력에 메타문자가 섞이면 임의 명령이 실행된다. 셸을 거치지 않는 exec/posix_spawn으로 인자를 분리 전달한다.system runs commands through a shell, so embedded metacharacters can execute arbitrary commands. Use exec/posix_spawn to pass arguments separately without a shell.
ENV34-CENV · Rule · L2✓ compilableSEI index
특정 함수가 반환한 포인터를 보관해 재사용하지 않는다Do not store pointers returned by certain functions for later reuse
❌ 위반 예시Non-compliant example
#include <locale.h>
#include <stdio.h>
int main(void){
char *a = setlocale(LC_ALL, "C");
setlocale(LC_ALL, "POSIX"); /* a 가 가리키던 내용이 덮어써질 수 있음 */
if (a) printf("%s\n", a);
return 0;
}✅ 준수 예시Compliant example
#include <locale.h>
#include <string.h>
#include <stdio.h>
int main(void){
char saved[64] = "";
char *a = setlocale(LC_ALL, NULL);
if (a) { strncpy(saved, a, sizeof saved - 1); saved[sizeof saved - 1] = '\0'; }
setlocale(LC_ALL, "POSIX");
printf("%s\n", saved); /* 즉시 복사해 보관한 값 사용 */
return 0;
}⚠️ getenv/setlocale/strerror 등이 반환한 포인터는 다음 호출에서 덮어써질 수 있다. 값을 즉시 복사해 보관한다.Pointers returned by getenv/setlocale/strerror may be overwritten by a subsequent call. Copy the value immediately if you need to retain it.
ENV01-CENV · Rule · SEISEI index
Do not make assumptions about the size of an environment variableDo not make assumptions about the size of an environment variable
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ENV01-C * SEI official index entry: Do not make assumptions about the size of an environment variable * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ENV01-C * SEI official index entry: Do not make assumptions about the size of an environment variable * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ENV01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ENV01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ENV02-CENV · Rule · SEISEI index
Beware of multiple environment variables with the same effective nameBeware of multiple environment variables with the same effective name
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ENV02-C * SEI official index entry: Beware of multiple environment variables with the same effective name * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ENV02-C * SEI official index entry: Beware of multiple environment variables with the same effective name * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ENV02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ENV02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
ENV03-CENV · Rule · SEISEI index
Sanitize the environment when invoking external programsSanitize the environment when invoking external programs
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for ENV03-C * SEI official index entry: Sanitize the environment when invoking external programs * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for ENV03-C * SEI official index entry: Sanitize the environment when invoking external programs * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ ENV03-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.ENV03-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
SIG시그널Signals
SIG30-CSIG · Rule · L1✓ compilableSEI index
시그널 핸들러에서는 비동기-안전(async-signal-safe) 함수만 호출한다Call only asynchronous-safe functions within signal handlers
❌ 위반 예시Non-compliant example
#include <signal.h>
#include <stdio.h>
void handler(int s){ printf("caught %d\n", s); } /* printf 는 async-signal-safe 아님 */
int main(void){ signal(SIGTERM, handler); return 0; }✅ 준수 예시Compliant example
#include <signal.h>
volatile sig_atomic_t flag = 0;
void handler(int s){ (void)s; flag = 1; } /* 플래그만 설정 */
int main(void){ signal(SIGTERM, handler); return (int)flag; }⚠️ 핸들러에서 malloc/printf 등 비동기-안전하지 않은 함수를 부르면 교착·재진입 손상이 생긴다. 플래그 설정 등 async-safe 작업만 한다.Calling non-async-signal-safe functions (malloc/printf) in a handler can deadlock or corrupt reentrant state. Do only async-safe work, such as setting a flag.
SIG31-CSIG · Rule · L1✓ compilableSEI index
시그널 핸들러에서 공유 객체를 안전하지 않게 접근하지 않는다Do not access shared objects in signal handlers in an unsafe manner
❌ 위반 예시Non-compliant example
#include <signal.h>
int counter;
void handler(int s){ (void)s; counter++; } /* 비원자 공유 접근 */
int main(void){ signal(SIGINT, handler); return counter; }✅ 준수 예시Compliant example
#include <signal.h>
volatile sig_atomic_t got = 0;
void handler(int s){ (void)s; got = 1; } /* sig_atomic_t 만 공유 */
int main(void){ signal(SIGINT, handler); return (int)got; }⚠️ 핸들러가 일반 변수를 갱신하면 메인 흐름과의 경쟁으로 값이 손상된다. volatile sig_atomic_t 또는 원자 타입만 공유한다.Updating an ordinary variable in a handler races with the main flow and corrupts it. Share only volatile sig_atomic_t or atomic types.
SIG34-CSIG · Rule · L2✓ compilableSEI index
인터럽트 가능한 시그널 핸들러 내부에서 signal() 을 호출하지 않는다Do not call signal() from within interruptible signal handlers
❌ 위반 예시Non-compliant example
#include <signal.h>
void handler(int s){ signal(s, handler); } /* 핸들러 안에서 재설정 — 경쟁 구간 */
int main(void){ signal(SIGTERM, handler); return 0; }✅ 준수 예시Compliant example
#include <signal.h>
#include <string.h>
void handler(int s){ (void)s; }
int main(void){
struct sigaction sa;
memset(&sa, 0, sizeof sa);
sa.sa_handler = handler;
sigaction(SIGTERM, &sa, NULL); /* 지속적 처리를 미리 설정 */
return 0;
}⚠️ 핸들러 안의 signal() 재설정은 경쟁 구간을 만들어 시그널을 놓칠 수 있다. sigaction으로 영속적 처리를 미리 설정한다.Re-arming with signal() inside a handler creates a race window where a signal can be lost. Establish a persistent disposition up front with sigaction.
SIG35-CSIG · Rule · L1✓ compilableSEI index
계산 예외(연산 오류) 시그널 핸들러에서 정상 반환하지 않는다Do not return from a computational exception signal handler
❌ 위반 예시Non-compliant example
#include <signal.h>
static void h(int s){ (void)s; return; } /* SIGFPE 핸들러가 반환 → 결함 명령 재실행 */
int main(void){
signal(SIGFPE, h);
return 0;
}✅ 준수 예시Compliant example
#include <signal.h>
#include <stdlib.h>
static volatile sig_atomic_t fpe = 0;
static void h(int s){ (void)s; fpe = 1; _Exit(1); } /* 정상 반환하지 않고 안전히 종료 */
int main(void){
signal(SIGFPE, h);
return 0;
}⚠️ 0 나눗셈 등 계산 예외(SIGFPE)의 핸들러에서 그냥 반환하면, 결함을 일으킨 바로 그 명령이 재실행되어 같은 예외가 무한히 반복되거나 미정의 동작이 된다. 이런 핸들러는 정상 반환하지 않고 _Exit 등으로 안전하게 종료한다.Returning from a handler for a computational exception like division by zero (SIGFPE) re-executes the very instruction that faulted, repeating the same exception indefinitely or causing undefined behaviour. Such handlers must not return normally; terminate safely with _Exit or similar.
SIG00-CPOS · Rule · SEISEI index
Mask signals handled by noninterruptible signal handlersMask signals handled by noninterruptible signal handlers
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for SIG00-C * SEI official index entry: Mask signals handled by noninterruptible signal handlers * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for SIG00-C * SEI official index entry: Mask signals handled by noninterruptible signal handlers * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ SIG00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.SIG00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
SIG01-CPOS · Rule · SEISEI index
Understand implementation-specific details regarding signal handler persistenceUnderstand implementation-specific details regarding signal handler persistence
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for SIG01-C * SEI official index entry: Understand implementation-specific details regarding signal handler persistence * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for SIG01-C * SEI official index entry: Understand implementation-specific details regarding signal handler persistence * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ SIG01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.SIG01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
SIG02-CPOS · Rule · SEISEI index
Avoid using signals to implement normal functionalityAvoid using signals to implement normal functionality
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for SIG02-C * SEI official index entry: Avoid using signals to implement normal functionality * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for SIG02-C * SEI official index entry: Avoid using signals to implement normal functionality * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ SIG02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.SIG02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC기타Miscellaneous
MSC11-CERR · Rule · SEISEI index
Incorporate diagnostic tests using assertionsIncorporate diagnostic tests using assertions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC11-C * SEI official index entry: Incorporate diagnostic tests using assertions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC11-C * SEI official index entry: Incorporate diagnostic tests using assertions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC11-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC11-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC30-CMSC · Rule · L3✓ compilableSEI index
보안 목적에 rand() 를 사용하지 않는다Do not use rand() for security purposes
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
int token = rand(); /* 예측 가능한 의사난수 — 토큰/키에 부적합 */
printf("%d\n", token);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
unsigned char token[16];
FILE *f = fopen("/dev/urandom", "rb"); /* OS 암호학적 난수(CSPRNG) */
if (!f || fread(token, 1, sizeof token, f) != sizeof token) { if (f) fclose(f); return -1; }
fclose(f);
printf("%02x\n", token[0]);
return 0;
}⚠️ rand()는 예측 가능해 토큰·키·논스 등 보안 요소에 부적합하다. OS의 암호학적 난수(CSPRNG)를 사용한다.rand() is predictable and unfit for tokens, keys, or nonces. Use the OS cryptographically secure RNG (CSPRNG), e.g., /dev/urandom.
MSC32-CMSC · Rule · L3✓ compilableSEI index
의사난수 생성기를 적절히 시드(seed)한다Properly seed pseudorandom number generators
❌ 위반 예시Non-compliant example
#include <stdlib.h>
#include <stdio.h>
int main(void){
srand(1); /* 고정 시드 — 매 실행 동일 수열 */
printf("%d\n", rand());
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main(void){
srand((unsigned)time(NULL) ^ (unsigned)getpid()); /* 비보안 용도에 한해 */
printf("%d\n", rand());
return 0;
}⚠️ 고정 시드는 매 실행마다 같은 수열을 만들어 예측 가능하다. 비보안 용도라도 변하는 값으로 시드하고, 보안 용도는 CSPRNG를 쓴다.A fixed seed yields the same sequence every run and is predictable. Seed with a varying value for non-security use; use a CSPRNG for security.
MSC33-CMSC · Rule · L2✓ compilableSEI index
asctime() 에 유효하지 않은 데이터를 넘기지 않는다Do not pass invalid data to asctime()
❌ 위반 예시Non-compliant example
#include <time.h>
#include <stdio.h>
int main(void){
struct tm t = {0};
t.tm_mon = 13; /* 범위를 벗어난 필드 */
char *s = asctime(&t); /* 내부 고정 버퍼 오버플로우 가능 */
printf("%s", s);
return 0;
}✅ 준수 예시Compliant example
#include <time.h>
#include <stdio.h>
int main(void){
struct tm t = {0};
t.tm_year = 124; t.tm_mon = 5; t.tm_mday = 23;
char buf[64];
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &t); /* 경계가 안전 */
printf("%s\n", buf);
return 0;
}⚠️ asctime은 tm 필드가 범위를 벗어나면 내부 고정 버퍼를 넘쳐 손상된다. 경계가 안전한 strftime을 사용한다.asctime can overflow its fixed internal buffer when tm fields are out of range. Use the bounded strftime instead.
MSC37-CMSC · Rule · L1✓ compilableSEI index
비void 함수의 끝에 제어가 도달하지 않도록 한다Ensure that control never reaches the end of a non-void function
❌ 위반 예시Non-compliant example
#include <stdio.h>
int sign(int x){
if (x > 0) return 1;
if (x < 0) return -1;
} /* x==0 일 때 반환 없음 — 불확정 반환값 */
int main(void){ printf("%d\n", sign(0)); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
int sign(int x){
if (x > 0) return 1;
if (x < 0) return -1;
return 0; /* 모든 경로에서 반환 */
}
int main(void){ printf("%d\n", sign(0)); return 0; }⚠️ 반환 없이 끝나는 비void 함수의 반환값은 불확정이라 호출부가 쓰레기값을 쓴다. 모든 경로에서 값을 반환한다.A non-void function that falls off the end returns an indeterminate value the caller then uses. Return a value on every path.
MSC38-CMSC · Rule · L1✓ compilableSEI index
미리 정의된(predefined) 식별자를 객체처럼 다루지 않는다Do not treat a predefined identifier as an object
❌ 위반 예시Non-compliant example
#include <stdio.h>
static const char *saved;
static void here(void){
saved = &__func__[0]; /* __func__ 의 주소를 보관 — 수명·표현이 보장되지 않음 */
}
int main(void){ here(); printf("%s\n", saved ? "set" : "null"); return 0; }✅ 준수 예시Compliant example
#include <stdio.h>
#include <string.h>
static char name[64];
static void here(void){
strncpy(name, __func__, sizeof name - 1); /* 값을 복사해 사용 */
name[sizeof name - 1] = '\0';
}
int main(void){ here(); printf("%s\n", name); return 0; }⚠️ __func__ 같은 미리 정의된 식별자는 일반 객체가 아니라 컴파일러가 함수마다 제공하는 특수 식별자라, 그 주소를 보관해 함수 밖에서 재사용하는 동작은 수명·표현이 보장되지 않는다. 필요한 값은 별도 버퍼에 복사해 사용한다.A predefined identifier like __func__ is not an ordinary object but a special, compiler-provided identifier per function, so storing its address and reusing it outside the function has no guaranteed lifetime or representation. Copy the needed value into a separate buffer and use that.
MSC39-CMSC · Rule · L1✓ compilableSEI index
불확정 상태의 va_list 에 va_arg 를 호출하지 않는다Do not call va_arg() on a va_list that has an indeterminate value
❌ 위반 예시Non-compliant example
#include <stdarg.h>
#include <stdio.h>
static int consume(va_list ap){ return va_arg(ap, int); } /* 인자를 소비 */
static int bad_first(int n, ...){
va_list ap; va_start(ap, n);
(void)consume(ap); /* 피호출자가 ap 를 소비 → ap 는 불확정 상태가 될 수 있음 */
int x = va_arg(ap, int); /* 소비된 ap 재사용 — 미정의 동작 */
va_end(ap);
return x;
}
int main(void){ printf("%d\n", bad_first(2, 10, 20)); return 0; }✅ 준수 예시Compliant example
#include <stdarg.h>
#include <stdio.h>
static int consume(va_list ap){ return va_arg(ap, int); }
static int good_first(int n, ...){
va_list ap, copy;
va_start(ap, n);
va_copy(copy, ap); /* 독립 복사본을 만들어 넘김 */
(void)consume(copy);
va_end(copy);
int x = va_arg(ap, int); /* 원본 ap 는 소비되지 않아 안전 */
va_end(ap);
return x;
}
int main(void){ printf("%d\n", good_first(2, 10, 20)); return 0; }⚠️ va_list 를 다른 함수에 값으로 넘기면 그 함수가 va_arg 로 인자를 소비해 호출 측의 va_list 가 불확정 상태가 될 수 있는데, 그 상태에서 다시 va_arg 를 부르면 미정의 동작이 된다. 넘길 때는 va_copy 로 독립 복사본을 만들어 원본 상태를 보존한다.Passing a va_list by value to another function lets that function consume arguments via va_arg, potentially leaving the caller’s va_list in an indeterminate state, and calling va_arg again then is undefined behaviour. Make an independent copy with va_copy before passing to preserve the original’s state.
MSC40-CMSC · Rule · L2✓ compilableSEI index
언어 제약(constraints)을 위반하지 않는다Do not violate constraints
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int *p = "text"; /* 호환되지 않는 포인터 타입으로 초기화 — 제약 위반 */
printf("%p\n", (void *)p);
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
const char *p = "text"; /* 타입을 일치 */
printf("%s\n", p);
return 0;
}⚠️ 표준이 정의한 제약(호환되지 않는 타입 대입 등)을 어기면 진단 가능하지만 이식성·동작이 깨질 수 있다. 타입 규칙 등 언어 제약을 준수한다.Violating a Standard constraint (e.g., assigning incompatible pointer types) is diagnosable but breaks portability and behavior. Honor language constraints such as type rules.
MSC41-CMSC · Rule · L1✓ compilableSEI index
민감 정보를 소스에 하드코딩하지 않는다Never hard code sensitive information
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
const char *db_pass = "P@ssw0rd!"; /* 소스에 비밀번호 노출 */
printf("connecting...\n");
return db_pass[0] ? 0 : 1;
}✅ 준수 예시Compliant example
#include <stdio.h>
#include <stdlib.h>
int main(void){
const char *db_pass = getenv("DB_PASS"); /* 런타임에 외부에서 로드 */
if (!db_pass) { fprintf(stderr, "secret not provided\n"); return 1; }
printf("connecting...\n");
return 0;
}⚠️ 소스에 박힌 비밀번호·키는 바이너리·저장소를 통해 유출된다. 비밀은 보안 저장소·환경에서 런타임에 로드한다.Passwords and keys embedded in source leak through the binary and the repository. Load secrets at runtime from a secure store or environment.
MSC00-CMSC · Rec · SEISEI index
Compile cleanly at high warning levelsCompile cleanly at high warning levels
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC00-C * SEI official index entry: Compile cleanly at high warning levels * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC00-C * SEI official index entry: Compile cleanly at high warning levels * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC01-CMSC · Rec · SEISEI index
Strive for logical completenessStrive for logical completeness
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC01-C * SEI official index entry: Strive for logical completeness * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC01-C * SEI official index entry: Strive for logical completeness * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC04-CMSC · Rec · SEISEI index
Use comments consistently and in a readable fashionUse comments consistently and in a readable fashion
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC04-C * SEI official index entry: Use comments consistently and in a readable fashion * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC04-C * SEI official index entry: Use comments consistently and in a readable fashion * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC05-CMSC · Rec · SEISEI index
Do not manipulate time_t typed values directlyDo not manipulate time_t typed values directly
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC05-C * SEI official index entry: Do not manipulate time_t typed values directly * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC05-C * SEI official index entry: Do not manipulate time_t typed values directly * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC06-CMSC · Rec · SEISEI index
Beware of compiler optimizationsBeware of compiler optimizations
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC06-C * SEI official index entry: Beware of compiler optimizations * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC06-C * SEI official index entry: Beware of compiler optimizations * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC06-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC06-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC07-CMSC · Rec · SEISEI index
Detect and remove dead codeDetect and remove dead code
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC07-C * SEI official index entry: Detect and remove dead code * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC07-C * SEI official index entry: Detect and remove dead code * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC10-CMSC · Rec · SEISEI index
Character encoding: UTF8-related issuesCharacter encoding: UTF8-related issues
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC10-C * SEI official index entry: Character encoding: UTF8-related issues * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC10-C * SEI official index entry: Character encoding: UTF8-related issues * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC10-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC10-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC12-CMSC · Rec · L2✓ compilableSEI index
죽은(dead) 코드를 검출하고 제거한다Detect and remove code that has no effect or is never executed
❌ 위반 예시Non-compliant example
#include <stdio.h>
int compute(void){ return 42; }
int demo(void){
int v = compute();
return v;
printf("unreached\n"); /* 도달 불가 — 죽은 코드 */
}
int main(void){ return demo() & 1; }✅ 준수 예시Compliant example
#include <stdio.h>
int compute(void){ return 42; }
int demo(void){
int v = compute();
printf("computed %d\n", v);
return v;
}
int main(void){ return demo() & 1; }⚠️ 도달 불가·효과 없는 코드는 논리 오류의 신호이며 유지보수를 방해한다. 죽은 코드는 제거하거나 흐름을 바로잡는다.Unreachable or no-effect code signals a logic error and hampers maintenance. Remove dead code or fix the control flow.
MSC13-CMSC · Rec · SEISEI index
Detect and remove unused valuesDetect and remove unused values
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC13-C * SEI official index entry: Detect and remove unused values * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC13-C * SEI official index entry: Detect and remove unused values * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC13-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC13-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC14-CMSC · Rec · SEISEI index
Do not introduce unnecessary platform dependenciesDo not introduce unnecessary platform dependencies
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC14-C * SEI official index entry: Do not introduce unnecessary platform dependencies * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC14-C * SEI official index entry: Do not introduce unnecessary platform dependencies * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC14-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC14-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC15-CMSC · Rec · SEISEI index
Do not depend on undefined behaviorDo not depend on undefined behavior
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC15-C * SEI official index entry: Do not depend on undefined behavior * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC15-C * SEI official index entry: Do not depend on undefined behavior * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC15-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC15-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC17-CMSC · Rec · L2✓ compilableSEI index
모든 switch 절을 break 로 마무리한다Finish every nonempty switch clause with break
❌ 위반 예시Non-compliant example
#include <stdio.h>
int main(void){
int c = 1;
switch (c) {
case 1: printf("one\n"); /* break 누락 — fall-through */
case 2: printf("two\n"); break;
}
return 0;
}✅ 준수 예시Compliant example
#include <stdio.h>
int main(void){
int c = 1;
switch (c) {
case 1: printf("one\n"); break;
case 2: printf("two\n"); break;
default: break;
}
return 0;
}⚠️ break 누락은 의도치 않은 다음 절 실행을 유발한다. 각 절을 break/return으로 명시 종료한다(의도적 fall-through는 주석으로 표시).A missing break causes unintended fall-through to the next clause. End each clause with break/return (mark intentional fall-through with a comment).
MSC18-CMSC · Rec · SEISEI index
Be careful while handling sensitive data, such as passwords, in program codeBe careful while handling sensitive data, such as passwords, in program code
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC18-C * SEI official index entry: Be careful while handling sensitive data, such as passwords, in program code * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC18-C * SEI official index entry: Be careful while handling sensitive data, such as passwords, in program code * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC18-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC18-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC19-CMSC · Rec · SEISEI index
For functions that return an array, prefer returning an empty array over a null valueFor functions that return an array, prefer returning an empty array over a null value
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC19-C * SEI official index entry: For functions that return an array, prefer returning an empty array over a null value * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC19-C * SEI official index entry: For functions that return an array, prefer returning an empty array over a null value * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC19-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC19-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC20-CMSC · Rec · SEISEI index
Do not use a switch statement to transfer control into a complex blockDo not use a switch statement to transfer control into a complex block
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC20-C * SEI official index entry: Do not use a switch statement to transfer control into a complex block * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC20-C * SEI official index entry: Do not use a switch statement to transfer control into a complex block * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC20-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC20-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC21-CMSC · Rec · L2✓ compilableSEI index
견고한 루프 종료 조건을 사용한다Use robust loop termination conditions
❌ 위반 예시Non-compliant example
#include <stddef.h>
#include <stdio.h>
int main(void){
size_t n = 3;
for (size_t i = n; i >= 0; i--) /* size_t 는 항상 >=0 — 무한 루프 */
printf("%zu\n", i);
return 0;
}✅ 준수 예시Compliant example
#include <stddef.h>
#include <stdio.h>
int main(void){
size_t n = 3;
for (size_t i = n; i-- > 0; ) /* 부호 없는 타입에 안전한 종료 */
printf("%zu\n", i);
return 0;
}⚠️ 부호 없는 카운터에 >=0 종료 조건을 쓰면 영원히 참이라 무한 루프가 된다. 타입 특성을 고려한 안전한 종료 조건을 쓴다.An unsigned counter with a >=0 termination test is always true, creating an infinite loop. Use a termination condition that accounts for the type.
MSC22-CMSC · Rec · SEISEI index
Use the setjmp(), longjmp() facility securelyUse the setjmp(), longjmp() facility securely
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC22-C * SEI official index entry: Use the setjmp(), longjmp() facility securely * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC22-C * SEI official index entry: Use the setjmp(), longjmp() facility securely * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC22-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC22-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC23-CMSC · Rec · SEISEI index
Beware of vendor-specific library and language differencesBeware of vendor-specific library and language differences
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC23-C * SEI official index entry: Beware of vendor-specific library and language differences * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC23-C * SEI official index entry: Beware of vendor-specific library and language differences * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC23-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC23-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC24-CMSC · Rec · SEISEI index
Do not use deprecated or obsolescent functionsDo not use deprecated or obsolescent functions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC24-C * SEI official index entry: Do not use deprecated or obsolescent functions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC24-C * SEI official index entry: Do not use deprecated or obsolescent functions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC24-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC24-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC25-CMSC · Rec · SEISEI index
Do not use insecure or weak cryptographic algorithmsDo not use insecure or weak cryptographic algorithms
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC25-C * SEI official index entry: Do not use insecure or weak cryptographic algorithms * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC25-C * SEI official index entry: Do not use insecure or weak cryptographic algorithms * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC25-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC25-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
MSC09-CMSC · Rec · SEISEI index
Character encoding: Use subset of ASCII for safetyCharacter encoding: Use subset of ASCII for safety
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for MSC09-C * SEI official index entry: Character encoding: Use subset of ASCII for safety * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for MSC09-C * SEI official index entry: Character encoding: Use subset of ASCII for safety * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ MSC09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.MSC09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
WINWindowsWindows
WIN01-CCON · Rule · SEISEI index
Do not forcibly terminate executionDo not forcibly terminate execution
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for WIN01-C * SEI official index entry: Do not forcibly terminate execution * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for WIN01-C * SEI official index entry: Do not forcibly terminate execution * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ WIN01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.WIN01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
WIN30-CWIN · Rule · L1✓ compilableSEI index
할당과 해제 함수를 올바르게 짝지어 사용한다Properly pair allocation and deallocation functions
❌ 위반 예시Non-compliant example
#include <stdlib.h>
int main(void){
char *p = (char *)malloc(32);
if (!p) return 1;
free(p + 1); /* malloc 이 돌려준 포인터가 아님 — 힙 손상 (Win: malloc/HeapFree 불일치와 동일) */
return 0;
}✅ 준수 예시Compliant example
#include <stdlib.h>
int main(void){
char *p = (char *)malloc(32);
if (!p) return 1;
free(p); /* 같은 할당기가 돌려준 정확한 포인터로 해제 */
return 0;
}⚠️ 서로 다른 할당기로 할당·해제하거나 잘못된 포인터를 해제하면 힙이 손상된다. malloc↔free, (Windows) HeapAlloc↔HeapFree처럼 동일 계열·정확한 포인터로 짝지어 사용한다.Freeing with a mismatched allocator or a wrong pointer corrupts the heap. Pair them correctly with the exact pointer: malloc/free, and on Windows HeapAlloc/HeapFree.
WIN00-CWIN · Rule · SEISEI index
Be specific when dynamically loading librariesBe specific when dynamically loading libraries
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for WIN00-C * SEI official index entry: Be specific when dynamically loading libraries * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for WIN00-C * SEI official index entry: Be specific when dynamically loading libraries * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ WIN00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.WIN00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
WIN02-CWIN · Rule · SEISEI index
Restrict privileges when spawning child processesRestrict privileges when spawning child processes
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for WIN02-C * SEI official index entry: Restrict privileges when spawning child processes * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for WIN02-C * SEI official index entry: Restrict privileges when spawning child processes * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ WIN02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.WIN02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
WIN03-CWIN · Rule · SEISEI index
Understand HANDLE inheritanceUnderstand HANDLE inheritance
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for WIN03-C * SEI official index entry: Understand HANDLE inheritance * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for WIN03-C * SEI official index entry: Understand HANDLE inheritance * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ WIN03-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.WIN03-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
WIN04-CWIN · Rule · SEISEI index
Consider encrypting function pointersConsider encrypting function pointers
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for WIN04-C * SEI official index entry: Consider encrypting function pointers * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for WIN04-C * SEI official index entry: Consider encrypting function pointers * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ WIN04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.WIN04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
APIAPIApplication Programming Interfaces
API10-CARR · Rec · SEISEI index
APIs should have security options enabled by defaultAPIs should have security options enabled by default
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API10-C * SEI official index entry: APIs should have security options enabled by default * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API10-C * SEI official index entry: APIs should have security options enabled by default * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API10-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API10-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
API00-CAPI · Rec · SEISEI index
Functions should validate their parametersFunctions should validate their parameters
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API00-C * SEI official index entry: Functions should validate their parameters * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API00-C * SEI official index entry: Functions should validate their parameters * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API00-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API00-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
API01-CAPI · Rec · SEISEI index
Avoid laying out strings in memory directly before sensitive dataAvoid laying out strings in memory directly before sensitive data
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API01-C * SEI official index entry: Avoid laying out strings in memory directly before sensitive data * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API01-C * SEI official index entry: Avoid laying out strings in memory directly before sensitive data * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API01-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API01-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
API02-CAPI · Rec · SEISEI index
Functions that read or write to or from an array should take an argument to specify the source or target sizeFunctions that read or write to or from an array should take an argument to specify the source or target size
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API02-C * SEI official index entry: Functions that read or write to or from an array should take an argument to specify the source or target size * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API02-C * SEI official index entry: Functions that read or write to or from an array should take an argument to specify the source or target size * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API02-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API02-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
API03-CAPI · Rec · SEISEI index
Create consistent interfaces and capabilities across related functionsCreate consistent interfaces and capabilities across related functions
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API03-C * SEI official index entry: Create consistent interfaces and capabilities across related functions * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API03-C * SEI official index entry: Create consistent interfaces and capabilities across related functions * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API03-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API03-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
API04-CAPI · Rec · SEISEI index
Provide a consistent and usable error-checking mechanismProvide a consistent and usable error-checking mechanism
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API04-C * SEI official index entry: Provide a consistent and usable error-checking mechanism * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API04-C * SEI official index entry: Provide a consistent and usable error-checking mechanism * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API04-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API04-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
API05-CAPI · Rec · SEISEI index
Use conformant array parametersUse conformant array parameters
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API05-C * SEI official index entry: Use conformant array parameters * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API05-C * SEI official index entry: Use conformant array parameters * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API05-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API05-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
API07-CAPI · Rec · SEISEI index
Enforce type safetyEnforce type safety
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API07-C * SEI official index entry: Enforce type safety * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API07-C * SEI official index entry: Enforce type safety * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API07-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API07-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
API09-CAPI · Rec · SEISEI index
Compatible values should have the same typeCompatible values should have the same type
❌ 위반 예시Non-compliant example
/* Non-compliant training placeholder for API09-C * SEI official index entry: Compatible values should have the same type * Add a reviewed C example before using this item as a hands-on lab. */
✅ 준수 예시Compliant example
/* Compliant training placeholder for API09-C * SEI official index entry: Compatible values should have the same type * Add a reviewed C example before using this item as a hands-on lab. */
⚠️ API09-C는 SEI CERT 공식 공개 인덱스 기준으로 추가한 항목입니다. 현재 항목은 목록 완전성을 위해 먼저 반영했으며, 실습 전 공식 페이지와 정적분석 진단 기준으로 예제를 보강하세요.API09-C was added from the official public SEI CERT index. It is included for coverage completeness; add reviewed examples against the official page and static-analysis diagnostics before hands-on use.
CERT C++
SEI CERT C++ Coding Standard
Rules / RecommendationsRules / RecommendationsSeverity × Likelihood × RemediationSeverity × Likelihood × RemediationLevel L1 / L2 / L3Level L1 / L2 / L3
CERT C의 C++ 판으로, RAII·예외·객체수명 등 C++ 고유 위험을 다룬다. 규칙 ID는 "섹션+번호-CPP"(예: MEM50-CPP).The C++ edition of CERT C, covering C++-specific hazards such as RAII, exceptions and object lifetime. Rule IDs use "section+number-CPP" (e.g. MEM50-CPP).
DCL선언·초기화Declarations
DCL50-CPPDCL · Rule · L1✓ compilableSEI index
C 스타일 가변인자 함수를 정의하지 않는다Do not define a C-style variadic function
❌ 위반 예시Non-compliant example
#include <cstdarg>
#include <iostream>
// 타입·개수 검사가 전혀 없는 C 스타일 가변인자
static long sum(int n, ...) {
va_list ap; va_start(ap, n);
long s = 0;
for (int i = 0; i < n; ++i) s += va_arg(ap, int); // 호출자가 double 을 넘기면 미정의
va_end(ap);
return s;
}
int main() {
std::cout << sum(3, 10, 20, 30) << '\n'; // 우연히 동작하지만 타입 안전성 없음
std::cout << sum(2, 10, 3.5) << '\n'; // 두 번째가 double — 잘못된 추출, 쓰레기 값
}✅ 준수 예시Compliant example
#include <iostream>
// 가변 템플릿 — 인자 타입·개수를 컴파일 타임에 안전하게 처리
template <typename... Args>
auto sum(Args... args) { return (args + ... + 0); } // C++17 fold expression
int main() {
std::cout << sum(10, 20, 30) << '\n';
std::cout << sum(10, 3.5) << '\n'; // double 도 타입 안전하게 합산
}⚠️ 근거: C 스타일 ... 가변인자는 인자의 타입과 개수에 대한 정보가 컴파일러에 남지 않아 va_arg 가 지정한 타입과 실제 인자가 다르면 검사 없이 잘못된 비트를 읽는다. 영향: 호출자가 형식 문자열과 인자를 어긋나게 넘기면 쓰레기 값·크래시·정보 유출로 이어진다. 대응: 가변 템플릿(fold expression)이나 std::initializer_list 로 대체하면 타입·개수가 모두 컴파일 타임에 검증된다.Rationale: C-style "..." varargs keep no type or count information, so va_arg blindly reinterprets bytes when the requested type does not match the actual argument. Impact: a mismatch between caller arguments and extraction yields garbage values, crashes, or information disclosure. Fix: replace with variadic templates (fold expressions) or std::initializer_list so types and counts are checked at compile time.
DCL51-CPPDCL · Rule · L1✓ compilableSEI index
예약된 식별자를 선언하거나 정의하지 않는다Do not declare or define a reserved identifier
❌ 위반 예시Non-compliant example
#include <iostream>
#define _Max 100 // 밑줄+대문자로 시작 — 전역에서 구현에 예약됨
int __count = 0; // 이중 밑줄 — 모든 사용처에서 구현에 예약됨
int main() {
__count = _Max;
std::cout << __count << '\n'; // 표준 라이브러리 매크로와 충돌하면 의미가 조용히 바뀜
}✅ 준수 예시Compliant example
#include <iostream>
constexpr int kMax = 100; // 예약되지 않은 일반 이름
int g_count = 0;
int main() {
g_count = kMax;
std::cout << g_count << '\n';
}⚠️ 근거: 밑줄+대문자/이중 밑줄로 시작하는 이름과 전역의 밑줄+소문자 이름은 표준이 구현(컴파일러·표준 라이브러리)에 예약한 영역이다. 영향: 그런 이름을 정의하면 헤더 내부 매크로·식별자와 충돌해 진단 없이 코드 의미가 바뀌거나 미정의 동작이 된다. 대응: 사용자 코드는 예약 패턴을 피한 비예약 이름만 사용한다.Rationale: names beginning with an underscore followed by an uppercase letter, names containing a double underscore, and file-scope names beginning with an underscore are reserved for the implementation. Impact: defining them can silently collide with library macros or identifiers, changing program meaning or causing undefined behaviour with no diagnostic. Fix: user code must use only non-reserved names.
DCL52-CPPDCL · Rule · L1SEI index
참조(reference) 타입에 const/volatile 한정을 붙이지 않는다Never qualify a reference type with const or volatile
❌ 위반 예시Non-compliant example
int x = 0; int& const r = x; // 참조는 본래 재바인딩 불가 — 참조에 const 는 무의미하며 컴파일 에러 int& volatile vr = x; // 마찬가지로 부적격(ill-formed)
✅ 준수 예시Compliant example
int x = 0; int& r = x; // 참조 자체엔 cv 한정 불필요 const int& cr = x; // 한정은 가리키는 '대상' 타입에 적용 volatile int& vr = x;
⚠️ 근거: 참조는 초기화 후 다른 객체를 가리키도록 재바인딩될 수 없으므로 참조 자체는 이미 변경 불가이고, 거기에 다시 const/volatile 을 붙이는 것은 의미가 없어 표준이 부적격(ill-formed)으로 규정한다. 영향: 의도(가리키는 대상을 const 로 보호)와 표기가 어긋나, 컴파일 에러가 나거나 typedef 를 거쳐 조용히 무시되면서 오해를 부른다. 대응: cv 한정은 참조가 가리키는 대상 타입(const int&)에 적용한다.Rationale: a reference cannot be rebound to another object after initialization, so the reference itself is already immutable, and adding const/volatile to it is meaningless — the standard makes it ill-formed. Impact: intent (protecting the referent as const) and notation diverge, causing a compile error or, when laundered through a typedef, being silently ignored and misleading readers. Fix: apply cv-qualification to the referent type (const int&).
DCL53-CPPDCL · Rule · L3✓ compilableSEI index
구문적으로 모호한 선언(most vexing parse)을 작성하지 않는다Do not write syntactically ambiguous declarations
❌ 위반 예시Non-compliant example
#include <iostream>
struct Gadget { Gadget(){} };
struct Widget { Widget(Gadget){ } int v = 7; };
int main() {
Widget w(Gadget()); // 객체가 아니라 'Gadget(*)() 를 받는 함수 w' 선언으로 해석
// w 는 객체가 아니라 함수라서 w.v 같은 멤버 접근은 컴파일조차 되지 않는다
std::cout << "no Widget object was constructed; 'w' is a function declaration\n";
}✅ 준수 예시Compliant example
#include <iostream>
struct Gadget { Gadget(){} };
struct Widget { Widget(Gadget){ } int v = 7; };
int main() {
Widget w{Gadget{}}; // 중괄호 초기화 — 명백히 객체 생성
std::cout << w.v << '\n';
}⚠️ 근거: T obj( U() ) 형태는 객체 초기화가 아니라 "U(*)() 를 인자로 받아 T 를 반환하는 함수 obj" 의 선언으로 해석된다(most vexing parse). 영향: 의도한 객체가 만들어지지 않아 이후 멤버 접근이 컴파일 에러가 나거나, 더 미묘하게는 함수 선언이 조용히 통과해 런타임 논리가 어긋난다. 대응: 중괄호 초기화 Widget w{...} 를 써서 선언/함수 모호성을 제거한다.Rationale: the form T obj( U() ) is parsed not as object initialization but as a declaration of a function obj taking a "U(*)()" and returning T (the most vexing parse). Impact: the intended object is never created, so later member access fails to compile, or more subtly a stray function declaration passes silently and breaks runtime logic. Fix: use brace initialization Widget w{...} to remove the declaration/function ambiguity.
DCL54-CPPDCL · Rule · L1✓ compilableSEI index
할당/해제 연산자는 짝을 맞춰 오버로드한다Overload allocation and deallocation functions as a pair
❌ 위반 예시Non-compliant example
#include <cstdlib>
#include <new>
#include <iostream>
struct Pool {
static void* operator new(std::size_t n) { // new 만 오버로드, delete 없음
std::cout << "pool alloc\n";
return std::malloc(n);
}
int v = 1;
};
int main() {
Pool* p = new Pool; // 사용자 정의 new
delete p; // 기본 delete — malloc 메모리를 표준 해제기로 반환, 짝 어긋남
}✅ 준수 예시Compliant example
#include <cstdlib>
#include <new>
#include <iostream>
struct Pool {
static void* operator new(std::size_t n) {
std::cout << "pool alloc\n";
return std::malloc(n);
}
static void operator delete(void* p) noexcept { // 짝 정의 — 같은 할당기로 해제
std::cout << "pool free\n";
std::free(p);
}
int v = 1;
};
int main() {
Pool* p = new Pool;
delete p;
}⚠️ 근거: operator new 를 오버로드하면서 대응하는 operator delete 를 정의하지 않으면, 사용자 정의 할당으로 얻은 메모리가 기본 해제기로 반환되어 할당기와 해제기가 어긋난다. 영향: 풀·아레나 같은 커스텀 할당기에서 힙 메타데이터가 손상되고, 생성자 예외 시 호출되는 짝 맞는 delete 가 없어 누수가 발생한다. 대응: new/delete(및 배열 형태)를 항상 짝으로 오버로드한다.Rationale: overloading operator new without the matching operator delete means memory from the custom allocator is returned through the default deallocator, so allocator and deallocator no longer agree. Impact: with pool/arena allocators this corrupts heap metadata, and if a constructor throws there is no matching delete to call, leaking memory. Fix: always overload new/delete (and the array forms) as a pair.
DCL55-CPPDCL · Rule · L1✓ compilableSEI index
신뢰 경계 너머로 객체를 전달할 때 패딩으로 정보가 유출되지 않게 한다Avoid information leakage when passing a class object across a trust boundary
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstring>
struct Msg { char tag; int val; }; // tag 와 val 사이에 패딩 바이트 존재
int main() {
char prev[sizeof(Msg)];
std::memset(prev, 0xAB, sizeof prev); // 이전에 쓰던 민감 데이터를 흉내
Msg m;
std::memcpy(&m, prev, sizeof m); // 패딩에 0xAB 잔존
m.tag = 1; m.val = 2; // 멤버만 덮음 — 패딩은 그대로
const unsigned char* raw = reinterpret_cast<const unsigned char*>(&m);
for (std::size_t i = 0; i < sizeof m; ++i) std::printf("%02X ", raw[i]); // 패딩에 AB 유출
std::cout << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstring>
struct Msg { char tag; int val; };
int main() {
Msg m{}; // 값 초기화 — 패딩 포함 전체가 0
m.tag = 1; m.val = 2;
const unsigned char* raw = reinterpret_cast<const unsigned char*>(&m);
for (std::size_t i = 0; i < sizeof m; ++i) std::printf("%02X ", raw[i]);
std::cout << '\n'; // 패딩은 00 — 잔존 데이터 없음
}⚠️ 근거: 구조체 멤버 사이에는 정렬을 맞추기 위한 패딩 바이트가 들어가는데, 멤버만 대입하면 이 패딩은 초기화되지 않은 채(이전에 그 메모리에 있던 값) 남는다. 영향: sizeof 만큼 통째로 직렬화해 소켓·파일·다른 프로세스 등 신뢰 경계 밖으로 보내면, 패딩에 남은 스택·힙 잔존물(키·포인터 등)이 함께 유출된다. 대응: 경계를 넘는 객체는 값 초기화({})로 패딩까지 0 으로 만든 뒤 멤버를 채우거나, 패딩 없는 명시적 직렬화 포맷을 사용한다.Rationale: padding bytes are inserted between struct members for alignment, and assigning only the members leaves that padding uninitialized — holding whatever was previously in that memory. Impact: serializing the whole object by sizeof and sending it across a trust boundary (socket, file, another process) leaks the leftover stack/heap contents (keys, pointers) sitting in the padding. Fix: value-initialize ({}) objects that cross a boundary so padding is zeroed before filling members, or use an explicit padding-free serialization format.
DCL56-CPPDCL · Rule · L2SEI index
정적 객체 초기화 중 순환 의존을 만들지 않는다Avoid cycles during initialization of static objects
❌ 위반 예시Non-compliant example
// a.cpp extern int b; int a = b + 1; // 다른 TU 의 b 에 의존 // b.cpp extern int a; int b = a + 1; // 초기화 순서가 TU 간에 미정 — 한쪽은 0 을 읽음
✅ 준수 예시Compliant example
// 지연 초기화로 순서를 강제 — 최초 호출 시 정확히 한 번 초기화
int& a();
int& b() { static int v = 1; return v; }
int& a() { static int v = b() + 1; return v; } // a() 호출이 b() 를 먼저 보장⚠️ 근거: 서로 다른 번역단위의 네임스페이스 범위 정적 객체들은 초기화 순서가 표준으로 정해지지 않아(미지정), 한 객체가 아직 초기화 안 된 다른 객체의 값에 의존하면 0(영초기화 상태)을 읽을 수 있다. 영향: a, b 가 서로의 값으로 초기화되면 빌드·링크 순서에 따라 결과가 달라지는 비결정적 버그가 되어 재현이 어렵다. 대응: 전역 의존 대신 함수 지역 static(최초 사용 시 초기화)으로 감싸 호출이 의존 순서를 강제하게 한다.Rationale: namespace-scope static objects in different translation units have no standardized initialization order (unspecified), so one that depends on another not-yet-initialized object may read 0 (the zero-initialized state). Impact: if a and b initialize from each other, the result varies with build/link order — a nondeterministic bug that is hard to reproduce. Fix: wrap dependencies in function-local statics (initialized on first use) so calls enforce the dependency order instead of relying on globals.
DCL57-CPPDCL · Rule · L1✓ compilableSEI index
소멸자나 해제 연산자에서 예외가 빠져나가지 않게 한다Do not let exceptions escape from destructors or deallocation functions
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
struct File {
bool dirty = true;
void flush() { throw std::runtime_error("disk full"); }
~File() { flush(); } // 소멸자에서 예외가 빠져나감 → 스택 풀기 중이면 terminate
};
int main() {
try { File f; } // f 소멸 시 던진 예외 — 위험
catch (const std::exception& e) { std::cout << e.what() << '\n'; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct File {
bool dirty = true;
void flush() { throw std::runtime_error("disk full"); }
~File() noexcept { // 명시적 noexcept
try { flush(); }
catch (...) { std::cerr << "flush failed in dtor, logged\n"; } // 흡수
}
};
int main() {
File f;
std::cout << "clean shutdown\n";
}⚠️ 근거: 예외로 스택이 풀리는 도중 또 다른 예외가 소멸자에서 빠져나가면 동시에 두 예외가 전파되어 std::terminate 가 호출된다. 영향: 정상 오류 처리 경로에서도 프로그램이 즉시 강제 종료되어 다른 자원 정리가 모두 건너뛰어진다. 대응: 소멸자·해제 연산자는 noexcept 로 두고 내부에서 발생할 수 있는 예외를 try/catch 로 흡수해 로깅만 한다.Rationale: if a destructor lets an exception escape while the stack is already unwinding from another exception, two exceptions propagate at once and std::terminate is called. Impact: the program is killed even on an ordinary error path, skipping all other cleanup. Fix: mark destructors and deallocation functions noexcept and absorb any internal exception with try/catch, logging only.
DCL58-CPPDCL · Rule · L1SEI index
표준 네임스페이스(std)를 수정하지 않는다Do not modify the standard namespace
❌ 위반 예시Non-compliant example
// 다른 헤더에서 보이는 std 에 임의 선언을 추가 — 미정의 동작
namespace std {
void my_helper(); // std 에 사용자 함수 추가 — 금지
template <typename T> struct vector; // 표준 템플릿 재선언 — 금지
}✅ 준수 예시Compliant example
#include <functional>
struct MyKey { int id; };
// 사용자 타입에 대한 std::hash 특수화는 규정된 범위에서만 허용된다
template <>
struct std::hash<MyKey> {
std::size_t operator()(const MyKey& k) const noexcept {
return std::hash<int>{}(k.id);
}
};⚠️ 근거: 표준은 사용자가 정의한 타입에 한정한 일부 특수화만 허용하고, 그 밖에 std 네임스페이스에 선언·정의를 추가하는 것은 미정의 동작으로 규정한다. 영향: 구현이 제공하는 동일 이름과 충돌하거나 향후 표준 변경 시 깨져 진단 없이 동작이 바뀐다. 대응: 사용자 코드는 자체 네임스페이스에 두고, std 에는 허용된 사용자 타입 특수화(std::hash 등)만 규정대로 추가한다.Rationale: the standard permits only certain specializations limited to user-defined types; otherwise adding declarations or definitions to namespace std is undefined behaviour. Impact: it can collide with implementation-provided names or break on a future standard revision, silently changing behaviour. Fix: keep user code in your own namespace and add to std only the permitted user-type specializations (e.g. std::hash) exactly as specified.
DCL59-CPPDCL · Rule · L2SEI index
헤더에 이름 없는(unnamed) 네임스페이스를 정의하지 않는다Do not define an unnamed namespace in a header file
❌ 위반 예시Non-compliant example
// util.h — 여러 .cpp 가 포함
namespace { int counter = 0; } // 포함하는 번역단위마다 별도 counter 사본 생성
inline int next() { return ++counter; }✅ 준수 예시Compliant example
// util.h
namespace util { extern int counter; int next(); }
// util.cpp
namespace util { int counter = 0; int next(){ return ++counter; } }⚠️ 근거: 무명 네임스페이스의 멤버는 내부 링크를 가지므로 헤더를 포함하는 번역단위마다 완전히 별개의 실체가 만들어진다. 영향: 하나의 전역 상태라고 믿고 쓴 counter 가 TU마다 따로 존재해 값이 공유되지 않고, inline 함수가 TU별 사본을 참조해 ODR 혼란이 생긴다. 대응: 헤더에는 명명 네임스페이스의 extern 선언만 두고 정의는 한 .cpp 에 둔다.Rationale: members of an unnamed namespace have internal linkage, so each translation unit that includes the header gets an entirely separate entity. Impact: a counter intended as one global instead exists per TU and is not shared, and inline functions referring to per-TU copies create ODR confusion. Fix: put only an extern declaration in a named namespace in the header and the definition in one .cpp.
DCL60-CPPDCL · Rule · L2SEI index
단일 정의 규칙(ODR)을 준수한다Obey the one-definition rule
❌ 위반 예시Non-compliant example
// a.cpp
struct Packet { int len; }; // 정의 #1
// b.cpp
struct Packet { long len; char f; }; // 같은 이름, 다른 레이아웃 — ODR 위반✅ 준수 예시Compliant example
// packet.h (유일한 정의)
struct Packet { int len; };
// a.cpp, b.cpp 모두 #include "packet.h" 로 같은 정의 공유⚠️ 근거: 같은 이름의 클래스·인라인 함수·템플릿은 프로그램 전체에서 토큰 단위로 동일한 단 하나의 정의만 가져야 한다(ODR). 영향: 번역단위마다 레이아웃이 다른 Packet 을 정의하면 링커가 그중 하나를 임의 선택해, 크기·오프셋 불일치로 메모리 손상이 진단 없이 발생한다. 대응: 타입·인라인 함수 정의는 헤더 한 곳에 두고 모든 TU가 그 헤더를 포함한다.Rationale: a class, inline function, or template of a given name must have exactly one token-identical definition across the whole program (ODR). Impact: defining Packet with different layouts in different TUs lets the linker pick one arbitrarily, causing size/offset mismatch and silent memory corruption. Fix: put the type or inline-function definition in a single header that every TU includes.
CTR컨테이너Containers
CTR58-CPPCTR · Rule · L3✓ compilableSEI index
술어 함수 객체는 호출 간 상태를 변경하지 않게 한다Predicate function objects should not mutate state across calls
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
#include <algorithm>
struct Pred { // 호출마다 변하는 상태
int n = 0;
bool operator()(int) { return n++ < 2; }
};
int main() {
std::vector<int> v{1, 2, 3, 4, 5};
auto it = std::remove_if(v.begin(), v.end(), Pred{}); // 술어 복사·재호출 시 비결정적
v.erase(it, v.end());
for (int x : v) std::cout << x << ' ';
std::cout << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v{1, 2, 3, 4, 5};
auto it = std::remove_if(v.begin(), v.end(),
[](int x){ return x < 3; }); // 무상태 순수 술어
v.erase(it, v.end());
for (int x : v) std::cout << x << ' ';
std::cout << '\n';
}⚠️ 근거: 표준 알고리즘은 술어 함수 객체를 명세상 임의 횟수로 복사하고 호출할 수 있어, 호출 순서·횟수에 의존하는 가변 상태(카운터 등)는 사본마다 독립적으로 동작한다. 영향: 어떤 원소가 제거될지가 구현·최적화에 따라 달라지는 비결정적 결과가 되어 이식성과 재현성이 깨진다. 대응: 술어는 입력만으로 결과가 정해지는 부작용 없는 순수 함수(또는 무상태 람다)로 작성한다.Rationale: standard algorithms are permitted to copy and invoke a predicate function object any number of times, so mutable state (such as a counter) that depends on call order or count behaves independently in each copy. Impact: which elements are removed becomes nondeterministic across implementations and optimizations, breaking portability and reproducibility. Fix: write predicates as side-effect-free pure functions (or stateless lambdas) whose result depends only on the input.
CTR50-CPPCTR · Rule · L1✓ compilableSEI index
컨테이너 인덱스/반복자가 유효 범위 안에 있도록 보장한다Guarantee that container indices and iterators are within the valid range
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
static int element_at(const std::vector<int>& v, std::size_t idx) {
return v[idx]; // idx 범위 미검증 — 범위 밖이면 메모리 손상
}
int main() {
std::vector<int> v{1, 2, 3};
std::cout << element_at(v, 7) << '\n'; // 범위 밖 접근 — 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <stdexcept>
static int element_at(const std::vector<int>& v, std::size_t idx) {
return v.at(idx); // 경계 검사 — 범위 밖이면 std::out_of_range
}
int main() {
std::vector<int> v{1, 2, 3};
try { std::cout << element_at(v, 7) << '\n'; }
catch (const std::out_of_range& e) { std::cout << "out of range\n"; }
}⚠️ 근거: operator[] 는 성능을 위해 범위를 전혀 검사하지 않으므로, 잘못된 인덱스는 컨테이너 버퍼 밖의 메모리를 읽거나 쓴다. 영향: 범위 밖 접근은 인접 데이터 손상·정보 유출·크래시를 일으키고, 입력으로 제어되면 보안 취약점이 된다. 대응: 인덱스를 size() 와 비교하거나 경계 검사를 수행하는 at() 을 사용한다.Rationale: operator[] performs no bounds checking for speed, so an invalid index reads or writes memory outside the container buffer. Impact: an out-of-range access corrupts adjacent data, leaks information, or crashes, and becomes a security flaw when driven by input. Fix: compare the index against size() or use at(), which performs bounds checking.
CTR51-CPPCTR · Rule · L1✓ compilableSEI index
컨테이너 원소에 대한 유효한 참조/포인터/반복자만 사용한다Use valid references, pointers, and iterators to reference container elements
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
int& r = v[0]; // 첫 원소 참조
v.push_back(4); // 용량 초과 시 재할당 → 기존 버퍼 해제, r 무효화
r = 9; // 댕글링 참조에 쓰기 — 미정의 동작
std::cout << v[0] << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
v.push_back(4); // 먼저 컨테이너를 수정
v[0] = 9; // 그 다음 안전하게 인덱스로 접근
std::cout << v[0] << '\n';
}⚠️ 근거: vector 는 용량을 초과하는 삽입 시 더 큰 버퍼를 새로 할당하고 기존 버퍼를 해제하므로, 원소를 가리키던 참조·포인터·반복자가 모두 무효화된다. 영향: 무효화된 참조에 접근하면 해제된 힙을 읽거나 써서 댕글링 버그가 되고 데이터가 손상된다. 대응: 컨테이너를 수정한 뒤에는 참조·반복자를 다시 얻거나, 인덱스로 재접근한다.Rationale: a vector allocates a new larger buffer and frees the old one when an insertion exceeds capacity, invalidating every reference, pointer, and iterator to its elements. Impact: accessing an invalidated reference reads or writes freed heap, a dangling bug that corrupts data. Fix: re-obtain references/iterators after modifying the container, or re-access by index.
CTR52-CPPCTR · Rule · L2✓ compilableSEI index
컨테이너 연산이 용량을 넘쳐 오버플로우하지 않게 한다Guarantee that library functions do not overflow
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
#include <cstdint>
int main() {
std::vector<int> v;
std::size_t huge = SIZE_MAX / 2; // 거대한 요청
v.reserve(huge); // max_size 초과 → length_error/실패
std::cout << v.capacity() << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <cstdint>
int main() {
std::vector<int> v;
std::size_t huge = SIZE_MAX / 2;
if (huge <= v.max_size()) v.reserve(huge); // 한계 검증 후 예약
else std::cout << "request exceeds max_size\n";
std::cout << v.capacity() << '\n';
}⚠️ 근거: reserve·resize 에 전달한 원소 수에 원소 크기를 곱한 바이트 수가 size_t 범위를 넘거나 max_size() 를 초과하면 컨테이너가 할당을 수행할 수 없다. 영향: 검증 없이 거대한 값을 넘기면 std::length_error 나 bad_alloc 으로 갑작스러운 종료가 되고, 곱셈이 오버플로우하면 의도보다 작은 버퍼가 할당되어 이후 접근이 경계를 넘는다. 대응: 요청 크기를 max_size() 와 비교해 한계 안에서만 예약·확장한다.Rationale: if the requested element count times the element size exceeds the size_t range or max_size(), the container cannot perform the allocation. Impact: passing a huge value unchecked aborts abruptly via std::length_error or bad_alloc, and if the multiplication overflows, a smaller-than-intended buffer is allocated so later accesses run past the boundary. Fix: compare the requested size against max_size() and reserve or grow only within the limit.
CTR53-CPPCTR · Rule · L1✓ compilableSEI index
유효한 반복자 범위(iterator range)를 사용한다Use valid iterator ranges
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v{3, 1, 2};
std::sort(v.end(), v.begin()); // first 가 last 뒤 — 범위 무효, 미정의 동작
for (int x : v) std::cout << x << ' ';
std::cout << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v{3, 1, 2};
std::sort(v.begin(), v.end()); // [begin, end) — 유효한 반(half-open) 범위
for (int x : v) std::cout << x << ' ';
std::cout << '\n';
}⚠️ 근거: 표준 알고리즘은 [first, last) 가 반복적으로 first 를 증가시켜 last 에 도달할 수 있는 유효 범위라고 가정한다. 영향: first 가 last 보다 뒤이거나 서로 다른 컨테이너의 반복자를 섞으면 알고리즘이 끝을 넘어 순회해 메모리 손상·무한 루프가 된다. 대응: 같은 컨테이너에서 얻은 begin/end 를 올바른 순서로 전달한다.Rationale: standard algorithms assume [first, last) is a valid range where repeatedly incrementing first reaches last. Impact: if first is after last, or iterators from different containers are mixed, the algorithm runs past the end, causing memory corruption or an infinite loop. Fix: pass begin/end obtained from the same container in the correct order.
CTR54-CPPCTR · Rule · L2✓ compilableSEI index
같은 컨테이너에 속하지 않는 반복자를 비교/빼지 않는다Do not subtract or compare iterators that do not refer to the same container
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
int main() {
std::vector<int> a{1, 2, 3};
std::vector<int> b{4, 5};
auto d = a.begin() - b.begin(); // 서로 다른 컨테이너 반복자 뺄셈 — 미정의
std::cout << d << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
int main() {
std::vector<int> a{1, 2, 3};
auto d = a.end() - a.begin(); // 같은 컨테이너 — 유효한 거리
std::cout << d << '\n'; // 3
}⚠️ 근거: 반복자 뺄셈·관계 비교는 두 반복자가 같은 배열(컨테이너)의 원소를 가리킬 때만 의미가 정의된다. 영향: 서로 다른 컨테이너의 반복자를 빼면 무관한 두 메모리 주소의 차이를 계산해 의미 없는 값이 나오고 미정의 동작이 된다. 대응: 거리·순서 비교는 같은 컨테이너에서 얻은 반복자끼리만 수행한다.Rationale: iterator subtraction and relational comparison are defined only when both iterators refer to elements of the same array (container). Impact: subtracting iterators from different containers computes the difference of two unrelated addresses, yielding a meaningless value and undefined behaviour. Fix: perform distance and ordering comparisons only between iterators obtained from the same container.
CTR55-CPPCTR · Rule · L2✓ compilableSEI index
반복자 덧셈 연산이 범위를 넘쳐 오버플로우하지 않게 한다Do not use an additive operator on an iterator if the result would overflow
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
static int at_offset(const std::vector<int>& v, std::size_t offset) {
auto it = v.begin() + offset; // offset 이 size 보다 크면 end 를 넘어선 무효 반복자
return *it; // 무효 반복자 역참조 — 미정의 동작
}
int main() {
std::vector<int> v{1, 2, 3};
std::cout << at_offset(v, 9) << '\n'; // 범위 밖
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <optional>
static std::optional<int> at_offset(const std::vector<int>& v, std::size_t offset) {
if (offset >= v.size()) return std::nullopt; // 덧셈 전 범위 검증
return *(v.begin() + offset);
}
int main() {
std::vector<int> v{1, 2, 3};
auto r = at_offset(v, 9);
std::cout << (r ? std::to_string(*r) : "out of range") << '\n';
}⚠️ 근거: 임의 접근 반복자에 정수를 더하는 연산은 결과가 [begin, end] 범위 안에 머무를 때만 유효하며, 그 범위를 벗어나거나 정수 계산이 오버플로우하면 무효 반복자가 된다. 영향: 무효 반복자를 역참조하면 컨테이너 버퍼 밖 메모리를 읽어 미정의 동작·정보 유출·크래시가 나고, 오프셋이 외부 입력이면 보안 결함이 된다. 대응: 반복자에 오프셋을 더하기 전에 그 오프셋이 size() 이내인지 검사하고, 실패는 optional·예외 등으로 명시 처리한다.Rationale: adding an integer to a random-access iterator is valid only when the result stays within [begin, end], and going past that range or overflowing the integer arithmetic produces an invalid iterator. Impact: dereferencing an invalid iterator reads memory outside the container buffer, causing undefined behaviour, information disclosure, or a crash, and becomes a security flaw when the offset is external input. Fix: check that the offset is within size() before adding it to an iterator, and handle failure explicitly via optional or an exception.
CTR56-CPPCTR · Rule · L2✓ compilableSEI index
다형 객체에 포인터 산술을 적용하지 않는다Do not use pointer arithmetic on polymorphic objects
❌ 위반 예시Non-compliant example
#include <iostream>
#include <memory>
struct Base { virtual void f(){ std::cout << "Base\n"; } virtual ~Base()=default; };
struct Derived : Base { long extra=0; void f() override { std::cout << "Derived\n"; } };
int main() {
Base* arr = new Derived[3]; // 배열 요소는 Derived 크기
arr[1].f(); // Base 크기로 인덱싱 → 잘못된 주소, 미정의 동작
delete[] static_cast<Derived*>(arr);
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
#include <vector>
struct Base { virtual void f(){ std::cout << "Base\n"; } virtual ~Base()=default; };
struct Derived : Base { long extra=0; void f() override { std::cout << "Derived\n"; } };
int main() {
std::vector<std::unique_ptr<Base>> v; // 다형 컬렉션 — 포인터 산술 없음
v.push_back(std::make_unique<Derived>());
v.push_back(std::make_unique<Derived>());
v[1]->f(); // 정확한 다형 디스패치
}⚠️ 근거: arr[i] 와 포인터 산술은 정적 포인터 타입의 크기를 보폭으로 사용하는데, 실제 배열 요소가 더 큰 파생 타입이면 보폭이 어긋난다. 영향: 두 번째 이후 요소의 주소가 객체 경계와 맞지 않아 잘못된 메모리를 가상 호출 대상으로 삼아 미정의 동작·크래시가 난다. 대응: 다형 객체 컬렉션은 raw 배열 대신 스마트 포인터 컨테이너(vector<unique_ptr<Base>>)로 구성한다.Rationale: arr[i] and pointer arithmetic use the size of the static pointer type as the stride, but when the real array elements are a larger derived type the stride is wrong. Impact: addresses of elements past the first do not line up with object boundaries, so a virtual call targets wrong memory, causing undefined behaviour or a crash. Fix: build polymorphic collections with smart-pointer containers (vector<unique_ptr<Base>>) instead of raw arrays.
CTR57-CPPCTR · Rule · L2✓ compilableSEI index
정렬/연관 컨테이너에 유효한 순서 술어(predicate)를 제공한다Provide a valid ordering predicate for sorted and associative containers
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v{5, 2, 8, 2, 1};
std::sort(v.begin(), v.end(),
[](int a, int b){ return a <= b; }); // <= 는 엄격 약순서 위반
for (int x : v) std::cout << x << ' ';
std::cout << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v{5, 2, 8, 2, 1};
std::sort(v.begin(), v.end(),
[](int a, int b){ return a < b; }); // 동치를 false 로 — 엄격 약순서
for (int x : v) std::cout << x << ' ';
std::cout << '\n';
}⚠️ 근거: sort·map·set 같은 정렬/연관 컨테이너는 비교 술어가 엄격 약순서(strict weak ordering)를 만족한다고 가정하는데, 핵심은 같은 값에 대해 comp(a,a) 가 false 여야 한다는 것이다. 영향: <= 처럼 동치에 true 를 주는 술어는 두 동일 원소에서 모순을 만들어 알고리즘이 범위를 넘어 순회하거나 트리 불변식을 깨 미정의 동작이 된다. 대응: < 처럼 동치를 false 로 두는 술어를 사용한다.Rationale: sorted and associative containers like sort, map, and set assume the comparison predicate is a strict weak ordering, whose key requirement is that comp(a,a) is false for equal values. Impact: a predicate like <= that returns true for equal elements creates a contradiction on duplicates, letting the algorithm run past the range or break tree invariants — undefined behaviour. Fix: use a predicate such as < that returns false for equivalent values.
EXP표현식Expressions
EXP50-CPPEXP · Rule · L2✓ compilableSEI index
부작용의 평가 순서에 의존하지 않는다Do not depend on the order of evaluation for side effects
❌ 위반 예시Non-compliant example
#include <iostream>
static int g(int x){ std::cout << "g(" << x << ") "; return x; }
int main() {
int i = 0;
int r = g(i++) + g(i++); // 두 g 호출의 평가 순서가 미명세 — 인쇄 순서·증분 시점 불확정
std::cout << "= " << r << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
static int g(int x){ std::cout << "g(" << x << ") "; return x; }
int main() {
int i = 0;
int a = g(i++); // 부작용을 분리 — 순서 확정
int b = g(i++);
int r = a + b;
std::cout << "= " << r << '\n';
}⚠️ 근거: 한 식 안의 여러 함수 호출 인자나 피연산자의 평가 순서는(C++17에서 일부 강화됐어도) 일반적으로 미명세라 같은 변수를 여러 번 수정·읽으면 결과가 정해지지 않는다. 영향: 컴파일러·최적화 수준에 따라 다른 값이 나와 이식성·재현성이 깨지고, 같은 객체에 부작용이 겹치면 미정의 동작이 된다. 대응: 부작용을 별도 문장으로 분리해 순서를 명시적으로 확정한다.Rationale: the evaluation order of multiple call arguments or operands within one expression is generally unspecified (even with C++17 tightening), so modifying and reading the same variable multiple times gives an indeterminate result. Impact: different values appear depending on compiler/optimization, breaking portability and reproducibility, and overlapping side effects on one object are undefined behaviour. Fix: split side effects into separate statements to fix the order explicitly.
EXP51-CPPEXP · Rule · L1✓ compilableSEI index
잘못된 타입의 포인터로 배열을 delete 하지 않는다Do not delete an array through a pointer of the incorrect type
❌ 위반 예시Non-compliant example
#include <iostream>
struct Base { int x = 1; };
struct Derived : Base { int y = 2; }; // sizeof(Derived) > sizeof(Base)
int main() {
Base* p = new Derived[3]; // 배열 요소는 Derived 크기, 포인터는 Base*
delete[] p; // delete[] 가 Base 보폭으로 순회 — 미정의 동작
std::cout << "done\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
struct Base { int x = 1; };
struct Derived : Base { int y = 2; };
int main() {
std::vector<Derived> v(3); // 다형 배열 대신 컨테이너로 타입·수명 관리
std::cout << v.size() << '\n';
}⚠️ 근거: delete[] 는 정적 포인터 타입의 크기로 각 요소 주소를 계산해 소멸자를 호출하는데, 배열 실제 요소 타입이 더 큰 파생 클래스면 보폭이 어긋난다. 영향: 잘못된 주소에서 소멸자를 호출하고 잘못된 크기로 해제해 미정의 동작·힙 손상이 발생한다. 대응: 다형 객체 배열은 raw new[]/delete[] 대신 std::vector 나 스마트 포인터 컨테이너로 관리한다.Rationale: delete[] computes each element address using the size of the static pointer type to call destructors, so if the real element type is a larger derived class the stride is wrong. Impact: it calls destructors at wrong addresses and frees with the wrong size, causing undefined behaviour and heap corruption. Fix: manage arrays of polymorphic objects with std::vector or smart-pointer containers instead of raw new[]/delete[].
EXP52-CPPEXP · Rule · L3✓ compilableSEI index
미평가 피연산자(sizeof 등)의 부작용에 의존하지 않는다Do not rely on side effects in unevaluated operands
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int a[5] = {0};
int i = 0;
std::size_t n = sizeof(a[i++]); // sizeof 의 피연산자는 미평가 — i++ 가 일어나지 않음
std::cout << n << ' ' << i << '\n'; // i 는 여전히 0
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int a[5] = {0};
int i = 0;
std::size_t n = sizeof(a[0]); // 부작용 없는 표현
++i; // 의도한 증가는 별도 문장으로
std::cout << n << ' ' << i << '\n';
}⚠️ 근거: sizeof, decltype, noexcept, typeid(다형 glvalue 제외) 의 피연산자는 평가되지 않고 타입만 검사되므로 그 안의 부작용(증가·호출·할당)은 실행되지 않는다. 영향: i++ 같은 부작용이 일어났다고 가정하면 카운터·인덱스가 갱신되지 않아 논리 오류가 조용히 생긴다. 대응: 의도한 부작용은 미평가 문맥 밖의 별도 문장에서 수행한다.Rationale: the operands of sizeof, decltype, noexcept, and typeid (except a polymorphic glvalue) are unevaluated — only their type is inspected — so side effects inside (increment, call, assignment) do not run. Impact: assuming a side effect like i++ happened leaves counters/indices unchanged, silently introducing logic errors. Fix: perform intended side effects in a separate statement outside the unevaluated context.
EXP53-CPPEXP · Rule · L1✓ compilableSEI index
초기화되지 않은 메모리를 읽지 않는다Do not read uninitialized memory
❌ 위반 예시Non-compliant example
#include <iostream>
struct Point { int x; int y; };
int main() {
Point p; // 자동 저장 기간 — x, y 불확정
int sum = p.x + p.y; // 미초기화 멤버 읽기 — 미정의 동작
std::cout << sum << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
struct Point { int x = 0; int y = 0; }; // 기본 멤버 초기화
int main() {
Point p{3, 4};
int sum = p.x + p.y;
std::cout << sum << '\n';
}⚠️ 근거: 자동 저장 기간의 기본 타입·집합체는 명시 초기화가 없으면 불확정 값을 가지며, 그 값을 읽는 것은 미정의 동작이다. 영향: 디버그 빌드에서는 우연히 0 이 나오다가 릴리스에서 다른 값이 나오는 등 재현이 어려운 버그가 되고, 보안상 이전 스택 내용이 누출될 수 있다. 대응: 선언 시 기본 멤버 초기화나 중괄호 초기화로 모든 멤버를 사용 전에 초기화한다.Rationale: fundamental types and aggregates with automatic storage have indeterminate values without explicit initialization, and reading such a value is undefined behaviour. Impact: it may incidentally read 0 in a debug build but differ in release, producing hard-to-reproduce bugs and potentially leaking prior stack contents. Fix: initialize every member before use via default member initializers or brace initialization.
EXP54-CPPEXP · Rule · L1✓ compilableSEI index
수명이 끝난(out-of-lifetime) 객체에 접근하지 않는다Do not access an object outside of its lifetime
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
static const std::string& pick(bool b) {
std::string local = b ? "yes" : "no"; // 지역 객체
return local; // 소멸될 객체에 대한 참조 반환
}
int main() {
const std::string& r = pick(true); // r 는 이미 소멸된 객체를 가리킴
std::cout << r << '\n'; // 댕글링 참조 접근 — 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
static std::string pick(bool b) { // 값으로 반환
return b ? "yes" : "no";
}
int main() {
std::string s = pick(true); // 수명이 보장되는 객체에 보관
std::cout << s << '\n';
}⚠️ 근거: 지역 변수나 임시 객체의 수명이 끝난 뒤 그것을 가리키는 참조·포인터로 접근하는 것은 미정의 동작이다. 영향: 함수가 지역 객체의 참조를 반환하면 호출자는 이미 해제된 스택 메모리를 읽어 쓰레기 값·크래시·보안 취약점이 발생한다. 대응: 함수 밖에서 필요한 값은 값으로 반환하거나 수명이 호출자보다 긴 객체에 보관한다.Rationale: accessing an object through a reference or pointer after its lifetime has ended (local or temporary) is undefined behaviour. Impact: returning a reference to a local makes the caller read already-freed stack memory, producing garbage, crashes, or security vulnerabilities. Fix: return needed values by value or store them in an object whose lifetime outlives the caller.
EXP55-CPPEXP · Rule · L1✓ compilableSEI index
cv 한정(const/volatile) 객체를 비한정 타입으로 접근하지 않는다Do not access a cv-qualified object through a non-cv-qualified type
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
const int k = 5;
int& r = const_cast<int&>(k); // const 제거
r = 9; // 진짜 const 객체 수정 — 미정의 동작
std::cout << k << ' ' << r << '\n'; // 두 값이 어긋날 수 있음
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int k = 5; // 수정이 필요하면 처음부터 비-const 로 선언
k = 9;
std::cout << k << '\n';
}⚠️ 근거: 진짜로 const 로 정의된 객체를 const_cast 로 제거한 경로를 통해 수정하는 것은 미정의 동작이다(컴파일러가 const 객체를 상수 폴딩·읽기 전용 메모리에 둘 수 있기 때문). 영향: 수정이 무시되거나, 일부 플랫폼에서는 읽기 전용 페이지 쓰기로 크래시가 나며, 같은 객체의 두 읽기가 다른 값을 줄 수 있다. 대응: 수정이 필요한 객체는 처음부터 비-const 로 선언하고 const_cast 로 const 를 벗겨 쓰지 않는다.Rationale: modifying a truly const-defined object through a const_cast-stripped path is undefined behaviour, because the compiler may constant-fold it or place it in read-only memory. Impact: the write may be ignored, may crash on platforms that write-protect read-only pages, and two reads of the same object may differ. Fix: declare objects that need modification as non-const from the start and do not cast away const to write.
EXP56-CPPEXP · Rule · L1SEI index
언어 연결(language linkage)이 일치하지 않는 함수 포인터로 호출하지 않는다Do not call a function with a mismatched language linkage
❌ 위반 예시Non-compliant example
extern "C" void register_cb(void (*cb)()); // C 언어 연결의 콜백을 기대 void cpp_cb(); // 기본 C++ 언어 연결 // C 연결 포인터 자리에 C++ 연결 함수 전달 — 호출 규약 불일치(부적격) register_cb(cpp_cb);
✅ 준수 예시Compliant example
extern "C" void register_cb(void (*cb)()); extern "C" void c_cb(); // 콜백을 C 언어 연결로 선언 register_cb(c_cb); // 연결 일치
⚠️ 근거: 함수 타입의 언어 연결(extern "C" 대 C++)은 타입의 일부이며, 일부 ABI 에서는 연결에 따라 호출 규약·이름 맞춤이 달라진다. 영향: C 연결을 기대하는 자리에 C++ 연결 함수를 넘기면 호출 측과 피호출 측의 규약이 어긋나 인자 전달·스택 정리가 깨지는 미정의 동작이 될 수 있다. 대응: 경계를 넘나드는 콜백은 호출 측이 기대하는 언어 연결(보통 extern "C")로 선언해 연결을 일치시킨다.Rationale: the language linkage of a function type (extern "C" vs C++) is part of the type, and on some ABIs the calling convention or name mangling differs by linkage. Impact: passing a C++-linkage function where C linkage is expected can mismatch the conventions of caller and callee, breaking argument passing or stack cleanup — undefined behaviour. Fix: declare callbacks that cross boundaries with the language linkage the caller expects (usually extern "C") so the linkage matches.
EXP57-CPPEXP · Rule · L1SEI index
불완전(incomplete) 클래스 타입 포인터를 delete 하지 않는다Do not delete a pointer to an incomplete class type
❌ 위반 예시Non-compliant example
struct Impl; // 전방 선언만 — 불완전 타입
void release(Impl* p) {
delete p; // 소멸자·크기를 모른 채 delete — 소멸자 미호출(미정의)
}✅ 준수 예시Compliant example
#include <memory>
struct Impl;
void destroy(Impl*); // 완전 정의가 보이는 TU 에 정의
// PIMPL: 완전 정의가 보이는 곳에서만 삭제하거나 커스텀 deleter 사용
std::unique_ptr<Impl, void(*)(Impl*)> make() {
extern Impl* create();
return { create(), &destroy };
}⚠️ 근거: 클래스 정의가 보이지 않는(불완전) 타입의 포인터를 delete 하면 컴파일러가 소멸자와 정확한 크기를 알 수 없어, 표준은 소멸자 호출 여부를 미정의로 둔다. 영향: PIMPL 관용구에서 소멸자가 호출되지 않아 자원이 누수되고, 일부 컴파일러는 경고만 내고 통과시켜 발견이 늦어진다. 대응: 완전 정의가 보이는 번역단위에서 삭제하거나, unique_ptr 에 전용 deleter 를 지정한다.Rationale: deleting a pointer to a type whose definition is not visible (incomplete) leaves the compiler unable to know the destructor or exact size, so the standard makes calling the destructor undefined. Impact: in the PIMPL idiom the destructor is not called and resources leak, and some compilers only warn and let it pass, delaying discovery. Fix: delete in a translation unit where the full definition is visible, or give unique_ptr a dedicated deleter.
EXP58-CPPEXP · Rule · L1✓ compilableSEI index
va_start 에 올바른 타입의 객체를 전달한다Pass an object of the correct type to va_start
❌ 위반 예시Non-compliant example
#include <cstdarg>
#include <iostream>
#include <string>
// va_start 의 마지막 고정 매개변수가 참조형 — 미정의 동작
static void log(std::string& last, ...) {
va_list ap; va_start(ap, last); // last 가 참조형 → UB
va_end(ap);
std::cout << last << '\n';
}
int main() { std::string s = "tag"; log(s); }✅ 준수 예시Compliant example
#include <cstdarg>
#include <iostream>
// 마지막 고정 매개변수를 승격·참조 문제가 없는 적합한 타입으로
static long sum(int count, ...) {
va_list ap; va_start(ap, count); // count 는 int — 적합
long s = 0;
for (int i = 0; i < count; ++i) s += va_arg(ap, int);
va_end(ap);
return s;
}
int main() { std::cout << sum(3, 10, 20, 30) << '\n'; }⚠️ 근거: va_start 의 두 번째 인자(마지막 고정 매개변수)가 참조형이거나 register 저장, 함수/배열, 기본 인자 승격 대상 타입이면 표준은 그 동작을 미정의로 둔다(가변인자 영역의 시작 주소 계산이 보장되지 않음). 영향: 참조형을 넘기면 va_arg 추출 기준점이 어긋나 쓰레기 값을 읽거나 크래시가 나며, 플랫폼마다 다르게 깨진다. 대응: 가변인자 자체를 가변 템플릿으로 대체하는 것을 우선하고, C 가변인자가 불가피하면 마지막 고정 인자를 int 같은 적합한 값 타입으로 둔다.Rationale: if the second argument to va_start (the last fixed parameter) is a reference type, register storage, a function/array, or subject to default argument promotion, the standard leaves the behaviour undefined, since the start address of the variadic area is not guaranteed to be computable. Impact: passing a reference type makes the va_arg extraction baseline wrong, reading garbage or crashing, and breaking differently per platform. Fix: prefer replacing varargs with variadic templates, and when C varargs are unavoidable make the last fixed parameter a suitable value type such as int.
EXP59-CPPEXP · Rule · L1✓ compilableSEI index
offsetof 는 표준 레이아웃 타입의 유효한 멤버에만 사용한다Use offsetof() on valid types and members
❌ 위반 예시Non-compliant example
#include <cstddef>
#include <iostream>
struct WithVtbl { // 가상 함수 보유 — 비표준 레이아웃
virtual void f() {}
int m;
};
int main() {
std::size_t o = offsetof(WithVtbl, m); // 비표준 레이아웃에 offsetof — 조건부 지원/미정의
std::cout << o << '\n'; // vptr 때문에 의미가 불분명한 값
}✅ 준수 예시Compliant example
#include <cstddef>
#include <iostream>
struct PlainData { // 가상 없음, 단일 접근 — 표준 레이아웃
int a;
int m;
};
int main() {
std::size_t o = offsetof(PlainData, m); // 표준 레이아웃의 비정적 멤버 — 유효
std::cout << o << '\n';
}⚠️ 근거: offsetof 는 표준 레이아웃(standard-layout) 타입의 비정적 데이터 멤버에 대해서만 정의되며, 가상 함수·가상 기반·혼합 접근 지정 등으로 비표준 레이아웃이 된 타입에 쓰면 조건부 지원이거나 미정의 동작이다. 영향: 숨은 vptr 이나 컴파일러가 자유롭게 정하는 배치 때문에 반환 오프셋이 무의미해져, 그 값으로 메모리를 직접 인덱싱하면 잘못된 위치에 접근한다. 대응: offsetof 는 표준 레이아웃 타입의 실제 멤버에만 사용하고, 필요하면 static_assert(std::is_standard_layout_v<T>) 로 보증한다.Rationale: offsetof is defined only for non-static data members of a standard-layout type, and using it on a type made non-standard-layout by virtual functions, virtual bases, or mixed access specifiers is conditionally-supported or undefined. Impact: a hidden vptr or compiler-chosen layout makes the returned offset meaningless, so indexing memory with that value accesses the wrong location. Fix: use offsetof only on real members of standard-layout types, asserting it with static_assert(std::is_standard_layout_v<T>) when needed.
EXP60-CPPEXP · Rule · L2✓ compilableSEI index
비표준 레이아웃(non-standard-layout) 객체를 실행 경계 너머로 전달하지 않는다Do not pass a nonstandard-layout type object across execution boundaries
❌ 위반 예시Non-compliant example
#include <iostream>
#include <type_traits>
struct Mixed { // private/public 혼합 — 멤버 순서 배치 미보장
private: int a;
public: int b;
Mixed(int x, int y): a(x), b(y) {}
int sum() const { return a + b; }
};
// C 등 다른 경계 코드가 {int,int} 라고 가정하고 접근하면 a/b 순서가 어긋날 수 있음
int main() {
std::cout << std::boolalpha << std::is_standard_layout<Mixed>::value << '\n'; // false
}✅ 준수 예시Compliant example
#include <iostream>
#include <type_traits>
struct Flat { // 단일 접근 지정 — 표준 레이아웃, 멤버 순서 보장
int a;
int b;
};
int main() {
static_assert(std::is_standard_layout<Flat>::value, "must be standard-layout");
std::cout << std::boolalpha << std::is_standard_layout<Flat>::value << '\n'; // true
}⚠️ 근거: 접근 지정자가 섞이거나 가상 기능이 있는 비표준 레이아웃 타입은 멤버의 상대적 메모리 배치가 표준으로 보장되지 않아 컴파일러가 자유롭게 재배치할 수 있다. 영향: 이런 타입을 C 코드·다른 컴파일러·디스크/네트워크 포맷 같은 실행 경계 밖으로 그대로 넘기면, 받는 쪽이 가정한 오프셋과 실제 배치가 달라 잘못된 필드를 읽는 손상이 발생한다. 대응: 경계를 넘는 타입은 단일 접근 지정·가상 없음으로 표준 레이아웃을 보장하고 static_assert 로 검증한다.Rationale: a non-standard-layout type with mixed access specifiers or virtual features has no standardized relative memory layout of members, so the compiler may reorder them freely. Impact: passing such a type as-is across an execution boundary (C code, another compiler, an on-disk/network format) makes the receiver assume offsets that differ from the actual layout, reading the wrong field and corrupting data. Fix: ensure types that cross boundaries are standard-layout (single access specifier, no virtuals) and verify with static_assert.
EXP61-CPPEXP · Rule · L2✓ compilableSEI index
람다 객체가 캡처한 참조보다 오래 살지 않게 한다A lambda object must not outlive any of its reference-captured objects
❌ 위반 예시Non-compliant example
#include <iostream>
#include <functional>
static std::function<int()> make() {
int local = 42;
return [&]{ return local; }; // 참조 캡처 — local 은 함수 종료 시 소멸
}
int main() {
auto f = make();
std::cout << f() << '\n'; // 댕글링 참조 접근 — 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
#include <functional>
static std::function<int()> make() {
int local = 42;
return [local]{ return local; }; // 값 캡처 — 람다가 사본 소유
}
int main() {
auto f = make();
std::cout << f() << '\n'; // 42
}⚠️ 근거: 참조로 캡처한 변수는 람다 안에 포인터처럼 보관되므로, 그 변수가 람다보다 먼저 소멸하면 람다 내부 참조는 댕글링이 된다. 영향: 함수가 지역 변수를 참조 캡처한 람다(또는 std::function)를 반환하면 호출 시점에 해제된 스택을 읽어 쓰레기 값·크래시가 난다. 대응: 람다보다 수명이 짧을 수 있는 대상은 값으로 캡처하거나, 공유 수명이 필요하면 shared_ptr 를 캡처한다.Rationale: a reference-captured variable is held like a pointer inside the lambda, so if it is destroyed before the lambda its captured reference dangles. Impact: returning a lambda (or std::function) that reference-captures a local makes the call read freed stack, yielding garbage or a crash. Fix: capture by value anything that may be shorter-lived than the lambda, or capture a shared_ptr when shared lifetime is needed.
EXP62-CPPEXP · Rule · L2✓ compilableSEI index
객체 값에 속하지 않는 표현(representation) 비트에 접근하지 않는다Do not access the bits of an object representation that are not part of the value representation
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstring>
struct S { char c; int v; }; // c 와 v 사이 패딩(값에 속하지 않는 비트)
static std::size_t bad_hash(const S& s) {
const unsigned char* p = reinterpret_cast<const unsigned char*>(&s);
std::size_t h = 0;
for (std::size_t i = 0; i < sizeof s; ++i) h = h * 131 + p[i]; // 패딩까지 해시
return h;
}
int main() {
S a; // a 의 패딩은 불확정(이전 스택 값)
std::memset(&a, 0xFF, sizeof a); // 패딩을 0xFF 로 오염시킨 뒤
a.c = 'x'; a.v = 7; // 멤버만 설정 — 패딩엔 0xFF 잔존
S b{}; // b 의 패딩은 0
b.c = 'x'; b.v = 7; // 같은 논리 값
std::cout << std::boolalpha
<< (bad_hash(a) == bad_hash(b)) << '\n'; // 값이 같아도 false 가능
}✅ 준수 예시Compliant example
#include <iostream>
#include <functional>
struct S { char c; int v; };
static std::size_t good_hash(const S& s) {
std::size_t h = std::hash<char>{}(s.c); // 값 멤버만 결합
h ^= std::hash<int>{}(s.v) + 0x9e3779b9 + (h << 6) + (h >> 2);
return h;
}
int main() {
S a{'x', 7}, b{'x', 7};
std::cout << std::boolalpha << (good_hash(a) == good_hash(b)) << '\n'; // 항상 true
}⚠️ 근거: 객체의 표현 비트 중 패딩 같은 부분은 값(value)에 속하지 않아 불확정 상태일 수 있고, 같은 논리적 값을 가진 두 객체라도 그 비트는 다를 수 있다. 영향: reinterpret_cast 로 객체를 바이트열로 보고 전체를 해시·비교하면, 값이 같은데도 패딩 차이로 해시·비교 결과가 달라져 컨테이너 조회 실패·비결정적 동작이 생긴다. 대응: 해시·동등 비교는 의미 있는 값 멤버만을 결합해 계산하고, 객체 전체 바이트열에 의존하지 않는다.Rationale: some object-representation bits, such as padding, are not part of the value and may be indeterminate, so two objects with the same logical value can still differ in those bits. Impact: reinterpret_cast-ing an object to a byte array and hashing or comparing the whole thing makes equal values produce different hash/compare results due to padding, causing container lookup failures and nondeterministic behaviour. Fix: compute hashes and equality from the meaningful value members only, never relying on the full object byte representation.
EXP63-CPPEXP · Rule · L2✓ compilableSEI index
이동된(moved-from) 객체의 값에 의존하지 않는다Do not rely on the value of a moved-from object
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
#include <utility>
int main() {
std::string a = "payload";
std::string b = std::move(a); // a 는 유효하나 값은 미지정
std::cout << "len=" << a.size() << '\n'; // 미지정 상태에 의존 — 비결정적
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
#include <utility>
int main() {
std::string a = "payload";
std::string b = std::move(a);
a = "reset"; // 재사용 전 명확히 재설정
std::cout << "len=" << a.size() << '\n'; // 5
}⚠️ 근거: 표준 라이브러리 타입은 이동 후 "유효하지만 미지정(valid but unspecified)" 상태가 되어, 소멸·재대입은 안전하지만 구체적 값(길이·내용)은 보장되지 않는다. 영향: 이동된 객체의 값을 읽어 계산·분기하면 구현·최적화에 따라 결과가 달라지는 비결정적 버그가 된다. 대응: 이동된 객체는 다시 대입하거나 clear() 등으로 명확한 상태로 만든 뒤에만 재사용한다.Rationale: standard-library types are left "valid but unspecified" after a move — destruction and reassignment are safe, but the concrete value (size, contents) is not guaranteed. Impact: reading the value of a moved-from object to compute or branch yields nondeterministic bugs that vary by implementation/optimization. Fix: reuse a moved-from object only after putting it in a known state, e.g. reassigning or calling clear().
ERR오류 처리Error Handling
ERR62-CPPERR · Rule · L1✓ compilableSEI index
문자열을 숫자로 변환할 때 오류를 검출한다Detect errors when converting a string to a number
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdlib>
#include <string>
int main() {
std::string s = "12abc";
int n = std::atoi(s.c_str()); // 변환 실패와 정상 0 을 구분 못함, 범위초과 미검출
std::cout << n << '\n'; // 12 — 뒤의 'abc' 가 조용히 무시됨
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
#include <stdexcept>
int main() {
std::string s = "12abc";
try {
std::size_t pos;
int n = std::stoi(s, &pos); // 범위초과 시 out_of_range, 무변환 시 invalid_argument
if (pos != s.size()) throw std::invalid_argument("trailing chars");
std::cout << n << '\n';
} catch (const std::exception& e) { std::cout << "convert error: " << e.what() << '\n'; }
}⚠️ 근거: atoi 는 변환 실패 시 0 을 반환할 뿐 오류 신호가 없고, 변환을 멈춘 위치도 알려주지 않으며 범위 초과를 미정의 동작으로 둔다. 영향: "0" 과 변환 실패가 구분되지 않고 "12abc" 처럼 일부만 변환된 입력이 조용히 통과해, 잘못된 수치가 계산·인덱스로 흘러든다. 대응: std::stoi/stol 을 쓰고 예외와 변환 종료 위치(pos)를 검사해 전체 문자열이 정확히 소비됐는지 확인한다.Rationale: atoi merely returns 0 on failure with no error signal, does not report where conversion stopped, and leaves out-of-range as undefined behaviour. Impact: "0" is indistinguishable from a failure and partially converted input like "12abc" passes silently, letting a wrong number flow into computations or indices. Fix: use std::stoi/stol and check both exceptions and the end position (pos) to confirm the whole string was consumed exactly.
ERR50-CPPERR · Rule · L3✓ compilableSEI index
프로그램을 비정상적으로 종료(abort/terminate)시키지 않는다Do not abruptly terminate the program
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdlib>
struct Logger { ~Logger(){ std::cout << "flush log\n"; } }; // 정리 작업
static void handle(int code, int argc) {
Logger lg;
if (code != 0) {
if (argc >= 0) std::abort(); // 소멸자·정리 건너뛰고 즉시 종료(가드: 항상 참)
}
}
int main(int argc, char**) { handle(1, argc); }✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct Logger { ~Logger(){ std::cout << "flush log\n"; } };
static void handle(int code) {
Logger lg;
if (code != 0) throw std::runtime_error("bad state"); // 스택 풀기로 정리됨
}
int main() {
try { handle(1); }
catch (const std::exception& e) { std::cout << "handled: " << e.what() << '\n'; }
}⚠️ 근거: std::abort 와 std::terminate 는 스택 풀기를 수행하지 않으므로 활성 자동 객체의 소멸자가 호출되지 않는다. 영향: 열린 파일·획득한 잠금·버퍼에 모인 로그 같은 자원이 정리되지 않아 데이터 손상·누수·일관성 깨짐이 남는다. 대응: 오류는 예외로 전달해 정상적인 스택 풀기로 소멸자가 실행되게 하고, 최상위에서 포착해 정의된 방식으로 종료한다.Rationale: std::abort and std::terminate do not perform stack unwinding, so destructors of active automatic objects are not run. Impact: resources such as open files, acquired locks, and buffered logs are left uncleaned, causing data corruption, leaks, and broken consistency. Fix: signal errors with exceptions so normal unwinding runs destructors, and catch at the top level to terminate in a defined way.
ERR51-CPPERR · Rule · L3✓ compilableSEI index
모든 예외를 처리한다Handle all exceptions
❌ 위반 예시Non-compliant example
#include <stdexcept>
static void run(int argc) {
if (argc >= 0) throw std::runtime_error("boom"); // 가드: 항상 참
}
int main(int argc, char**) {
run(argc); // 예외가 main 밖으로 — std::terminate
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
static void run() { throw std::runtime_error("boom"); }
int main() {
try { run(); }
catch (const std::exception& e) { std::cout << "err: " << e.what() << '\n'; return 1; }
catch (...) { std::cout << "unknown error\n"; return 1; }
}⚠️ 근거: main 밖으로 빠져나온, 즉 어떤 핸들러도 잡지 않은 예외는 std::terminate 를 호출하며, 이때 스택 풀기 수행 여부조차 구현 정의라 소멸자가 실행되지 않을 수 있다. 영향: 진단 메시지 없이 비정상 종료되어 오류 원인 파악이 어렵고, 정리 누락으로 자원이 남는다. 대응: 최상위(main 또는 스레드 진입점)에서 std::exception 과 catch(...) 로 모든 예외를 포착해 로깅·정의된 종료 코드로 처리한다.Rationale: an exception that escapes main — caught by no handler — calls std::terminate, and whether stack unwinding even occurs is implementation-defined, so destructors may not run. Impact: the program aborts with no diagnostic, making the cause hard to find, and leaves resources due to missed cleanup. Fix: at the top level (main or a thread entry point) catch all exceptions with std::exception and catch(...), logging and exiting with a defined code.
ERR52-CPPERR · Rule · L1✓ compilableSEI index
예외 대신 setjmp/longjmp 를 사용하지 않는다Do not use setjmp() or longjmp()
❌ 위반 예시Non-compliant example
#include <csetjmp>
#include <iostream>
static std::jmp_buf env;
struct Guard { ~Guard(){ std::cout << "cleanup\n"; } }; // longjmp 시 호출 안 됨
static void work() {
Guard g;
std::longjmp(env, 1); // g 소멸자 건너뜀 — 자원 누수
}
int main() {
if (setjmp(env) == 0) work();
else std::cout << "recovered\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct Guard { ~Guard(){ std::cout << "cleanup\n"; } };
static void work() {
Guard g;
throw std::runtime_error("fail"); // 예외 — 스택 풀기로 g 정상 소멸
}
int main() {
try { work(); }
catch (const std::exception&) { std::cout << "recovered\n"; }
}⚠️ 근거: longjmp 는 C 의 비지역 점프로, 스택을 되감을 때 그 사이에 살아 있던 C++ 자동 객체의 소멸자를 전혀 호출하지 않는다. 영향: 잠금·메모리·파일을 RAII 로 관리하던 객체가 정리되지 않아 누수·교착이 발생하고, 비trivial 객체가 있는 스코프를 건너뛰는 longjmp 자체가 미정의 동작이다. 대응: 오류 복구는 예외 처리(throw/catch)로 구현해 소멸자가 항상 실행되게 한다.Rationale: longjmp is C non-local jump that, when rewinding the stack, does not call destructors of any C++ automatic objects that were alive in between. Impact: objects managing locks, memory, or files via RAII are not cleaned up, causing leaks or deadlock, and a longjmp that skips a scope containing non-trivial objects is itself undefined behaviour. Fix: implement error recovery with exception handling (throw/catch) so destructors always run.
ERR53-CPPERR · Rule · L1✓ compilableSEI index
생성자/소멸자 function-try-block 핸들러에서 멤버·기반을 참조하지 않는다Do not reference base classes or class data members in a constructor or destructor function-try-block handler
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
struct Resource { int id = 0; Resource(){ throw std::runtime_error("init"); } };
struct Widget {
Resource r;
Widget()
try : r() {}
catch (...) {
std::cout << "id=" << r.id << '\n'; // 핸들러 도달 시 r 은 이미 소멸 — 미정의 접근
throw;
}
};
int main() {
try { Widget w; } catch (...) { std::cout << "ctor failed\n"; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct Resource { int id = 0; Resource(){ throw std::runtime_error("init"); } };
struct Widget {
Resource r;
Widget()
try : r() {}
catch (...) {
std::cout << "ctor failed, logging only\n"; // 멤버 미참조
throw; // 생성자 function-try-block 은 반드시 예외로 끝나야 함
}
};
int main() {
try { Widget w; } catch (...) { std::cout << "handled\n"; }
}⚠️ 근거: 생성자의 function-try-block 핸들러는 멤버나 기반 클래스의 생성이 실패했거나 이미 풀린(소멸된) 뒤에 진입하므로, 그 시점에 멤버·기반 객체는 더 이상 존재하지 않는다. 영향: 핸들러에서 멤버를 읽거나 쓰면 수명이 끝난 객체에 접근하는 미정의 동작이 되어 쓰레기 값·크래시가 난다. 또한 이 핸들러는 정상 반환할 수 없어 반드시 예외를 다시 던지거나 새로 던져야 한다. 대응: 핸들러에서는 멤버를 참조하지 말고 로깅 등 멤버 독립적 작업만 한 뒤 예외를 전파한다.Rationale: a constructor function-try-block handler is entered after a member or base class either failed to construct or has already been unwound (destroyed), so those subobjects no longer exist at that point. Impact: reading or writing a member in the handler accesses an out-of-lifetime object — undefined behaviour yielding garbage or a crash — and the handler cannot return normally, so it must rethrow or throw anew. Fix: in the handler do only member-independent work such as logging, then propagate the exception, without referencing members.
ERR54-CPPERR · Rule · L2✓ compilableSEI index
catch 핸들러는 가장 파생된 것부터 기본 순으로 배치한다Catch handlers should order their parameter types from most derived to least derived
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
int main() {
try { throw std::runtime_error("io"); }
catch (const std::exception& e) { // 기반 핸들러 먼저 — 파생도 여기서 잡힘
std::cout << "generic: " << e.what() << '\n';
}
catch (const std::runtime_error& e) { // 도달 불가 — 컴파일러 경고
std::cout << "specific: " << e.what() << '\n';
}
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
int main() {
try { throw std::runtime_error("io"); }
catch (const std::runtime_error& e) { // 파생(구체적) 먼저
std::cout << "specific: " << e.what() << '\n';
}
catch (const std::exception& e) { // 기반(일반) 나중
std::cout << "generic: " << e.what() << '\n';
}
}⚠️ 근거: catch 핸들러는 선언된 순서대로 검사되며, 던져진 예외의 타입과 호환되는 첫 핸들러가 선택된다(가상 디스패치가 아니라 순차 매칭). 영향: 기반 클래스 핸들러를 먼저 두면 모든 파생 예외가 거기서 잡혀, 뒤에 둔 더 구체적인 핸들러는 영영 도달하지 못해 의도한 세분화된 처리가 사라진다. 대응: 핸들러를 가장 파생된 타입부터 기반 타입 순으로 배치한다.Rationale: catch handlers are examined in declaration order, and the first one compatible with the thrown exception type is chosen (sequential matching, not virtual dispatch). Impact: placing a base-class handler first catches all derived exceptions there, so a more specific handler placed afterwards is never reached and the intended fine-grained handling is lost. Fix: order handlers from the most derived type down to the base type.
ERR55-CPPERR · Rule · L1✓ compilableSEI index
예외 명세(noexcept)를 준수한다Honor exception specifications
❌ 위반 예시Non-compliant example
#include <stdexcept>
static void may_throw(int argc) {
if (argc >= 0) throw std::runtime_error("x"); // 가드: 항상 참
}
static void f(int argc) noexcept {
may_throw(argc); // noexcept 함수에서 예외가 빠져나감 → std::terminate
}
int main(int argc, char**) { f(argc); }✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
static void may_throw() { throw std::runtime_error("x"); }
static void f() noexcept {
try { may_throw(); }
catch (...) { std::cout << "absorbed in noexcept fn\n"; } // 명세 준수
}
int main() { f(); }⚠️ 근거: noexcept 로 선언한 함수에서 예외가 빠져나가면 표준은 즉시 std::terminate 를 호출하도록 규정한다(되돌릴 수 없음). 영향: 호출자가 noexcept 를 믿고 예외 처리를 생략한 상태에서 프로그램이 정리 없이 강제 종료된다. 대응: noexcept 함수 내부에서 예외를 try/catch 로 흡수하거나, 예외가 빠져나갈 수 있으면 noexcept 를 떼어 명세를 사실에 맞춘다.Rationale: if an exception escapes a function declared noexcept, the standard mandates an immediate, unrecoverable call to std::terminate. Impact: callers that trusted noexcept and omitted handling see the program forcibly terminated without cleanup. Fix: absorb exceptions inside the noexcept function with try/catch, or remove noexcept so the specification matches reality if exceptions can escape.
ERR56-CPPERR · Rule · L2✓ compilableSEI index
예외 안전성(exception safety)을 보장한다Guarantee exception safety
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
struct Node { int v; Node* clone() const { throw std::runtime_error("oom"); } };
struct Holder {
Node* cur = nullptr;
void set(const Node& n) {
delete cur; // 먼저 기존 것을 해제
cur = n.clone(); // clone 이 던지면 cur 는 해제된 댕글링 상태로 남음
}
};
int main() {
Holder h; Node a{1};
try { h.set(a); } catch (...) { std::cout << "cur is dangling now\n"; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct Node { int v; Node* clone() const { return new Node{v}; } };
struct Holder {
Node* cur = nullptr;
~Holder(){ delete cur; }
void set(const Node& n) {
Node* tmp = n.clone(); // 먼저 성공시키고(던질 수 있는 작업 선행)
delete cur; // 그 다음에만 상태 교체
cur = tmp;
}
};
int main() {
Holder h; Node a{1};
h.set(a);
std::cout << "value=" << h.cur->v << '\n';
}⚠️ 근거: 던질 수 있는 연산을 상태 변경의 중간에 두면, 예외 발생 시 객체가 일부만 갱신된 깨진 상태로 남는다. 영향: 예제처럼 기존 포인터를 먼저 해제하고 clone 이 던지면 cur 는 이미 해제된 메모리를 가리키는 댕글링이 되어 이후 접근이 use-after-free 가 된다. 대응: 던질 수 있는 작업을 임시 변수로 먼저 완성한 뒤, 던지지 않는 연산(swap/대입)으로 상태를 교체하는 강한 예외 보장(strong guarantee) 패턴을 쓴다.Rationale: placing a throwing operation in the middle of a state change leaves the object in a broken, partially updated state if an exception occurs. Impact: as in the example, freeing the existing pointer first and having clone throw leaves cur dangling at freed memory, so later access is a use-after-free. Fix: complete the throwing work into a temporary first, then swap or assign with a non-throwing operation — the strong-guarantee pattern.
ERR57-CPPERR · Rule · L2✓ compilableSEI index
예외 처리 중 자원을 누수하지 않는다Do not leak resources when handling exceptions
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
static void risky(int argc) { if (argc >= 0) throw std::runtime_error("boom"); }
static void f(int argc) {
int* buf = new int[100]; // raw 자원
risky(argc); // 예외 발생 시 아래 delete[] 를 건너뜀 → 누수
delete[] buf;
}
int main(int argc, char**) {
try { f(argc); } catch (...) { std::cout << "leaked buf\n"; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
#include <stdexcept>
static void risky() { throw std::runtime_error("boom"); }
static void f() {
auto buf = std::make_unique<int[]>(100); // RAII — 예외에도 자동 해제
risky();
}
int main() {
try { f(); } catch (...) { std::cout << "no leak (RAII freed)\n"; }
}⚠️ 근거: new 로 얻은 raw 자원을 보유한 채 그 뒤 코드에서 예외가 발생하면, 대응하는 delete 문장이 실행되지 않고 스택이 풀려 누수가 발생한다. 영향: 예외 경로가 반복되면 메모리·핸들이 점진적으로 고갈되어 장시간 구동 서비스가 불안정해진다. 대응: 모든 자원을 RAII 객체(unique_ptr, lock_guard, fstream)에 담아 예외로 스택이 풀릴 때 소멸자가 자동 해제하게 한다.Rationale: holding a raw resource from new while later code throws means the matching delete statement never executes as the stack unwinds, leaking the resource. Impact: repeated exception paths progressively exhaust memory and handles, destabilizing long-running services. Fix: hold every resource in an RAII object (unique_ptr, lock_guard, fstream) so destructors free it automatically during unwinding.
ERR58-CPPERR · Rule · L3✓ compilableSEI index
main 시작 전에 던져지는 예외를 처리한다Handle all exceptions thrown before main() begins executing
❌ 위반 예시Non-compliant example
#include <stdexcept>
struct Config { Config(){ throw std::runtime_error("cfg load failed"); } };
static Config g_cfg; // 정적 초기화 중 예외 — main 이전이라 포착 불가 → terminate
int main() { return 0; }✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct Config { int v = 0; Config(){ throw std::runtime_error("cfg load failed"); } };
static Config& cfg() {
static Config c; // 최초 호출 시 초기화 — main 안에서 try 로 포착 가능
return c;
}
int main() {
try { (void)cfg(); }
catch (const std::exception& e) { std::cout << "handled: " << e.what() << '\n'; }
}⚠️ 근거: 네임스페이스 범위 전역/정적 객체의 생성자는 main 진입 전에 실행되므로, 거기서 던진 예외를 감쌀 try 블록을 둘 수 없어 곧장 std::terminate 로 간다. 영향: 설정 로딩·자원 획득 실패가 진단 없는 비정상 종료가 되어 원인 파악과 우아한 실패 처리가 불가능하다. 대응: 무거운 초기화는 함수 내 지역 static(최초 사용 시 초기화)으로 미뤄, main 안의 제어 가능한 시점에서 try/catch 로 처리한다.Rationale: constructors of namespace-scope global/static objects run before main begins, so there is no enclosing try block for an exception they throw, and it goes straight to std::terminate. Impact: a failed config load or resource acquisition becomes an abort with no diagnostic, making diagnosis and graceful failure impossible. Fix: defer heavy initialization to a function-local static (initialized on first use) so it can be handled with try/catch at a controlled point inside main.
ERR59-CPPERR · Rule · L1✓ compilableSEI index
예외를 실행 경계(언어 경계 등) 너머로 던지지 않는다Do not throw an exception across execution boundaries
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
// C 호출자가 부를 수 있는 인터페이스인데 예외를 경계 밖으로 던짐
extern "C" void c_api(int x) {
if (x < 0) throw std::runtime_error("negative"); // C 경계 밖으로 — 미정의
}
int main() {
try { c_api(-1); } catch (...) { std::cout << "only safe because caller is C++\n"; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
// 경계 내부에서 모든 예외를 포착해 오류 코드로 변환
extern "C" int c_api(int x) {
try {
if (x < 0) throw std::runtime_error("negative");
return 0;
} catch (...) { return -1; } // 예외를 경계 밖으로 내보내지 않음
}
int main() {
std::cout << "rc=" << c_api(-1) << '\n'; // rc=-1
}⚠️ 근거: C 함수 인터페이스나 스레드 진입점, 콜백 같은 실행 경계는 C++ 예외 전파 메커니즘을 이해하지 못하므로, 예외가 그 경계를 넘어 전파되면 표준은 미정의 동작(대개 std::terminate)으로 둔다. 영향: C 코드가 호출한 함수에서 예외가 빠져나가면 스택 풀기가 C 프레임에서 깨져 프로그램이 정리 없이 강제 종료된다. 대응: 경계로 노출되는 모든 함수는 내부에서 catch(...) 로 예외를 포착해 반환 코드·에러 객체 같은 경계가 이해하는 형태로 변환한다.Rationale: execution boundaries such as a C function interface, a thread entry point, or a callback do not understand the C++ exception propagation mechanism, so the standard makes an exception propagating across such a boundary undefined behaviour (usually std::terminate). Impact: if an exception escapes a function called from C code, stack unwinding breaks at the C frame and the program is forcibly terminated without cleanup. Fix: have every boundary-exposed function catch exceptions internally with catch(...) and translate them into a form the boundary understands, such as a return code or error object.
ERR60-CPPERR · Rule · L2✓ compilableSEI index
예외 객체는 nothrow 복사 생성 가능해야 한다Exception objects must be nothrow-copy-constructible
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
struct HeavyError {
std::string detail; // 복사 시 힙 할당 — 복사가 던질 수 있음
explicit HeavyError(std::string d) : detail(std::move(d)) {}
};
int main() {
try { throw HeavyError("disk full at sector 42"); }
catch (const HeavyError& e) { std::cout << e.detail << '\n'; }
}✅ 준수 예시Compliant example
#include <iostream>
struct LightError {
const char* msg; // 복사가 noexcept(포인터 복사뿐)
explicit LightError(const char* m) noexcept : msg(m) {}
};
int main() {
try { throw LightError("disk full at sector 42"); }
catch (const LightError& e) { std::cout << e.msg << '\n'; }
}⚠️ 근거: 예외 객체는 던지고 잡는 과정에서 구현이 복사·이동할 수 있는데, 그 복사 생성자가 또 예외를 던지면(예: std::string 복사 중 메모리 부족) 예외 처리 도중 새 예외가 발생해 std::terminate 로 간다. 영향: 정작 오류를 알리려던 예외가 전파 중 복사 실패로 프로그램을 강제 종료시켜, 진단조차 남기지 못하는 최악의 시점에 죽는다. 대응: 예외 타입은 복사·이동이 noexcept 가 되도록 설계하고(예: 동적 할당 멤버 대신 고정 버퍼·리터럴 포인터·참조 카운트 문자열), 풍부한 정보가 필요하면 표준 예외처럼 내부적으로 nothrow 복사를 보장하는 형태를 쓴다.Rationale: an exception object may be copied or moved by the implementation while being thrown and caught, and if that copy constructor itself throws (e.g. out of memory while copying a std::string), a new exception arises during handling and goes to std::terminate. Impact: the very exception meant to report an error kills the program due to a copy failure during propagation, dying at the worst moment with no diagnostic. Fix: design exception types so copy/move is noexcept (e.g. a fixed buffer, literal pointer, or reference-counted string instead of a dynamically allocating member), using forms that guarantee nothrow copy internally when rich information is needed.
ERR61-CPPERR · Rule · L3✓ compilableSEI index
예외는 lvalue 참조로 catch 한다Catch exceptions by lvalue reference
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
struct AppError : std::runtime_error {
int code;
AppError(const char* m, int c) : std::runtime_error(m), code(c) {}
};
int main() {
try { throw AppError("disk", 42); }
catch (std::runtime_error e) { // 값 catch — AppError 의 code 가 슬라이싱됨
std::cout << e.what() << '\n'; // code 정보 손실
}
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct AppError : std::runtime_error {
int code;
AppError(const char* m, int c) : std::runtime_error(m), code(c) {}
};
int main() {
try { throw AppError("disk", 42); }
catch (const AppError& e) { // 참조 catch — 파생 정보·다형성 보존
std::cout << e.what() << " code=" << e.code << '\n';
}
}⚠️ 근거: 예외를 값으로 잡으면 던져진 객체가 핸들러 매개변수 타입으로 복사되며, 그 타입이 기반 클래스면 파생 부분이 잘려 나간다(slicing). 영향: 파생 예외가 담은 오류 코드·문맥 정보와 다형적 what() 동작을 잃어 진단 정보가 사라지고, 복사 비용도 든다. 대응: 예외는 const lvalue 참조로 잡아 복사·슬라이싱 없이 실제 동적 타입의 정보를 보존한다.Rationale: catching an exception by value copies the thrown object into the handler parameter type, and if that type is a base class the derived part is sliced off. Impact: the error code, context, and polymorphic what() behaviour carried by the derived exception are lost, discarding diagnostic information and incurring a copy. Fix: catch by const lvalue reference to preserve the actual dynamic type information without a copy or slicing.
INT정수Integers
INT50-CPPINT · Rule · L1✓ compilableSEI index
열거형의 범위를 벗어난 값으로 캐스트하지 않는다Do not cast to an out-of-range enumeration value
❌ 위반 예시Non-compliant example
#include <iostream>
enum class Color { Red, Green, Blue }; // 유효 값 0,1,2
static const char* name(Color c) {
switch (c) { case Color::Red: return "red";
case Color::Green: return "green";
case Color::Blue: return "blue"; }
return "?";
}
int main() {
Color c = static_cast<Color>(7); // 범위 밖 값 — 미지정 동작
std::cout << name(c) << '\n'; // switch 가 어떤 분기도 못 타거나 오동작
}✅ 준수 예시Compliant example
#include <iostream>
enum class Color { Red, Green, Blue };
static bool to_color(int raw, Color& out) {
if (raw < 0 || raw > 2) return false; // 캐스트 전 범위 검사
out = static_cast<Color>(raw);
return true;
}
int main() {
Color c;
if (to_color(7, c)) std::cout << "ok\n";
else std::cout << "rejected out-of-range\n";
}⚠️ 근거: 고정 기반 타입이 없는 enum 의 유효 값 집합은 열거자들을 표현하는 데 필요한 최소 비트 폭으로 정해지며, 그 범위를 벗어난 정수를 캐스트하면 미지정(또는 미정의) 값이 된다. 영향: 그런 값은 switch 의 어떤 case 에도 해당하지 않아 기본 처리가 누락되거나, 값 기반 분기·배열 인덱스로 쓰일 때 범위를 넘는 접근으로 이어진다. 대응: 외부에서 받은 정수는 유효 범위를 검사한 뒤에만 enum 으로 캐스트한다.Rationale: for an enum without a fixed underlying type, the set of valid values is determined by the minimum bit width needed to represent its enumerators, and casting an integer outside that range yields an unspecified (or undefined) value. Impact: such a value matches no switch case so default handling is missed, and when used for value-based branching or as an array index it leads to out-of-range access. Fix: cast an externally supplied integer to the enum only after checking it is within the valid range.
FIO입출력Input/Output
FIO51-CPPFIO · Rule · L2✓ compilableSEI index
더 이상 필요 없는 파일은 닫는다Close files when they are no longer needed
❌ 위반 예시Non-compliant example
#include <cstdio>
static void process(int argc) {
for (int i = 0; i < argc; ++i) {
std::FILE* f = std::fopen("data.bin", "r"); // 매 반복 열기, fclose 누락
if (f) { char b[4]; (void)std::fread(b, 1, 4, f); } // 핸들 누수
}
}
int main(int argc, char**) { process(argc); }✅ 준수 예시Compliant example
#include <iostream>
#include <fstream>
static void process(int argc) {
for (int i = 0; i < argc; ++i) {
std::ifstream f("data.bin"); // RAII — 스코프 종료 시 자동 close
char b[4]; f.read(b, 4);
}
}
int main(int argc, char**) { process(argc); std::cout << "done\n"; }⚠️ 근거: 운영체제는 프로세스당 열 수 있는 파일 디스크립터 수에 한계를 두는데, 연 파일을 닫지 않으면 디스크립터가 회수되지 않고 쌓인다. 영향: 루프·장시간 구동에서 디스크립터가 고갈되면 이후 열기·소켓 생성이 모두 실패해 서비스가 마비되고, 버퍼가 flush 되지 않아 데이터가 유실될 수 있다. 대응: RAII 스트림(ifstream/ofstream)을 사용해 스코프 종료 시 자동으로 닫히게 하거나, 수동 FILE* 는 모든 경로에서 fclose 를 보장한다.Rationale: the operating system caps the number of file descriptors per process, and not closing opened files leaves descriptors unreclaimed and accumulating. Impact: in loops or long-running services, exhausting descriptors makes all subsequent opens and socket creations fail, paralyzing the service, and unflushed buffers can lose data. Fix: use RAII streams (ifstream/ofstream) that close automatically at end of scope, or guarantee fclose on every path for a manual FILE*.
FIO50-CPPFIO · Rule · L2✓ compilableSEI index
위치 지정 없이 입력과 출력을 번갈아 하지 않는다Do not alternately input and output from a file stream without an intervening positioning call
❌ 위반 예시Non-compliant example
#include <iostream>
#include <fstream>
int main() {
std::fstream f("data.bin", std::ios::in | std::ios::out | std::ios::trunc);
f << "abc";
char c;
f >> c; // 출력→입력 전환 전에 위치 지정 없음 — 미정의 동작
std::cout << "read: " << c << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <fstream>
int main() {
std::fstream f("data.bin", std::ios::in | std::ios::out | std::ios::trunc);
f << "abc";
f.seekg(0); // 명시적 위치 지정으로 입력 모드로 안전 전환
char c;
f >> c;
std::cout << "read: " << c << '\n';
}⚠️ 근거: 읽기·쓰기를 함께 여는 갱신(update) 모드 스트림에서는, 출력 뒤 곧바로 입력(또는 그 반대)을 하기 전에 seekg/seekp/flush 같은 위치 지정 연산을 끼워 넣어야 한다는 것이 표준의 요구다. 영향: 이를 어기면 내부 버퍼와 파일 위치가 동기화되지 않아 미정의 동작이 되어, 엉뚱한 바이트를 읽거나 데이터가 유실된다. 대응: 입출력 방향을 바꿀 때마다 seek 또는 flush 로 스트림 위치를 명시적으로 동기화한다.Rationale: on an update-mode stream opened for both reading and writing, the standard requires an intervening positioning operation such as seekg/seekp/flush before switching from output to input (or vice versa). Impact: violating this leaves the internal buffer and file position out of sync — undefined behaviour — so wrong bytes are read or data is lost. Fix: explicitly synchronize the stream position with a seek or flush each time the I/O direction changes.
CON동시성Concurrency
CON56-CPPCON · Rule · L2✓ compilableSEI index
호출 스레드가 이미 보유한 비재귀 뮤텍스를 다시 잠그지 않는다Do not speculatively lock a non-recursive mutex that is already owned by the calling thread
❌ 위반 예시Non-compliant example
#include <mutex>
static std::mutex m;
static void inner(){ std::lock_guard<std::mutex> g(m); /* m 재잠금 */ }
static void outer(){ std::lock_guard<std::mutex> g(m); inner(); } // 같은 스레드가 m 두 번 잠금 → 자기 교착
int main() { (void)&outer; } // 실행 회피(검증 시 자기 교착 방지). 패턴 자체가 결함✅ 준수 예시Compliant example
#include <iostream>
#include <mutex>
static std::mutex m;
static void inner_locked(){ /* 호출자가 m 을 이미 보유한다고 가정, 다시 잠그지 않음 */ }
static void outer(){
std::lock_guard<std::mutex> g(m);
inner_locked(); // 잠금을 중복 획득하지 않음
}
int main() { outer(); std::cout << "no self-deadlock\n"; }⚠️ 근거: 기본 std::mutex 는 비재귀(non-recursive)라 이미 잠근 스레드가 같은 뮤텍스를 다시 잠그려 하면 영원히 자기 자신을 기다리는 자기 교착(self-deadlock)이 된다(미정의 동작). 영향: 잠금을 쥔 함수가 같은 뮤텍스를 잠그는 다른 함수를 호출하는 흔한 리팩터링에서 의도치 않게 발생해 스레드가 멈춘다. 대응: 잠금을 이미 보유한 경로용 내부 함수는 다시 잠그지 않도록 설계하고, 진짜 재진입이 필요하면 std::recursive_mutex 를 명시적으로 사용한다.Rationale: a default std::mutex is non-recursive, so a thread that has already locked it and tries to lock the same mutex again self-deadlocks, waiting on itself forever (undefined behaviour). Impact: it arises unintentionally in the common refactor where a lock-holding function calls another that also locks the same mutex, stalling the thread. Fix: design internal functions for the already-locked path so they do not lock again, and use std::recursive_mutex explicitly only when genuine reentrancy is required.
CON50-CPPCON · Rule · L2✓ compilableSEI index
잠긴 뮤텍스를 파괴하지 않는다Do not destroy a mutex while it is locked
❌ 위반 예시Non-compliant example
#include <iostream>
#include <mutex>
int main() {
auto* m = new std::mutex;
m->lock();
delete m; // 잠긴 상태로 파괴 — 미정의 동작
std::cout << "destroyed while locked\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <mutex>
int main() {
std::mutex m;
{
std::lock_guard<std::mutex> g(m); // RAII 잠금
std::cout << "in critical section\n";
} // 스코프 종료 시 자동 해제
// m 은 잠기지 않은 상태로 소멸 — 안전
}⚠️ 근거: 표준은 어떤 스레드가 보유(잠금)하고 있는 뮤텍스를 파괴하는 것을 미정의 동작으로 규정한다(내부 OS 동기화 객체가 일관되지 않은 상태로 해제됨). 영향: 잠긴 뮤텍스 파괴는 대기 중인 다른 스레드를 영구 차단하거나 런타임 오류를 일으키며, 동적 할당된 뮤텍스에서 특히 발생하기 쉽다. 대응: 임계 영역은 lock_guard/unique_lock 같은 RAII 잠금으로 감싸 뮤텍스가 반드시 해제된 뒤에 소멸하도록 보장한다.Rationale: the standard makes destroying a mutex that is owned (locked) by any thread undefined behaviour, since the underlying OS synchronization object is released in an inconsistent state. Impact: destroying a locked mutex can permanently block other waiting threads or raise a runtime error, and is especially easy to hit with dynamically allocated mutexes. Fix: wrap critical sections in RAII locks (lock_guard/unique_lock) so the mutex is guaranteed to be unlocked before it is destroyed.
CON51-CPPCON · Rule · L2✓ compilableSEI index
예외 상황에서도 보유한 잠금을 해제한다Ensure actively held locks are released on exceptional conditions
❌ 위반 예시Non-compliant example
#include <iostream>
#include <mutex>
#include <stdexcept>
static std::mutex m;
static void risky(int argc) { if (argc >= 0) throw std::runtime_error("boom"); }
static void f(int argc) {
m.lock();
risky(argc); // 예외 발생 시 아래 unlock 을 건너뜀 → 잠금 영구 보유
m.unlock();
}
int main(int argc, char**) {
try { f(argc); } catch (...) { std::cout << "lock leaked\n"; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <mutex>
#include <stdexcept>
static std::mutex m;
static void risky() { throw std::runtime_error("boom"); }
static void f() {
std::lock_guard<std::mutex> g(m); // 예외로 스택이 풀려도 소멸자가 unlock
risky();
}
int main() {
try { f(); } catch (...) { std::cout << "lock released by RAII\n"; }
}⚠️ 근거: 명시적 lock 과 unlock 사이의 코드가 예외를 던지면 스택이 풀리면서 unlock 문장을 건너뛰어, 그 뮤텍스가 영원히 잠긴 채로 남는다. 영향: 같은 뮤텍스를 기다리는 다른 스레드가 모두 무기한 차단되어 교착·서비스 멈춤이 발생한다. 대응: lock_guard/unique_lock 같은 RAII 잠금을 사용해 정상 경로든 예외 경로든 스코프를 벗어날 때 자동으로 해제되게 한다.Rationale: if code between an explicit lock and unlock throws, stack unwinding skips the unlock statement, leaving that mutex locked forever. Impact: every other thread waiting on the same mutex is blocked indefinitely, causing deadlock and a service hang. Fix: use RAII locks (lock_guard/unique_lock) so the mutex is released automatically on leaving scope, whether the path is normal or exceptional.
CON52-CPPCON · Rule · L2✓ compilableSEI index
비트필드 멤버 접근 시 데이터 경쟁을 방지한다Prevent data races when accessing bit-fields from multiple threads
❌ 위반 예시Non-compliant example
#include <iostream>
struct Flags { unsigned a : 1; unsigned b : 1; }; // a, b 가 같은 메모리 워드 공유
// T1 이 f.a 를, T2 가 f.b 를 동시에 써도, 둘은 같은 워드를 read-modify-write 하므로 경쟁
static void set_a(Flags& f) { f.a = 1; }
static void set_b(Flags& f) { f.b = 1; }
int main() {
Flags f{0, 0};
set_a(f); set_b(f); // 단일 스레드 데모(동시 실행 시 한쪽 갱신이 유실될 수 있음)
std::cout << f.a << f.b << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <mutex>
struct Flags { unsigned a : 1; unsigned b : 1; };
static std::mutex m;
static void set_a(Flags& f) { std::lock_guard<std::mutex> g(m); f.a = 1; }
static void set_b(Flags& f) { std::lock_guard<std::mutex> g(m); f.b = 1; }
int main() {
Flags f{0, 0};
set_a(f); set_b(f); // 동일 뮤텍스로 워드 단위 갱신을 직렬화
std::cout << f.a << f.b << '\n';
}⚠️ 근거: 인접한 비트필드 멤버는 서로 다른 비트라도 같은 메모리 워드를 공유할 수 있고, 비트필드 갱신은 워드를 읽어 일부 비트를 바꾼 뒤 다시 쓰는 read-modify-write 로 구현된다. 영향: 두 스레드가 같은 워드의 서로 다른 비트필드를 잠금 없이 동시에 갱신하면, 한쪽의 read-modify-write 가 다른쪽 변경을 덮어써 갱신이 유실되는 데이터 경쟁(미정의 동작)이 된다. 대응: 같은 워드를 공유하는 비트필드들의 접근을 동일 뮤텍스로 보호하거나, 인접 비트필드를 별도 워드로 분리한다.Rationale: adjacent bit-field members can share the same memory word even when they are different bits, and updating a bit-field is implemented as a read-modify-write of the whole word. Impact: if two threads update different bit-fields in the same word concurrently without a lock, one read-modify-write overwrites the other change, losing an update — a data race and undefined behaviour. Fix: protect accesses to bit-fields sharing a word with the same mutex, or separate adjacent bit-fields into distinct words.
CON53-CPPCON · Rule · L2✓ compilableSEI index
정해진 순서로 잠가 교착을 방지한다Avoid deadlock by locking in a predefined order
❌ 위반 예시Non-compliant example
#include <iostream>
#include <mutex>
static std::mutex a, b;
// 스레드마다 잠금 순서가 다르면 교착: T1 이 a→b, T2 가 b→a 를 잡으면 서로 대기
static void t1(){ std::lock_guard<std::mutex> g1(a); std::lock_guard<std::mutex> g2(b); }
static void t2(){ std::lock_guard<std::mutex> g1(b); std::lock_guard<std::mutex> g2(a); }
int main() {
(void)&t1; (void)&t2; // 두 순서가 공존 — 동시 실행 시 교착 가능(여기선 실행만 회피)
std::cout << "inconsistent lock order\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <mutex>
static std::mutex a, b;
static void task() {
std::scoped_lock lock(a, b); // 교착 회피 알고리즘으로 여러 뮤텍스 동시 잠금
std::cout << "both locked safely\n";
}
int main() { task(); }⚠️ 근거: 두 개 이상의 뮤텍스를 스레드마다 서로 다른 순서로 잠그면, 각 스레드가 상대가 이미 쥔 뮤텍스를 기다리는 순환 대기(circular wait)가 만들어져 교착에 빠진다. 영향: 교착된 스레드들은 영원히 진행하지 못해 기능이 멈추고, 타이밍 의존적이라 재현·디버깅이 어렵다. 대응: 모든 곳에서 동일한 전역 잠금 순서를 강제하거나, std::scoped_lock 으로 여러 뮤텍스를 교착 없는 알고리즘으로 한 번에 잠근다.Rationale: locking two or more mutexes in different orders across threads creates a circular wait, where each thread waits on a mutex already held by another, leading to deadlock. Impact: the deadlocked threads never progress so functionality stalls, and being timing-dependent it is hard to reproduce and debug. Fix: enforce one consistent global lock order everywhere, or use std::scoped_lock to acquire multiple mutexes at once with a deadlock-avoidance algorithm.
CON54-CPPCON · Rule · L2✓ compilableSEI index
가짜 깨어남(spurious wakeup)이 가능한 대기는 술어로 감싼다Wrap functions that can spuriously wake up in a loop
❌ 위반 예시Non-compliant example
#include <condition_variable>
#include <mutex>
static std::mutex m;
static std::condition_variable cv;
static bool ready = false;
static void consume() {
std::unique_lock<std::mutex> lk(m);
if (!ready) cv.wait(lk); // if 검사 — 가짜 깨어남이면 ready 가 거짓인데 진행
// ... ready 를 가정하고 작업
}
int main() { (void)&consume; } // 실행 회피(검증 시 무한대기 방지). 패턴 자체가 결함✅ 준수 예시Compliant example
#include <iostream>
#include <condition_variable>
#include <mutex>
static std::mutex m;
static std::condition_variable cv;
static bool ready = false;
static void consume() {
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{ return ready; }); // 술어 버전 — 내부에서 조건을 루프로 재확인
}
int main() {
{ std::lock_guard<std::mutex> g(m); ready = true; }
cv.notify_one();
consume();
std::cout << "consumed safely\n";
}⚠️ 근거: 조건 변수의 wait 는 알림 없이도 깨어날 수 있는 가짜 깨어남(spurious wakeup)이 허용되므로, if 로 한 번만 조건을 검사하면 조건이 거짓인 상태로 깨어나 그대로 진행할 수 있다. 영향: 아직 준비되지 않은 데이터를 읽거나 만족하지 않은 불변식 위에서 작업해 경합·손상이 발생한다. 대응: 술어를 받는 wait(lk, pred) 형태나 while(!cond) wait(lk); 루프로 깨어날 때마다 조건을 다시 확인한다.Rationale: a condition variable wait is permitted to return without notification (a spurious wakeup), so checking the condition only once with if can let the thread proceed while the condition is still false. Impact: it reads not-yet-ready data or operates on an unsatisfied invariant, causing races and corruption. Fix: use the predicate form wait(lk, pred) or a while(!cond) wait(lk); loop to recheck the condition on every wakeup.
CON55-CPPCON · Rule · L2✓ compilableSEI index
조건 변수 사용 시 스레드 안전성과 진행성을 보존한다Preserve thread safety and liveness when using condition variables
❌ 위반 예시Non-compliant example
#include <condition_variable>
#include <mutex>
static std::mutex m;
static std::condition_variable cv;
static bool ready = false;
// 잠금 밖에서 술어 갱신 없이 통지 — 대기자가 아직 wait 에 안 들어갔으면 신호 유실
static void producer() {
ready = true; // 잠금 보호 없이 공유 상태 변경(경쟁)
cv.notify_one(); // 술어 갱신과 통지가 원자적이지 않음 → 신호 유실 가능
}
int main() { producer(); }✅ 준수 예시Compliant example
#include <iostream>
#include <condition_variable>
#include <mutex>
static std::mutex m;
static std::condition_variable cv;
static bool ready = false;
static void producer() {
{ std::lock_guard<std::mutex> g(m); ready = true; } // 잠금 안에서 술어 갱신
cv.notify_all(); // 그 다음 통지
}
int main() {
producer();
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{ return ready; }); // 술어로 신호 유실에도 안전
std::cout << "made progress\n";
}⚠️ 근거: 조건 변수의 올바른 사용은 공유 술어(조건)를 뮤텍스로 보호한 채 갱신한 뒤 통지하고, 대기 측은 술어를 받는 wait 로 조건을 재확인하는 것을 요구한다. 영향: 잠금 없이 술어를 바꾸고 통지하면, 통지가 대기 측이 wait 에 진입하기 전에 발생해 신호가 유실(lost wakeup)되어 대기 스레드가 영원히 깨어나지 못하는 진행성(liveness) 상실이 생긴다. 대응: 술어 갱신을 잠금 안에서 수행하고 그 뒤 통지하며, 대기는 술어 버전 wait(lk, pred) 로 작성한다.Rationale: correct condition-variable use requires updating the shared predicate while holding the mutex, then notifying, while the waiter rechecks the condition via the predicate form of wait. Impact: changing the predicate and notifying without the lock lets the notification occur before the waiter enters wait, losing the wakeup so the waiting thread never wakes — a loss of liveness. Fix: update the predicate under the lock and then notify, and write the wait using the predicate form wait(lk, pred).
STR문자·문자열Strings
STR50-CPPSTR · Rule · L1✓ compilableSEI index
문자열을 다룰 때 충분한 저장 공간을 보장한다Guarantee that storage for strings has sufficient space
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstring>
#include <string>
int main() {
std::string s = "this is far longer than eight bytes";
char buf[8];
std::strcpy(buf, s.c_str()); // s 가 8바이트 초과 → 스택 버퍼 오버플로우
std::cout << buf << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
int main() {
std::string s = "this is far longer than eight bytes";
std::string buf = s; // std::string 이 길이에 맞춰 동적 관리
std::cout << buf << '\n';
}⚠️ 근거: strcpy 같은 C 문자열 함수는 대상 버퍼 크기를 인자로 받지 않아, 원본이 고정 버퍼보다 길면 경계를 넘어 인접 메모리에 기록한다. 영향: 스택 버퍼 오버플로우는 반환 주소·인접 변수를 덮어 크래시·메모리 손상은 물론 코드 실행 공격의 통로가 된다. 대응: std::string 으로 길이를 자동 관리하거나, C 버퍼가 꼭 필요하면 길이를 검사한 뒤 한정된 복사를 한다.Rationale: C string functions like strcpy take no destination size, so if the source is longer than the fixed buffer it writes past the boundary into adjacent memory. Impact: a stack buffer overflow overwrites the return address and neighbouring variables, causing crashes and memory corruption and opening a path to code-execution attacks. Fix: manage length automatically with std::string, or when a C buffer is required, copy a bounded amount after checking the length.
STR52-CPPSTR · Rule · L1✓ compilableSEI index
basic_string 원소의 유효한 참조/반복자만 사용한다Use valid references, pointers, and iterators to reference elements of a basic_string
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
int main() {
std::string s = "hello";
const char& c = s[0]; // 첫 문자 참조
s += " world and a much longer suffix"; // 재할당 → c 무효화
std::cout << c << '\n'; // 댕글링 참조 — 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
int main() {
std::string s = "hello";
s += " world and a much longer suffix"; // 먼저 수정
const char& c = s[0]; // 그 다음 참조 획득
std::cout << c << '\n';
}⚠️ 근거: append·insert·operator+= 로 문자열이 현재 용량을 초과하면 내부 버퍼가 재할당되어 기존 문자에 대한 참조·포인터·반복자가 모두 무효화된다. 영향: 무효화된 참조를 읽으면 해제된 버퍼를 가리켜 쓰레기 값·크래시가 난다. 대응: 문자열을 수정한 뒤 참조·반복자를 다시 얻는다.Rationale: when an append, insert, or operator+= grows a string past its current capacity, the internal buffer is reallocated, invalidating all references, pointers, and iterators to existing characters. Impact: reading an invalidated reference points into the freed buffer, yielding garbage or a crash. Fix: re-obtain references/iterators after modifying the string.
STR53-CPPSTR · Rule · L1✓ compilableSEI index
문자열 원소 접근 시 범위를 검사한다Range check element access
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
int main() {
std::string s = "ab";
char c = s[5]; // 길이 2 인데 인덱스 5 — 범위 밖, 미정의 동작
std::cout << static_cast<int>(c) << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
#include <stdexcept>
int main() {
std::string s = "ab";
try { char c = s.at(5); std::cout << c << '\n'; } // 범위 밖이면 예외
catch (const std::out_of_range&) { std::cout << "out of range\n"; }
}⚠️ 근거: std::string::operator[] 는 컨테이너와 마찬가지로 범위를 검사하지 않아 size() 이상의 인덱스 접근은 미정의 동작이다. 영향: 길이를 넘는 읽기는 인접 메모리 내용을 노출하거나 쓰기 시 손상을 일으키며, 외부 입력 인덱스면 보안 결함이 된다. 대응: 인덱스를 size() 와 비교하거나 예외를 던지는 at() 으로 안전하게 접근한다.Rationale: std::string::operator[], like a container, does not check bounds, so accessing an index at or beyond size() is undefined behaviour. Impact: a read past the length exposes adjacent memory contents, a write corrupts it, and an externally supplied index makes it a security flaw. Fix: compare the index against size() or access safely via at(), which throws on out-of-range.
STR51-CPPSTR · Rule · L1✓ compilableSEI index
널 포인터로 std::string 을 생성하지 않는다Do not attempt to create a std::string from a null pointer
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdlib>
#include <string>
int main() {
const char* p = std::getenv("DOES_NOT_EXIST"); // 미설정 시 nullptr
std::string s(p); // nullptr 로 string 생성 — strlen(nullptr) 미정의, 크래시
std::cout << s << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstdlib>
#include <string>
int main() {
const char* p = std::getenv("DOES_NOT_EXIST");
std::string s = (p != nullptr) ? std::string(p) : std::string{}; // 널 검사
std::cout << "[" << s << "]\n";
}⚠️ 근거: const char* 를 받는 std::string 생성자는 내부적으로 strlen 으로 길이를 재는데, 인자가 nullptr 이면 널 포인터를 역참조하게 되어 미정의 동작이다. 영향: getenv·검색 함수 등 nullptr 을 반환할 수 있는 API 결과를 그대로 넘기면 대개 즉시 크래시가 난다. 대응: 포인터가 nullptr 이 아닌지 확인한 뒤 생성하고, 널이면 빈 문자열로 대체한다.Rationale: the std::string constructor taking const char* measures length internally with strlen, so a nullptr argument dereferences a null pointer — undefined behaviour. Impact: passing the result of APIs that may return nullptr (getenv, lookup functions) directly usually crashes immediately. Fix: check that the pointer is not nullptr before constructing, substituting an empty string when it is null.
MEM메모리 관리Memory
MEM50-CPPMEM · Rule · L1✓ compilableSEI index
해제된 메모리에 접근하지 않는다(use-after-free)Do not access freed memory
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int* p = new int(5);
delete p; // 메모리 해제
*p = 7; // 해제 후 사용 — 미정의 동작
std::cout << *p << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
int main() {
auto p = std::make_unique<int>(5);
*p = 7; // 스코프 종료 시 자동 해제 — 댕글링 불가능
std::cout << *p << '\n';
}⚠️ 근거: delete 후의 포인터는 댕글링 상태가 되어, 그것을 역참조해 읽거나 쓰는 것은 미정의 동작이다(해당 메모리가 이미 다른 객체에 재사용됐을 수 있다). 영향: use-after-free 는 힙 메타데이터·다른 객체를 손상시키고, 공격자가 해제와 재할당 사이를 노리면 정보 유출·임의 코드 실행으로 악용된다. 대응: RAII 스마트 포인터(unique_ptr/shared_ptr)로 수명을 소유권에 묶어 수동 delete 와 댕글링을 제거한다.Rationale: a pointer after delete is dangling, and dereferencing it to read or write is undefined behaviour, since that memory may already be reused by another object. Impact: a use-after-free corrupts heap metadata and other objects, and an attacker timing the gap between free and reallocation can exploit it for information disclosure or arbitrary code execution. Fix: tie lifetime to ownership with RAII smart pointers (unique_ptr/shared_ptr), eliminating manual delete and dangling.
MEM51-CPPMEM · Rule · L1✓ compilableSEI index
동적 자원을 올바른 형식으로 해제한다Properly deallocate dynamically allocated resources
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int* a = new int[10]; // 배열 형태로 할당
a[0] = 1;
delete a; // new[] 를 delete 로 해제 — 미정의 동작
std::cout << "done\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
int main() {
std::vector<int> a(10); // 컨테이너가 올바른 해제를 보장
a[0] = 1;
std::cout << a[0] << '\n';
}⚠️ 근거: new 와 new[] 는 서로 다른 할당 경로를 쓰며, 표준은 new 는 delete 로, new[] 는 delete[] 로만 해제하도록 요구한다. 영향: 형식이 어긋나면 배열 원소 소멸자가 호출되지 않거나 잘못된 크기로 반환되어 힙이 손상되는 미정의 동작이 된다. 대응: 직접 new/delete 대신 std::vector 나 std::make_unique<T[]> 로 할당·해제를 자동화한다.Rationale: new and new[] use different allocation paths, and the standard requires new to be matched with delete and new[] with delete[]. Impact: a mismatch skips element destructors or frees with the wrong size, corrupting the heap — undefined behaviour. Fix: replace raw new/delete with std::vector or std::make_unique<T[]> to automate matched allocation and deallocation.
MEM52-CPPMEM · Rule · L1✓ compilableSEI index
메모리 할당 오류를 검출하고 처리한다Detect and handle memory allocation errors
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdlib>
int main() {
std::size_t n = 1000;
int* p = static_cast<int*>(std::malloc(n * sizeof(int)));
p[0] = 1; // malloc 실패(nullptr) 미검사 → 널 역참조 가능
std::cout << p[0] << '\n';
std::free(p);
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
#include <new>
int main() {
std::size_t n = 1000;
try {
auto p = std::make_unique<int[]>(n); // 실패 시 std::bad_alloc
p[0] = 1;
std::cout << p[0] << '\n';
} catch (const std::bad_alloc&) { std::cout << "alloc failed\n"; }
}⚠️ 근거: malloc 은 실패 시 nullptr 을 반환하고 new 는 std::bad_alloc 을 던지는데, 두 신호 모두 처리하지 않으면 실패가 정상 흐름으로 새어든다. 영향: 검사 없이 malloc 반환을 역참조하면 널 포인터 역참조로 크래시가 나고, 일부 환경에서는 공격 가능한 상태가 된다. 대응: malloc 반환을 nullptr 과 비교해 처리하거나, new 의 bad_alloc 예외를 catch 한다.Rationale: malloc returns nullptr on failure and new throws std::bad_alloc, and ignoring either signal lets a failure leak into normal flow. Impact: dereferencing an unchecked malloc result is a null-pointer dereference that crashes, and in some environments leaves an exploitable state. Fix: compare the malloc result against nullptr and handle it, or catch the bad_alloc exception from new.
MEM53-CPPMEM · Rule · L2✓ compilableSEI index
수동 수명 관리 시 객체를 명시적으로 생성·소멸한다Explicitly construct and destruct objects when manually managing object lifetime
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
struct S { std::string name = "init"; void use(){ std::cout << name << '\n'; } };
int main() {
alignas(S) unsigned char buf[sizeof(S)];
S* p = reinterpret_cast<S*>(buf); // 생성자 미호출 — name 미초기화
p->use(); // 불변식 미성립 객체 사용 — 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
#include <new>
struct S { std::string name = "init"; void use(){ std::cout << name << '\n'; } };
int main() {
alignas(S) unsigned char buf[sizeof(S)];
S* p = new (buf) S(); // placement new 로 명시적 생성
p->use();
p->~S(); // 명시적 소멸
}⚠️ 근거: 원시 바이트 저장소를 객체 타입으로 캐스트만 하면 생성자가 실행되지 않아, 멤버 초기화와 클래스 불변식이 성립하지 않은 채 객체로 취급된다. 영향: 미초기화된 std::string 같은 멤버를 사용하면 잘못된 내부 포인터를 따라가 크래시·손상이 나고, 소멸도 누락된다. 대응: 수동 저장소에서는 placement new 로 생성하고, 사용 후 소멸자를 명시적으로 호출한다.Rationale: merely casting raw byte storage to an object type does not run the constructor, so the object is treated as live without member initialization or class invariants. Impact: using a member like an uninitialized std::string follows an invalid internal pointer and crashes or corrupts, and destruction is also missed. Fix: construct with placement new in manual storage and call the destructor explicitly after use.
MEM54-CPPMEM · Rule · L1✓ compilableSEI index
placement new 에 적절히 정렬된 충분한 저장소를 제공한다Provide placement new with properly aligned pointers to sufficient storage capacity
❌ 위반 예시Non-compliant example
#include <iostream>
#include <new>
#include <cstdint>
struct alignas(16) Vec4 { double a, b; }; // 16바이트 정렬 요구
int main() {
unsigned char buf[sizeof(Vec4)]; // 정렬 미보장 — char 배열은 1바이트 정렬
Vec4* p = new (buf) Vec4{1, 2}; // 오정렬 저장소에 배치 — 미정의 동작
std::cout << p->a << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <new>
struct alignas(16) Vec4 { double a, b; };
int main() {
alignas(Vec4) unsigned char buf[sizeof(Vec4)]; // 대상 타입 정렬 보장
Vec4* p = new (buf) Vec4{1, 2};
std::cout << p->a << '\n';
p->~Vec4();
}⚠️ 근거: placement new 는 주어진 주소에 그대로 객체를 배치할 뿐 정렬을 보정하지 않으므로, 저장소가 대상 타입의 정렬 요건을 만족해야 한다. 영향: 과도 정렬(alignas) 타입을 1바이트 정렬 버퍼에 배치하면 일부 아키텍처에서 정렬 폴트가 나거나 SIMD 명령이 실패하는 미정의 동작이 된다. 대응: 저장소를 alignas(대상 타입) 으로 선언하거나 std::aligned_alloc 으로 정렬된 메모리를 확보한다.Rationale: placement new simply constructs an object at the given address without correcting alignment, so the storage must meet the alignment requirement of the target type. Impact: placing an over-aligned (alignas) type into a 1-byte-aligned buffer causes alignment faults or failed SIMD instructions on some architectures — undefined behaviour. Fix: declare the storage with alignas(target type) or obtain aligned memory via std::aligned_alloc.
MEM55-CPPMEM · Rule · L2✓ compilableSEI index
교체(replacement) operator new/delete 는 요구사항을 준수한다Honor replacement dynamic storage management requirements
❌ 위반 예시Non-compliant example
#include <cstdlib>
#include <iostream>
// 전역 operator new 교체인데 실패 시 nullptr 반환 — non-throwing new 계약 위반
void* operator new(std::size_t n) {
return std::malloc(n); // 실패해도 예외를 던지지 않음
}
void operator delete(void* p) noexcept { std::free(p); }
int main() {
int* p = new int(5); // 표준은 실패 시 bad_alloc 을 기대 → 호출 코드가 nullptr 미대비
std::cout << *p << '\n';
delete p;
}✅ 준수 예시Compliant example
#include <cstdlib>
#include <new>
#include <iostream>
// 계약 준수: 성공하면 정렬된 메모리, 실패하면 std::bad_alloc
void* operator new(std::size_t n) {
if (void* p = std::malloc(n ? n : 1)) return p;
throw std::bad_alloc();
}
void operator delete(void* p) noexcept { std::free(p); }
int main() {
int* p = new int(5);
std::cout << *p << '\n';
delete p;
}⚠️ 근거: 기본(throwing) operator new 를 교체하면, 성공 시 적절히 정렬된 메모리를 돌려주고 실패 시 std::bad_alloc 을 던진다는 표준 계약을 그대로 지켜야 한다. 영향: 실패 시 nullptr 을 반환하면 표준 라이브러리와 사용자 코드가 모두 new 는 절대 nullptr 을 주지 않는다고 가정하므로, 검사 없이 역참조해 널 포인터 역참조로 크래시가 난다. 대응: 교체 operator new 는 실패 시 bad_alloc 을 던지고(또는 nothrow 버전만 nullptr), 0 바이트 요청도 유효 포인터를 주도록 계약을 충족하며, delete 와 짝을 맞춘다.Rationale: replacing the default (throwing) operator new requires honoring the standard contract — return suitably aligned memory on success and throw std::bad_alloc on failure. Impact: returning nullptr on failure breaks the assumption (held by the standard library and user code) that new never returns nullptr, so the result is dereferenced unchecked, causing a null-pointer-dereference crash. Fix: have replacement operator new throw bad_alloc on failure (only the nothrow form returns nullptr), return a valid pointer even for a zero-byte request, and pair it with a matching delete.
MEM56-CPPMEM · Rule · L1✓ compilableSEI index
이미 소유된 포인터를 무관한 스마트 포인터에 저장하지 않는다Do not store an already-owned pointer value in an unrelated smart pointer
❌ 위반 예시Non-compliant example
#include <iostream>
#include <memory>
int main() {
int* raw = new int(1);
std::shared_ptr<int> a(raw);
std::shared_ptr<int> b(raw); // 같은 raw 로 독립 제어블록 2개 — 이중 해제
std::cout << *a << '\n';
} // a, b 소멸 시 raw 를 두 번 delete✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
int main() {
auto a = std::make_shared<int>(1);
std::shared_ptr<int> b = a; // 같은 제어블록 공유 — 참조 카운트 2
std::cout << *a << " count=" << a.use_count() << '\n';
}⚠️ 근거: shared_ptr 는 자신이 생성한 제어 블록으로 참조 수를 추적하는데, 같은 raw 포인터로 별개의 shared_ptr 두 개를 생성하면 제어 블록이 둘로 나뉘어 서로의 존재를 모른다. 영향: 두 shared_ptr 가 각자 참조 수를 0 으로 떨어뜨리며 같은 메모리를 두 번 delete 해 이중 해제로 힙이 손상된다. 대응: 소유권은 make_shared 로 한 번 만들고 복사로 공유하며, 단일 소유는 unique_ptr 로 표현한다.Rationale: a shared_ptr tracks references with the control block it created, but constructing two separate shared_ptrs from the same raw pointer creates two control blocks that are unaware of each other. Impact: each shared_ptr drives its own reference count to zero and deletes the same memory twice, a double free that corrupts the heap. Fix: create ownership once with make_shared and share by copying, and express single ownership with unique_ptr.
MEM57-CPPMEM · Rule · L2✓ compilableSEI index
과도 정렬(over-aligned) 타입에 기본 operator new 가정에 의존하지 않는다Avoid using default operator new for over-aligned types
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdint>
struct alignas(64) CacheLine { char data[64]; }; // 캐시라인 정렬 요구
int main() {
CacheLine* p = new CacheLine(); // 정렬 인식 new 미지원 환경에선 64B 정렬 미보장
bool aligned = (reinterpret_cast<std::uintptr_t>(p) % 64) == 0;
std::cout << (aligned ? "aligned" : "MISALIGNED") << '\n';
delete p;
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstdlib>
#include <new>
#include <cstdint>
struct alignas(64) CacheLine { char data[64]; };
int main() {
void* m = std::aligned_alloc(64, sizeof(CacheLine)); // 정렬 보장 할당
CacheLine* p = new (m) CacheLine();
bool aligned = (reinterpret_cast<std::uintptr_t>(p) % 64) == 0;
std::cout << (aligned ? "aligned" : "MISALIGNED") << '\n';
p->~CacheLine();
std::free(m);
}⚠️ 근거: C++17 이전 또는 정렬 인식 operator new 를 제공하지 않는 구현에서는 기본 할당자가 기본 정렬(보통 16바이트)까지만 보장하므로, 확장 정렬을 요구하는 타입이 오정렬될 수 있다. 영향: SIMD 레지스터 로드나 캐시라인 정렬을 가정한 코드가 오정렬 메모리에서 정렬 폴트·성능 저하·미정의 동작을 일으킨다. 대응: 정렬 인식 operator new 를 쓰거나 std::aligned_alloc 으로 정렬을 명시 보장한 뒤 placement new 한다.Rationale: before C++17, or on implementations without an alignment-aware operator new, the default allocator only guarantees default alignment (typically 16 bytes), so a type requiring extended alignment can be misaligned. Impact: code assuming SIMD register loads or cache-line alignment hits alignment faults, performance loss, or undefined behaviour on misaligned memory. Fix: use an alignment-aware operator new, or guarantee alignment explicitly with std::aligned_alloc followed by placement new.
OOP객체지향OOP
OOP50-CPPOOP · Rule · L1✓ compilableSEI index
생성자/소멸자에서 가상 함수를 호출하지 않는다Do not invoke virtual functions from constructors or destructors
❌ 위반 예시Non-compliant example
#include <iostream>
struct Base {
Base() { init(); } // 생성 중 — 동적 타입은 아직 Base
virtual void init() { std::cout << "Base::init\n"; }
};
struct Derived : Base {
int* buf;
void init() override { buf = new int[4]; std::cout << "Derived::init\n"; }
};
int main() {
Derived d; // Derived::init 이 아니라 Base::init 호출 → buf 미할당
std::cout << "done\n";
}✅ 준수 예시Compliant example
#include <iostream>
struct Base {
Base() { } // 생성자에서는 가상 호출 안 함
void start() { init(); } // 생성 완료 후 별도 호출
virtual void init() { std::cout << "Base::init\n"; }
};
struct Derived : Base {
void init() override { std::cout << "Derived::init\n"; }
};
int main() {
Derived d;
d.start(); // 이제 Derived::init 으로 정상 디스패치
}⚠️ 근거: 생성·소멸 중에는 객체의 동적 타입이 현재 실행 중인 생성자/소멸자의 클래스로 고정되어, 가상 호출이 파생 오버라이드로 가지 않고 그 클래스 버전으로 정적 디스패치된다. 영향: 파생 클래스의 초기화를 기대한 가상 호출이 기반 버전을 부르면 멤버가 준비되지 않은 채 진행되어 미초기화 접근·논리 오류가 난다. 대응: 가상 동작이 필요한 초기화는 생성이 끝난 뒤 별도 메서드에서 호출한다.Rationale: during construction and destruction the dynamic type of the object is fixed to the class whose constructor/destructor is running, so a virtual call dispatches statically to the version in that class, not a derived override. Impact: a virtual call expected to run derived initialization instead runs the base version, proceeding with uninitialized members and logic errors. Fix: perform virtual-dependent initialization in a separate method called after construction completes.
OOP51-CPPOOP · Rule · L2✓ compilableSEI index
파생 객체를 슬라이싱(slicing)하지 않는다Do not slice derived objects
❌ 위반 예시Non-compliant example
#include <iostream>
struct Shape { virtual double area() const { return 0; } };
struct Circle : Shape {
double r;
Circle(double r):r(r){}
double area() const override { return 3.14159*r*r; }
};
static void print(Shape s) { // 값 전달 — 파생 부분이 잘림
std::cout << s.area() << '\n'; // 항상 Shape::area → 0
}
int main() { print(Circle{2.0}); }✅ 준수 예시Compliant example
#include <iostream>
struct Shape { virtual double area() const { return 0; } };
struct Circle : Shape {
double r;
Circle(double r):r(r){}
double area() const override { return 3.14159*r*r; }
};
static void print(const Shape& s) { // 참조 전달 — 다형성 보존
std::cout << s.area() << '\n';
}
int main() { print(Circle{2.0}); }⚠️ 근거: 파생 객체를 기반 클래스 값 매개변수로 받으면 기반 부분만 복사되고 파생 클래스가 추가한 멤버와 vtable 연결이 잘려 나간다(slicing). 영향: 가상 디스패치가 기반 버전으로 고정되어 Circle 의 area() 가 호출되지 못하고 0 이 반환되는 등 다형성이 조용히 깨진다. 대응: 다형 객체는 항상 기반 타입의 참조나 포인터로 전달·보관한다.Rationale: receiving a derived object by a base-class value parameter copies only the base subobject, slicing off the derived members and the vtable link. Impact: virtual dispatch is fixed to the base version, so Circle::area is never called and 0 is returned — polymorphism silently breaks. Fix: always pass and store polymorphic objects by reference or pointer to the base type.
OOP52-CPPOOP · Rule · L1✓ compilableSEI index
가상 소멸자가 없는 다형 객체를 기반 포인터로 delete 하지 않는다Do not delete a polymorphic object through a base pointer lacking a virtual destructor
❌ 위반 예시Non-compliant example
#include <iostream>
struct Base { ~Base() { std::cout << "~Base\n"; } }; // 비가상 소멸자
struct Derived : Base {
int* res;
Derived(){ res = new int[100]; }
~Derived(){ delete[] res; std::cout << "~Derived\n"; }
};
int main() {
Base* p = new Derived;
delete p; // ~Derived 미호출 → res 누수, 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
struct Base { virtual ~Base() = default; }; // 가상 소멸자
struct Derived : Base {
int* res;
Derived(){ res = new int[100]; }
~Derived() override { delete[] res; std::cout << "~Derived\n"; }
};
int main() {
Base* p = new Derived;
delete p; // ~Derived → ~Base 정상 호출
}⚠️ 근거: 기반 클래스 소멸자가 가상이 아니면 기반 포인터로 delete 할 때 정적 타입의 소멸자만 호출되고 파생 소멸자는 호출되지 않는다(미정의 동작). 영향: 파생 클래스가 소유한 자원이 정리되지 않아 누수되고, 일부 구현에서는 잘못된 크기로 해제되어 힙이 손상된다. 대응: 다형적으로 삭제될 기반 클래스에는 가상(또는 protected 비가상) 소멸자를 둔다.Rationale: if the base destructor is not virtual, deleting through a base pointer invokes only the destructor of the static type, not the derived one (undefined behaviour). Impact: resources owned by the derived class are not cleaned up and leak, and some implementations free with the wrong size, corrupting the heap. Fix: give a base class that will be deleted polymorphically a virtual (or protected non-virtual) destructor.
OOP53-CPPOOP · Rule · L3✓ compilableSEI index
생성자 멤버 초기화 목록을 선언 순서대로 작성한다Write constructor member initializers in canonical (declaration) order
❌ 위반 예시Non-compliant example
#include <iostream>
struct S {
int a;
int b;
S(int x) : b(x), a(b) {} // 목록 순서와 무관: 실제로는 a 가 먼저 초기화됨
}; // a(b) 시점에 b 는 아직 미초기화
int main() {
S s(5);
std::cout << s.a << ' ' << s.b << '\n'; // a 는 쓰레기 값
}✅ 준수 예시Compliant example
#include <iostream>
struct S {
int a;
int b;
S(int x) : a(x), b(x) {} // 선언 순서(a, b)와 일치 — 의존성 제거
};
int main() {
S s(5);
std::cout << s.a << ' ' << s.b << '\n';
}⚠️ 근거: 멤버는 초기화 목록에 적은 순서가 아니라 클래스 내 선언 순서대로 초기화된다. 영향: b(x), a(b) 처럼 적으면 직관과 달리 a 가 먼저 초기화되어 아직 미초기화된 b 를 읽어 a 에 쓰레기 값이 들어간다. 대응: 초기화 목록을 항상 선언 순서대로 적고, 한 멤버를 다른 멤버로 초기화하는 의존을 피한다.Rationale: members are initialized in their declaration order within the class, not in the order written in the initializer list. Impact: writing b(x), a(b) initializes a first against intuition, reading the still-uninitialized b and giving a a garbage value. Fix: always list initializers in declaration order and avoid initializing one member from another.
OOP54-CPPOOP · Rule · L3✓ compilableSEI index
자기 대입(self copy-assignment)을 안전하게 처리한다Gracefully handle self copy-assignment
❌ 위반 예시Non-compliant example
#include <iostream>
struct Buf {
int* data;
Buf(int v): data(new int(v)) {}
~Buf(){ delete data; }
Buf& operator=(const Buf& o) {
delete data; // o 가 this 면 자기 데이터를 먼저 해제
data = new int(*o.data); // 해제된 메모리에서 복사 — use-after-free
return *this;
}
};
int main() {
Buf b(7);
b = b; // 자기 대입 — UAF
std::cout << *b.data << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <utility>
struct Buf {
int* data;
Buf(int v): data(new int(v)) {}
Buf(const Buf& o): data(new int(*o.data)) {}
~Buf(){ delete data; }
Buf& operator=(Buf o) { // copy-and-swap — 자기 대입 자동 안전
std::swap(data, o.data);
return *this;
}
};
int main() {
Buf b(7);
b = b;
std::cout << *b.data << '\n';
}⚠️ 근거: 복사 대입에서 기존 자원을 먼저 해제하고 원본을 복사하는 순서로 작성하면, 원본과 대상이 같은 객체(self-assignment)일 때 복사할 원본이 이미 해제된 상태가 된다. 영향: use-after-free 로 쓰레기 값을 읽거나 크래시가 나며, 이중 해제로 힙이 손상될 수 있다. 대응: copy-and-swap 관용구(또는 명시적 자기 검사)를 사용해 자기 대입에서도 항상 안전하게 만든다.Rationale: a copy-assignment that frees the existing resource before copying the source breaks when source and target are the same object, because the source is already freed when copied. Impact: a use-after-free reads garbage or crashes, and a double free can corrupt the heap. Fix: use the copy-and-swap idiom (or an explicit self-check) so self-assignment is always safe.
OOP55-CPPOOP · Rule · L1✓ compilableSEI index
존재하지 않는 멤버를 멤버 포인터 연산으로 접근하지 않는다Do not use pointer-to-member operators to access nonexistent members
❌ 위반 예시Non-compliant example
#include <iostream>
struct Base { int b = 1; };
struct Derived : Base { int d = 2; };
int main() {
int Derived::* pm = &Derived::d; // Derived 의 멤버를 가리킴
Base base;
// pm 은 Derived 레이아웃 기준 오프셋 — Base 객체엔 그 멤버가 없음
Base* bp = &base;
auto* dp = static_cast<Derived*>(bp); // 잘못된 다운캐스트(실제 Derived 아님)
std::cout << dp->*pm << '\n'; // 객체에 없는 멤버 접근 — 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
struct Base { int b = 1; };
struct Derived : Base { int d = 2; };
int main() {
int Derived::* pm = &Derived::d;
Derived real; // 멤버가 실제로 존재하는 객체
std::cout << real.*pm << '\n'; // 2 — 안전
}⚠️ 근거: 멤버 포인터 .* / ->* 는 대상 객체에 그 멤버가 실제로 존재한다는 전제하에 오프셋을 적용하는데, 잘못된 다운캐스트로 얻은 객체에는 해당 멤버가 없을 수 있다. 영향: 객체 경계 밖 메모리를 읽거나 써서 미정의 동작·메모리 손상이 발생하고, 진단이 나오지 않아 발견이 어렵다. 대응: 멤버 포인터를 적용하기 전 대상 객체가 그 멤버를 가진 정확한 동적 타입인지 보장한다(dynamic_cast 검사 등).Rationale: the .* and ->* operators apply an offset assuming the target object actually has that member, but an object obtained by an invalid downcast may not. Impact: it reads or writes memory outside the bounds of the object, causing undefined behaviour and memory corruption with no diagnostic, making it hard to find. Fix: ensure the target object has the member (correct dynamic type, e.g. via dynamic_cast) before applying a pointer-to-member.
OOP56-CPPOOP · Rule · L2✓ compilableSEI index
교체한 핸들러(new_handler 등)의 요구사항을 준수한다Honor replacement handler requirements
❌ 위반 예시Non-compliant example
#include <new>
#include <iostream>
// new_handler 인데 메모리 확보도, 핸들러 해제도, 예외/종료도 하지 않음
static void my_handler() {
std::cout << "tried\n"; // 아무 해결 없이 반환 → operator new 가 무한 재시도
}
int main() {
std::set_new_handler(my_handler);
std::cout << "handler installed (not exercised)\n"; // 실제 OOM 유발은 회피
}✅ 준수 예시Compliant example
#include <new>
#include <iostream>
static void my_handler() {
// 1) 메모리를 확보하거나 2) 핸들러를 풀거나 3) 예외/종료 중 하나를 반드시 수행
std::set_new_handler(nullptr); // 더는 못 푼다고 판단 → 다음엔 bad_alloc 으로
throw std::bad_alloc();
}
int main() {
std::set_new_handler(my_handler);
std::cout << "handler installed\n";
}⚠️ 근거: operator new 는 할당 실패 시 등록된 new_handler 를 호출하고 다시 할당을 시도하는 루프를 도는데, 표준은 핸들러가 (a) 더 많은 메모리를 확보하거나 (b) set_new_handler 로 자신을 해제하거나 (c) 예외를 던지거나 종료하도록 요구한다. 영향: 이 중 무엇도 하지 않고 그냥 반환하면 가용 메모리가 늘지 않은 채 같은 실패와 호출이 영원히 반복되어 프로그램이 무한 루프에 빠진다. 대응: new_handler 는 셋 중 하나를 반드시 수행하도록 작성하고, 더 풀 수 없으면 bad_alloc 을 던져 루프를 끝낸다.Rationale: operator new loops by calling the registered new_handler on allocation failure and retrying, and the standard requires the handler to (a) make more memory available, (b) deregister itself via set_new_handler, or (c) throw an exception or terminate. Impact: simply returning without doing any of these leaves available memory unchanged, so the same failure and call repeat forever, hanging the program in an infinite loop. Fix: write the new_handler to always do one of the three, throwing bad_alloc to end the loop when nothing more can be freed.
OOP57-CPPOOP · Rule · L3✓ compilableSEI index
복사·비교에 C 표준 함수 대신 특수 멤버 함수/연산자를 선호한다Prefer special member functions and overloaded operators to C Standard Library functions
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstring>
#include <string>
struct Record {
std::string name; // 비trivial 멤버 — 내부에 포인터 보유
int id = 0;
};
int main() {
Record a; a.name = "alice"; a.id = 1;
Record b;
std::memcpy(&b, &a, sizeof a); // 포인터 비트만 복사 — 두 객체가 같은 버퍼 공유
std::cout << b.name << '\n'; // 소멸 시 이중 해제로 손상
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
struct Record {
std::string name;
int id = 0;
};
int main() {
Record a; a.name = "alice"; a.id = 1;
Record b = a; // 복사 생성자 — name 을 깊은 복사
std::cout << b.name << '\n';
}⚠️ 근거: std::string 처럼 비trivial 타입은 내부에 소유 포인터·불변식을 가지므로, memcpy 로 비트만 복사하면 두 객체가 같은 버퍼를 가리키게 된다. 영향: 한쪽 수정이 다른쪽에 새고, 두 객체가 소멸하면서 같은 메모리를 이중 해제해 힙이 손상된다. memcmp 역시 패딩·포인터 값을 비교해 잘못된 결과를 준다. 대응: 복사는 복사 생성자/대입, 비교는 operator== 등 클래스가 정의한 특수 멤버·연산자를 사용한다.Rationale: non-trivial types like std::string hold owning pointers and invariants, so a bitwise memcpy makes two objects point at the same buffer. Impact: a modification on one leaks to the other, and both objects double-free the same memory on destruction, corrupting the heap; memcmp likewise compares padding/pointer values and gives wrong results. Fix: use the copy constructor/assignment for copying and operator== for comparison — the special members and operators of the class.
OOP58-CPPOOP · Rule · L2✓ compilableSEI index
복사 연산은 원본(source)을 변경하지 않는다Copy operations must not mutate the source
❌ 위반 예시Non-compliant example
#include <iostream>
struct Handle {
int* p;
Handle(int v): p(new int(v)) {}
~Handle(){ delete p; }
Handle(const Handle& o) { // '복사'인데 원본을 비워버림
p = o.p;
const_cast<Handle&>(o).p = nullptr; // 원본 훼손 — 복사 의미 위반
}
};
int main() {
Handle a(3);
Handle b = a; // a 가 망가짐
std::cout << (a.p ? *a.p : -1) << '\n'; // -1 — 원본이 비었음
}✅ 준수 예시Compliant example
#include <iostream>
#include <utility>
struct Handle {
int* p;
Handle(int v): p(new int(v)) {}
~Handle(){ delete p; }
Handle(const Handle& o): p(o.p ? new int(*o.p) : nullptr) {} // 깊은 복사, 원본 보존
Handle(Handle&& o) noexcept : p(o.p) { o.p = nullptr; } // 비우기는 이동만
};
int main() {
Handle a(3);
Handle b = a; // a 보존
std::cout << (a.p ? *a.p : -1) << '\n'; // 3
}⚠️ 근거: 복사 생성/대입은 원본을 읽기만 하고 그대로 보존해야 한다는 것이 복사의 의미론적 계약이며, 그래서 매개변수가 const 참조다. 영향: 복사가 원본을 비우거나 바꾸면 const_cast 로 계약을 위반하게 되고, 표준 알고리즘·컨테이너가 사본을 자유롭게 만든다는 가정 아래 원본이 예기치 않게 파괴된다. 대응: 원본을 비우는 동작은 이동 생성/대입에만 두고 복사는 깊은 복사로 원본을 보존한다.Rationale: copy construction/assignment must only read and preserve the source — that is the semantic contract, which is why the parameter is a const reference. Impact: a copy that empties or alters the source violates the contract via const_cast, and standard algorithms/containers that freely make copies will unexpectedly destroy the original. Fix: put emptying behaviour only in move construction/assignment and keep copy as a deep copy that preserves the source.
MSC기타Miscellaneous
MSC50-CPPMSC · Rule · L3✓ compilableSEI index
std::rand() 로 보안에 민감한 난수를 만들지 않는다Do not use std::rand() for generating pseudorandom numbers
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdlib>
static std::string make_token() {
std::string t;
for (int i = 0; i < 8; ++i) t += char('a' + std::rand() % 26); // 예측 가능
return t;
}
int main() { std::cout << make_token() << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
#include <random>
#include <string>
static std::string make_token() {
std::random_device rd; // 비결정적 엔트로피 소스
std::uniform_int_distribution<int> dist(0, 25);
std::string t;
for (int i = 0; i < 8; ++i) t += char('a' + dist(rd));
return t;
}
int main() { std::cout << make_token() << '\n'; }⚠️ 근거: std::rand 는 구현마다 품질이 낮고 주기가 짧으며 내부 상태가 작아, 출력 몇 개만 보면 이후 값을 예측할 수 있는 경우가 많다. 영향: 토큰·세션 ID·솔트 같은 보안 요소를 rand 로 만들면 공격자가 값을 추측해 인증 우회·세션 탈취가 가능해진다. 대응: 보안 용도는 OS CSPRNG(또는 그에 시드된 엔진), 비보안 용도라도 <random> 의 분포·엔진 조합을 사용한다.Rationale: std::rand is often low quality with a short period and small internal state, so a few outputs frequently suffice to predict subsequent values. Impact: generating security elements like tokens, session IDs, or salts with rand lets an attacker guess values, enabling authentication bypass or session hijacking. Fix: use an OS CSPRNG (or an engine seeded from one) for security, and even for non-security use the distribution/engine combinations in <random>.
MSC51-CPPMSC · Rule · L3✓ compilableSEI index
난수 생성기를 적절히 시드(seed)한다Ensure your random number generator is properly seeded
❌ 위반 예시Non-compliant example
#include <iostream>
#include <random>
int main() {
std::mt19937 gen; // 기본 고정 시드 — 매 실행 동일한 수열
std::uniform_int_distribution<int> d(1, 100);
std::cout << d(gen) << '\n'; // 항상 같은 값
}✅ 준수 예시Compliant example
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd()); // 엔트로피 소스로 시드 — 실행마다 다른 수열
std::uniform_int_distribution<int> d(1, 100);
std::cout << d(gen) << '\n';
}⚠️ 근거: mt19937 같은 결정적 엔진은 같은 시드에서 항상 같은 수열을 생성하는데, 기본 생성하면 고정된 기본 시드가 쓰여 매 실행이 동일하다. 영향: 게임·시뮬레이션의 다양성이 사라지고, 보안 문맥에서는 수열이 완전히 예측 가능해져 토큰·논스를 공격자가 미리 계산할 수 있다. 대응: random_device 등 비결정적 엔트로피 소스로 엔진을 시드하고, 더 강한 무작위성이 필요하면 시드 시퀀스를 사용한다.Rationale: a deterministic engine like mt19937 produces the same sequence from the same seed, and default-constructing it uses a fixed default seed so every run is identical. Impact: variety in games and simulations disappears, and in a security context the sequence becomes fully predictable, letting an attacker precompute tokens or nonces. Fix: seed the engine from a non-deterministic entropy source such as random_device, using a seed sequence when stronger randomness is needed.
MSC52-CPPMSC · Rule · L1✓ compilableSEI index
값을 반환하는 함수는 모든 종료 경로에서 값을 반환한다Value-returning functions must return a value from all exit paths
❌ 위반 예시Non-compliant example
#include <iostream>
static int sign(int x) {
if (x > 0) return 1;
if (x < 0) return -1;
// x == 0 경로에서 반환 없음 — 그 결과를 사용하면 미정의 동작
}
int main() { std::cout << sign(0) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
static int sign(int x) {
if (x > 0) return 1;
if (x < 0) return -1;
return 0; // 모든 경로에서 명시적 반환
}
int main() { std::cout << sign(0) << '\n'; }⚠️ 근거: void 가 아닌 함수가 return 문 없이 끝까지 흘러 그 반환값을 사용하면 미정의 동작이며, 컴파일러는 이를 가정해 해당 경로를 도달 불가로 최적화할 수 있다. 영향: x==0 같은 누락 경로에서 호출자가 레지스터·스택의 임의 값을 반환값으로 받아, 분기·인덱스로 쓰일 때 예측 불가능한 오동작이나 메모리 손상으로 번진다. 대응: 모든 종료 경로에서 명시적으로 값을 반환하고, 컴파일러 경고(-Wreturn-type)를 켜 누락을 잡는다.Rationale: flowing off the end of a non-void function without a return statement and then using the result is undefined behaviour, and the compiler may assume it and optimize that path as unreachable. Impact: on a missed path like x==0 the caller receives an arbitrary register/stack value as the result, which when used for branching or indexing escalates to unpredictable misbehaviour or memory corruption. Fix: return a value explicitly on every exit path and enable compiler warnings (-Wreturn-type) to catch omissions.
MSC53-CPPMSC · Rule · L1✓ compilableSEI index
[[noreturn]] 으로 표시된 함수에서 반환하지 않는다Do not return from a function declared [[noreturn]]
❌ 위반 예시Non-compliant example
#include <cstdlib>
// [[noreturn]] 인데 일부 경로에서 반환할 수 있음 — 호출자 가정과 모순
[[noreturn]] void fatal(bool can_recover) {
if (can_recover) return; // noreturn 함수가 반환 → 미정의 동작
std::abort();
}
int main() { (void)&fatal; } // 실행 회피(반환 경로 미트리거). 패턴 자체가 결함✅ 준수 예시Compliant example
#include <cstdlib>
#include <stdexcept>
// 모든 경로에서 비반환을 보장
[[noreturn]] void fatal(bool can_recover) {
if (can_recover) throw std::runtime_error("recoverable handled elsewhere");
std::abort(); // 어느 경로든 예외 또는 종료로 끝남
}
int main() { (void)&fatal; }⚠️ 근거: [[noreturn]] 속성은 그 함수가 호출자에게 결코 제어를 되돌려주지 않는다고 컴파일러와 호출자에게 약속하는 것이며, 컴파일러는 이를 믿고 호출 지점 뒤를 도달 불가로 간주해 최적화한다. 영향: 실제로 그 함수가 반환하면 약속이 깨져 미정의 동작이 되고, 호출 뒤에 더는 없다고 가정해 제거·재배치된 코드 때문에 예측 불가능한 흐름·손상이 발생한다. 대응: [[noreturn]] 함수는 모든 경로에서 예외를 던지거나 abort/exit/무한 루프 등으로 끝나게 하여 절대 반환하지 않도록 보장한다.Rationale: the [[noreturn]] attribute promises the compiler and callers that the function never returns control, and the compiler relies on this to treat code after the call site as unreachable and optimize accordingly. Impact: if the function actually returns, the promise is broken — undefined behaviour — and code that was removed or rearranged on the assumption that nothing follows the call leads to unpredictable flow and corruption. Fix: ensure a [[noreturn]] function ends on every path by throwing, or via abort/exit/an infinite loop, so it never returns.
MSC54-CPPMSC · Rule · L1✓ compilableSEI index
시그널 핸들러는 일반(plain old) 함수로 작성한다A signal handler must be a plain old function
❌ 위반 예시Non-compliant example
#include <iostream>
#include <csignal>
#include <string>
static void handler(int) {
std::string s = "got signal"; // 비동기 비안전: 핸들러에서 동적 할당·스트림 사용
std::cout << s << '\n'; // async-signal-safe 하지 않음 — 미정의 동작
}
int main() { std::signal(SIGTERM, handler); std::cout << "installed\n"; }✅ 준수 예시Compliant example
#include <iostream>
#include <csignal>
#include <atomic>
static volatile std::sig_atomic_t g_flag = 0;
extern "C" void on_term(int) { g_flag = 1; } // POF, async-safe 작업만
int main() {
std::signal(SIGTERM, on_term);
std::cout << "installed; flag=" << g_flag << '\n';
}⚠️ 근거: 시그널 핸들러는 프로그램 흐름과 비동기적으로 끼어들 수 있어, C++ 고유 기능(예외, 비trivial 객체 생성·소멸, 스트림 입출력, 동적 할당)을 호출하면 비재진입·비안전 함수를 잘못된 시점에 부르게 되어 미정의 동작이 된다. 영향: 핸들러 안의 std::string·std::cout 사용은 락·힙 상태가 일관되지 않은 순간에 진입해 교착·손상·크래시를 일으킬 수 있다. 대응: 핸들러는 C 연결의 일반 함수로 두고 volatile sig_atomic_t 플래그 설정 같은 async-signal-safe 작업만 한 뒤, 실제 처리는 메인 루프에서 수행한다.Rationale: a signal handler can interrupt program flow asynchronously, so calling C++-specific features (exceptions, non-trivial construction/destruction, stream I/O, dynamic allocation) invokes non-reentrant, unsafe functions at the wrong moment — undefined behaviour. Impact: using std::string or std::cout in a handler may enter while locks or heap state are inconsistent, causing deadlock, corruption, or a crash. Fix: keep the handler a C-linkage plain old function doing only async-signal-safe work such as setting a volatile sig_atomic_t flag, and do the real processing in the main loop.
AUTOSAR C++14
Guidelines for the use of C++14 in critical and safety-related systems
Required / AdvisoryRequired / AdvisoryAutomated / Non-automatedAutomated / Non-automatedA###(AUTOSAR) / M###(MISRA 유래)A###(AUTOSAR-original) / M###(MISRA-origin)
자동차 안전필수 C++14 가이드라인. 규칙 ID는 A0-1-1·M0-1-1 형식(A=AUTOSAR 신규, M=MISRA 유래). 현재 MISRA C++:2023이 승계.Automotive safety-critical C++14 guidelines. Rule IDs use the A0-1-1 / M0-1-1 form (A=AUTOSAR-original, M=MISRA-origin). Now succeeded by MISRA C++:2023.
A0A0 (AUTOSAR)A0 (AUTOSAR-original)
A0-1-1Required · Automated✓ compilable
결과가 사용되지 않는 값(useless assignment)을 두지 않는다A project shall not contain instances of non-volatile variables being given values that are not used
❌ 위반 예시Non-compliant example
#include <iostream>
static int compute() { return 42; }
int main() {
int x = compute(); // compute() 결과를 받았지만
x = 5; // 읽기 전에 덮어씀 — compute() 호출과 그 대입이 죽은 코드
std::cout << x << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int x = 5; // 실제로 쓰일 값만 대입
std::cout << x << '\n';
}⚠️ 근거: 어떤 값을 변수에 넣은 뒤 읽히기 전에 다른 값으로 덮어쓰면 그 첫 계산과 대입은 결과에 아무 영향이 없는 죽은 코드(dead store)다. 영향: 대개 의도한 대입을 빠뜨렸거나 조건 분기가 잘못된 신호이며, 부작용 있는 함수를 호출해 놓고 결과를 버리면 의도와 다른 동작이 숨는다. 대응: 사용되지 않는 계산·대입을 제거하고, 정말 필요한 값만 대입한다.Rationale: assigning a value to a variable and then overwriting it before it is read makes the first computation and assignment a dead store with no effect on the result. Impact: it usually signals a missed assignment or a wrong branch, and discarding the result of a side-effecting call hides behaviour that differs from intent. Fix: remove the unused computation and assignment, keeping only the value actually needed.
A0-1-2Required · Automated✓ compilable
비void 함수의 반환값을 사용한다The value returned by a function having a non-void return type that is not an overloaded operator shall be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
static bool resize_buf(std::vector<int>& v, std::size_t n) {
if (n > 1000) return false; // 실패를 bool 로 알림
v.resize(n); return true;
}
int main() {
std::vector<int> v;
resize_buf(v, 5000); // 반환값 무시 — 실패해도 모른 채 진행
std::cout << v.size() << '\n'; // 0 인데 성공으로 가정하면 버그
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
static bool resize_buf(std::vector<int>& v, std::size_t n) {
if (n > 1000) return false;
v.resize(n); return true;
}
int main() {
std::vector<int> v;
if (!resize_buf(v, 5000)) { std::cout << "resize rejected\n"; return 1; }
std::cout << v.size() << '\n';
}⚠️ 근거: 비void 함수의 반환값은 보통 결과나 성공/실패 같은 의미 있는 정보를 담는데, 이를 사용하지 않으면 그 정보가 소실된다. 영향: 오류 코드를 반환하는 함수의 결과를 무시하면 실패한 상태로 다음 단계를 진행해 데이터 손상·잘못된 결정이 누적된다. 대응: 반환값을 검사·사용하고, 의도적으로 버리는 경우에는 (void) 캐스트로 명시한다.Rationale: the return value of a non-void function usually carries meaningful information such as a result or success/failure, which is lost if not used. Impact: ignoring the result of a function that returns an error code proceeds into the next step in a failed state, accumulating data corruption and wrong decisions. Fix: inspect and use the return value, and when intentionally discarding it make that explicit with a (void) cast.
A0-1-3Required · Automated✓ compilable
정의된 모든 함수(정적/익명 네임스페이스)는 사용되어야 한다Every function defined in an anonymous namespace, or static function, shall be used
❌ 위반 예시Non-compliant example
#include <iostream>
namespace {
int helper() { return 7; } // 정의했지만 어디서도 호출 안 됨 — 죽은 코드
}
int main() {
std::cout << "no call to helper\n";
}✅ 준수 예시Compliant example
#include <iostream>
namespace {
int helper() { return 7; } // 정의한 함수를 실제로 사용
}
int main() {
std::cout << helper() << '\n';
}⚠️ 근거: 내부 링크(정적/익명 네임스페이스)를 가진 함수는 그 번역단위 안에서만 쓸 수 있으므로, 호출되지 않으면 영원히 죽은 코드로 남는다. 영향: 미사용 함수는 유지보수자가 호출 의도를 추측하게 만들고, 호출을 빠뜨린 진짜 버그(연결 누락)를 가리며 바이너리·검토 부담을 늘린다. 대응: 사용되지 않는 정적/익명 함수는 삭제하거나, 빠뜨린 호출을 추가해 실제로 사용한다.Rationale: a function with internal linkage (static or anonymous namespace) can only be used within its translation unit, so if it is never called it remains dead code forever. Impact: an unused function makes maintainers guess the intended call site, can mask a real bug (a missed call), and adds binary and review burden. Fix: delete unused static/anonymous functions, or add the missing call so they are actually used.
A0-4-1Required · Non-automated✓ compilable
부동소수 구현은 IEEE 754(IEC 60559)를 따라야 한다Floating-point implementation shall comply with IEEE 754
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cmath>
// IEEE 754 준수 여부를 확인하지 않고 NaN/Inf 동작에 의존
int main() {
double x = 0.0 / 0.0; // IEEE 면 NaN, 비준수 환경에선 동작이 다름
if (x != x) std::cout << "treated as NaN\n"; // Na!=Na 가정에 의존
else std::cout << "no NaN semantics\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <limits>
// IEEE 754 준수를 컴파일 타임에 강제 — 비준수 플랫폼은 빌드 자체가 실패
static_assert(std::numeric_limits<double>::is_iec559,
"IEEE 754 (IEC 60559) floating point is required");
int main() {
std::cout << "IEEE 754 guaranteed at compile time\n";
}⚠️ 근거: 반올림 규칙, NaN·무한대 같은 특수값, 비정규수 처리 같은 부동소수 의미론은 IEEE 754 를 따를 때만 보장되며, 컴파일러 플래그(-ffast-math 등)나 플랫폼에 따라 달라질 수 있다. 영향: IEEE 비준수 환경에서 Na != NaN 같은 가정에 의존하면 비교·예외 처리가 조용히 다르게 동작해 안전필수 계산 결과가 흔들린다. 대응: std::numeric_limits<T>::is_iec559 를 static_assert 로 검사해 비준수 플랫폼에서 빌드를 막고, 부동소수 동작 가정을 명시적으로 보증한다.Rationale: floating-point semantics such as rounding rules, special values like NaN and infinity, and subnormal handling are guaranteed only under IEEE 754, and can change with compiler flags (e.g. -ffast-math) or platform. Impact: relying on assumptions like NaN != NaN in a non-IEEE environment makes comparisons and exception handling silently differ, destabilizing safety-critical results. Fix: check std::numeric_limits<T>::is_iec559 with static_assert to block builds on non-compliant platforms and explicitly guarantee the assumed floating-point behaviour.
A0-1-4Required · Automated✓ compilable📄 공식 예제Official example
There shall be no unused named parameters in non-virtual functions.There shall be no unused named parameters in non-virtual functions.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstdint>
#include <cmath>
#include <set>
//% $Id: A0-1-4.cpp 305588 2018-01-29 11:07:35Z michal.szczepankiewicz $
#include <type_traits>
#include <string>
//Logger.hpp
class Logger
{
public:
struct console_t {};
struct file_t {};
constexpr static console_t console = console_t();
constexpr static file_t file = file_t();
void init(console_t);
void init(file_t, const std::string& prefix);
};
//Logger.cpp
void Logger::init(console_t)
{
//initialization for a console logger
}
void Logger::init(file_t, const std::string& prefix)
{
//initialization for a file logger for a given prefix path
}
//Message.h
struct MessagePolicy {};
struct WriteMessagePolicy final : public MessagePolicy { };
template <typename T> struct is_mutable : std::false_type {};
template <> struct is_mutable<WriteMessagePolicy> : std::true_type {};
template <typename T, typename Policy = MessagePolicy>
class Message
{
public:
static_assert(std::is_base_of<MessagePolicy, Policy>::value == true, "Given parameter is not derived from MessagePolicy");
using value_type = T;
template<typename U = void>
void set(T&& u, typename std::enable_if<is_mutable<Policy>::value, U>::type *
= 0)
{
v = u;
}
private:
value_type v;
};
int main(int, char **)
{
Logger log;
log.init(Logger::console);
log.init(Logger::file, std::string("/tmp/"));
Message<uint8_t> read;
Message<uint8_t, WriteMessagePolicy> write;
//read.set(uint8_t(12)); Compilation error
write.set(uint8_t(12));
return 0;
}⚠️ Unused named parameters are often a result of a design changes and can lead to
mismatched parameter lists.
Note: This rule does not apply to unnamed parameters, as they are widely used in
SFINAE and concept compliance.
See also:
• C++ Core Guidelines [11]: F .9: Unused parameters should be unnamedUnused named parameters are often a result of a design changes and can lead to
mismatched parameter lists.
Note: This rule does not apply to unnamed parameters, as they are widely used in
SFINAE and concept compliance.
See also:
• C++ Core Guidelines [11]: F .9: Unused parameters should be unnamed
A0-1-5Required · Automated✓ compilable📄 공식 예제Official example
There shall be no unused named parameters in the set of parameters for a virtual function and all the functions that override it.There shall be no unused named parameters in the set of parameters for a virtual function and all the functions that override it.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A0-1-5.cpp 305588 2018-01-29 11:07:35Z michal.szczepankiewicz $
#include <cstdint>
#include <vector>
//Compressor.h
class Compressor
{
public:
using raw_memory_type = std::vector<uint8_t>;
raw_memory_type Compress(const raw_memory_type& in, uint8_t ratio);
private:
virtual raw_memory_type __Compress(const raw_memory_type& in, uint8_t ratio)
= 0;
};
//Compressor.cpp
Compressor::raw_memory_type Compressor::Compress(const raw_memory_type& in,
uint8_t ratio)
{
return __Compress(in, ratio);
}
//JPEGCompressor.h
class JPEGCompressor : public Compressor
{
private:
raw_memory_type __Compress(const raw_memory_type& in, uint8_t ratio) override
;
};
//JPEGCompressor.cpp
JPEGCompressor::raw_memory_type JPEGCompressor::__Compress(const raw_memory_type&
in, uint8_t ratio)
{
raw_memory_type ret;
//jpeg compression, ratio used
return ret;
}
//HuffmanCompressor.h
class HuffmanCompressor : public Compressor
{
private:
raw_memory_type __Compress(const raw_memory_type& in, uint8_t) override;
};
//JPEGCompressor.cpp
HuffmanCompressor::raw_memory_type HuffmanCompressor::__Compress(const
raw_memory_type& in, uint8_t)
{
raw_memory_type ret;
//Huffman compression, no ratio parameter available in the algorithm
return ret;
}⚠️ Unused named parameters are often a result of a design changes and can lead to
mismatched parameter lists.
Note: This rule does not apply to unnamed parameters, as overridden methods for
some subclasses may need additional parameters.
See also:
• C++ Core Guidelines [11]: F .9: Unused parameters should be unnamedUnused named parameters are often a result of a design changes and can lead to
mismatched parameter lists.
Note: This rule does not apply to unnamed parameters, as overridden methods for
some subclasses may need additional parameters.
See also:
• C++ Core Guidelines [11]: F .9: Unused parameters should be unnamed
A0-1-6Advisory · Automated✓ compilable📄 공식 예제Official example
There should be no unused type declarations.There should be no unused type declarations.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A0-1-6.cpp$
#include <cstdint>
std::uint32_t Fn() noexcept
{
using LocalUIntPtr = std::uint32_t *;
return 0U;
}⚠️ Unused type declarations make code unnecessary more complex and complicate
review process. Unused types can be redundant or be unused by mistake.
Note: Libraries development require introduction new types not used internally .
See also:
• MISRA C++ 2008 [7]: Rule 0-1-5 reclassified from required to advisory .
6.0.2 StorageUnused type declarations make code unnecessary more complex and complicate
review process. Unused types can be redundant or be unused by mistake.
Note: Libraries development require introduction new types not used internally .
See also:
• MISRA C++ 2008 [7]: Rule 0-1-5 reclassified from required to advisory .
6.0.2 Storage
A0-4-2Required · Automated✓ compilable📄 공식 예제Official example
Type long double shall not be used.Type long double shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A0-4-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
void Fn() noexcept
{
float f1{0.1F}; // Compliant
double f2{0.1}; // Compliant
long double f3{0.1L}; // Non-compliant
}⚠️ The width of long double type, and therefore width of the significand, is implementation-
defined.
The width of long double type can be either:
• 64 bits, as the C++14 Language Standard allows long double to provide at least
as much precision as type double does, or
• 80 bits, as the IEEE 754 standard allows extended precision formats (see:
Extended-Precision-Format), or
• 128 bits, as the IEEE 754 standard defines quadruple precision format
See also:
• noneThe width of long double type, and therefore width of the significand, is implementation-
defined.
The width of long double type can be either:
• 64 bits, as the C++14 Language Standard allows long double to provide at least
as much precision as type double does, or
• 80 bits, as the IEEE 754 standard allows extended precision formats (see:
Extended-Precision-Format), or
• 128 bits, as the IEEE 754 standard defines quadruple precision format
See also:
• none
A0-4-3Required · Automated✓ compilable📄 공식 예제Official example
The implementations in the chosen compiler shall strictly comply with the C++14 Language Standard.The implementations in the chosen compiler shall strictly comply with the C++14 Language Standard.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Since the ISO/IEC 14882:2014 C++ Language Standard, the integer division and
// modulo operator results are no longer implementation-defined. The sentence "if both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined" from ISO/IEC 14882:2003 is no longer present
// in the standard since ISO/IEC 14882:2011. Note that this rule also covers the modulo
// operator as it is defined in terms of integer division.
// Deducing the type of an auto variable initialized using auto x{<value>} is
// implemented differently depending on the language standard. In C++11 and C++14,
// x will be a std::initializer_list, whereas in C++17, x will be a type deduced
// from the specified <value>. Furthermore, some compilers may already implement
// the C++17 behavior even when operated in C++14 mode.
// Note: Rule A8-5-3 forbids initializing an auto variable with the curly braces ( {})
// syntax.
// Other features provided by the chosen compiler also should follow the ISO/IEC
// 14882:2014 C++ Language Standard.⚠️ It is important to determine whether implementations provided by the chosen compiler
strictly follow the ISO/IEC 14882:2014 C++ Language Standard.
See also:
• MISRA C++ 2008 [7]: Rule 1-0-3 The implementation of integer division in the
chosen compiler shall be determined and documented.
• C++ Core Guidelines [11]: F .46: int is the return type for main().It is important to determine whether implementations provided by the chosen compiler
strictly follow the ISO/IEC 14882:2014 C++ Language Standard.
See also:
• MISRA C++ 2008 [7]: Rule 1-0-3 The implementation of integer division in the
chosen compiler shall be determined and documented.
• C++ Core Guidelines [11]: F .46: int is the return type for main().
A0-4-4Required · Partially automated✓ compilable📄 공식 예제Official example
Range, domain and pole errors shall be checked when using math functions.Range, domain and pole errors shall be checked when using math functions.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A0-4-4.cpp 305588 2018-01-29 11:07:35Z michal.szczepankiewicz $
#include <cmath>
#include <cfenv>
float Foo(float val)
{
//non-compliant, domain error for negative values
return std::sqrt(val);
}
float Bar(float val)
{
//non-compliant
//domain error for val < 0
//pole error for val==0
return std::log(val);
}
// \return true, if a range error occurred
bool DetectRangeErr()
{
return ((math_errhandling & MATH_ERREXCEPT) &&
(fetestexcept(FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW) != 0));
}⚠️ The C Standard defines the following types of error related to math functions
specifically:
• domain error – input arguments are outside a domain of a mathematical function
definition
• pole error – for finite input arguments a function gives an exact infinite result
• range error – a result of a mathematical function cannot be represented by the
return type limitations
Domain and pole errors require that bounds are checked for input parameters before
calling a mathematical function. Range errors in most cases cannot be prevented, as
their occurrence mostly depend on the implementation of floating-point numbers (see
A0-4-1).
Checking for range errors for multi-threaded applications require that floating-point
exception state is in a per-thread basis.
See also:
• SEI CERT C++ Coding Standard [10]: FLP32-C: Prevent or detect domain and
range errors in math functions
6.1 General
6.1.1 ScopeThe C Standard defines the following types of error related to math functions
specifically:
• domain error – input arguments are outside a domain of a mathematical function
definition
• pole error – for finite input arguments a function gives an exact infinite result
• range error – a result of a mathematical function cannot be represented by the
return type limitations
Domain and pole errors require that bounds are checked for input parameters before
calling a mathematical function. Range errors in most cases cannot be prevented, as
their occurrence mostly depend on the implementation of floating-point numbers (see
A0-4-1).
Checking for range errors for multi-threaded applications require that floating-point
exception state is in a per-thread basis.
See also:
• SEI CERT C++ Coding Standard [10]: FLP32-C: Prevent or detect domain and
range errors in math functions
6.1 General
6.1.1 Scope
A2A2 (AUTOSAR)A2 (AUTOSAR-original)
A2-7-2Required · Automated✓ compilable
코드 섹션을 주석 처리(commented-out)로 비활성화하지 않는다Sections of code shall not be commented out
❌ 위반 예시Non-compliant example
#include <iostream>
static void transform(int& d) { d *= 2; }
static void notify(int d) { std::cout << "notify " << d << '\n'; }
int main() {
int d = 10;
// transform(d); // 의도가 불명확한 주석 처리 — 비활성? 임시? 삭제 예정?
notify(d);
}✅ 준수 예시Compliant example
#include <iostream>
static void transform(int& d) { d *= 2; }
static void notify(int d) { std::cout << "notify " << d << '\n'; }
#ifndef DISABLE_TRANSFORM
#define USE_TRANSFORM 1
#endif
int main() {
int d = 10;
#if USE_TRANSFORM
transform(d); // 조건부 컴파일로 의도를 명시
#endif
notify(d);
}⚠️ 근거: 주석으로 막은 코드는 그것이 영구 삭제 대상인지, 일시 비활성인지, 디버깅 잔재인지 의도를 전혀 드러내지 못한다. 영향: 시간이 지나면 주석 처리된 코드가 본문과 어긋난 채 방치되어 오해를 부르고, 리뷰·검색을 어지럽힌다(이력은 버전관리로 충분히 추적된다). 대응: 임시 비활성은 조건부 컴파일(#if)·기능 플래그로 의도를 드러내고, 더 이상 필요 없는 코드는 삭제한다.Rationale: commented-out code reveals nothing about intent — whether it is slated for permanent deletion, temporarily disabled, or leftover debugging. Impact: over time it drifts out of sync with the live code, misleads readers, and clutters reviews and searches (history is already tracked by version control). Fix: express temporary disabling with conditional compilation (#if) or feature flags to show intent, and delete code that is no longer needed.
A2-10-1Required · Automated✓ compilable
내부 범위 식별자가 외부 범위 식별자를 가리지(shadow) 않게 한다An identifier declared in an inner scope shall not hide an identifier declared in an outer scope
❌ 위반 예시Non-compliant example
#include <iostream>
static int count = 100; // 외부(파일) 범위
static void f() {
int count = 5; // 같은 이름으로 외부 count 를 가림(shadow)
std::cout << count << '\n'; // 5 — 어느 count 인지 혼동
}
int main() { f(); std::cout << count << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
static int g_count = 100; // 외부 범위는 g_ 접두사로 구분
static void f() {
int local = 5; // 다른 이름 — 가림 없음
std::cout << local << '\n';
}
int main() { f(); std::cout << g_count << '\n'; }⚠️ 근거: 안쪽 범위에서 바깥 범위와 같은 이름을 선언하면 안쪽 이름이 바깥 이름을 가려, 그 구간에서는 의도와 다른 객체를 참조할 수 있다. 영향: 리팩터링·복사 과정에서 가려진 변수를 수정한 줄 알았는데 지역 사본만 바뀌는 식의 미묘한 버그가 생기고, 코드 리뷰에서 어느 변수인지 즉시 알기 어렵다. 대응: 내부 식별자에 다른 이름(또는 접두사 규칙)을 부여해 가림을 없애고, 컴파일러 경고(-Wshadow)를 켠다.Rationale: declaring the same name in an inner scope as in an outer scope hides the outer name, so within that region a different object than intended may be referenced. Impact: during refactoring or copy-paste a subtle bug arises where a line thought to modify the outer variable changes only a local copy, and reviewers cannot tell at a glance which variable is meant. Fix: give inner identifiers different names (or a prefix convention) to remove the shadowing, and enable compiler warnings (-Wshadow).
A2-13-1Required · Automated✓ compilable
표준에 정의된 이스케이프 시퀀스만 사용한다Only those escape sequences that are defined in the C++ Standard shall be used
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
const char* s = "col1\qcol2"; // \q 는 표준에 없는 이스케이프 — 구현정의
std::cout << s << '\n'; // 어떻게 처리될지 불확실
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
const char* s = "col1\tcol2"; // \t 는 표준 이스케이프(탭)
std::cout << s << '\n';
}⚠️ 근거: C++ 표준은 \n, \t, \\ 등 허용되는 이스케이프 시퀀스 집합을 명시하며, 그 밖의 역슬래시 조합(\q 등)은 조건부 지원이거나 구현정의 동작이다. 영향: 비표준 이스케이프는 컴파일러마다 경고만 내고 다르게 해석하거나 무시해, 의도한 문자열과 실제 내용이 달라지는 이식성 결함이 된다. 대응: 표준에 정의된 이스케이프만 사용하고, 특수 문자는 \x·\u 같은 표준 형식이나 명명 상수로 표현한다.Rationale: the C++ Standard specifies the allowed set of escape sequences (\n, \t, \\, etc.), and any other backslash combination (such as \q) is conditionally-supported or implementation-defined. Impact: a non-standard escape is interpreted differently or ignored across compilers with only a warning, making the intended string differ from the actual content — a portability defect. Fix: use only standard-defined escapes, and represent special characters with standard forms like \x/\u or named constants.
A2-13-3Required · Automated✓ compilable
wchar_t 타입을 사용하지 않는다Type wchar_t shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
wchar_t buf[] = L"hey"; // 요소 폭이 플랫폼마다 다름(Windows 2, Unix 4)
std::cout << "sizeof wchar_t = " << sizeof(wchar_t) << '\n'; // 2 또는 4 — 비이식
(void)buf;
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstdint>
int main() {
char16_t u16[] = u"hey"; // 폭이 16비트로 고정
char32_t u32[] = U"hey"; // 폭이 32비트로 고정
std::cout << sizeof(u16[0]) << ' ' << sizeof(u32[0]) << '\n'; // 2 4 (이식 가능)
}⚠️ 근거: wchar_t 의 크기와 인코딩은 구현정의라 Windows 에서는 16비트(UTF-16), 대부분의 유닉스에서는 32비트(UTF-32)로 서로 다르다. 영향: wchar_t 로 직렬화·파일 포맷·프로토콜을 다루면 플랫폼 간에 폭과 인코딩이 어긋나 데이터가 깨지고, 코드가 한 플랫폼에 고착된다. 대응: 폭이 표준으로 고정된 char16_t/char32_t(및 std::u16string/u32string)를 사용해 이식 가능한 유니코드 처리를 한다.Rationale: the size and encoding of wchar_t are implementation-defined, being 16-bit (UTF-16) on Windows but 32-bit (UTF-32) on most Unix systems. Impact: using wchar_t for serialization, file formats, or protocols mismatches width and encoding across platforms, corrupting data and locking code to one platform. Fix: use char16_t/char32_t (and std::u16string/u32string) whose widths are fixed by the standard for portable Unicode handling.
A2-10-4Required · Automated✓ compilable📄 공식 예제Official example
The identifier name of a non-member object with static storage duration or static function shall not be reused within a namespace.The identifier name of a non-member object with static storage duration or static function shall not be reused within a namespace.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-10-4.cpp 305382 2018-01-26 06:32:15Z michal.szczepankiewicz $
#include <cstdint>
// f1.cpp
namespace ns1
{
static std::int32_t globalvariable = 0;
}
// f2.cpp
namespace ns1
{
// static std::int32_t globalvariable = 0; // Non-compliant - identifier reused
// in ns1 namespace in f1.cpp
}
namespace ns2
{
static std::int32_t globalvariable =
0; // Compliant - identifier reused, but in another namespace
}
// f3.cpp
static std::int32_t globalvariable =
0; // Compliant - identifier reused, but in another namespace⚠️ No identifier with static storage duration should be re-used in the same namespace
across any source files in the project.
This may lead to the developer or development tool confusing the identifier with another
one.
See also:
• MISRA C++ 2008 [7]: advisory 2-10-5 The identifier name of a non-member
object or function with static storage duration should not be reused.No identifier with static storage duration should be re-used in the same namespace
across any source files in the project.
This may lead to the developer or development tool confusing the identifier with another
one.
See also:
• MISRA C++ 2008 [7]: advisory 2-10-5 The identifier name of a non-member
object or function with static storage duration should not be reused.
A2-10-5Advisory · Automated✓ compilable📄 공식 예제Official example
An identifier name of a function with static storage duration or a non-member object with external or internal linkage should not be reused.An identifier name of a function with static storage duration or a non-member object with external or internal linkage should not be reused.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-10-5.cpp 305382 2018-01-26 06:32:15Z michal.szczepankiewicz $
#include <cstdint>
// f1.cpp
namespace n_s1
{
static std::int32_t globalvariable = 0;
}
static std::int32_t filevariable = 5; // Compliant - identifier not reused
static void Globalfunction();
// f2.cpp
namespace n_s1
{
// static std::int32_t globalvariable = 0; // Non-compliant - identifier reused
static std::int16_t modulevariable = 10; // Compliant - identifier not reused
}
namespace n_s2
{
static std::int16_t modulevariable2 = 20;
}
static void Globalfunction(); // Non-compliant - identifier reused
static std::int16_t modulevariable2 = 15; // Non-compliant - identifier reused⚠️ Regardless of scope, no identifier with static storage duration should be re-used across
any source files in the project. This includes objects or functions with external linkage
and any objects or functions with static storage class specifier. While the compiler
can understand this, the possibility exists for the developer or development tool to
incorrectly associate unrelated variables with the same name.
Note: This rule does not apply to objects without linkage, e.g. function local static
objects.
See also:
• MISRA C++ 2008 [7]: advisory 2-10-5 The identifier name of a non-member
object or function with static storage duration should not be reused.
6.2.11 KeywordsRegardless of scope, no identifier with static storage duration should be re-used across
any source files in the project. This includes objects or functions with external linkage
and any objects or functions with static storage class specifier. While the compiler
can understand this, the possibility exists for the developer or development tool to
incorrectly associate unrelated variables with the same name.
Note: This rule does not apply to objects without linkage, e.g. function local static
objects.
See also:
• MISRA C++ 2008 [7]: advisory 2-10-5 The identifier name of a non-member
object or function with static storage duration should not be reused.
6.2.11 Keywords
A2-10-6Required · Automated✓ compilable📄 공식 예제Official example
A class or enumeration name shall not be hidden by a variable, function or enumerator declaration in the same scope.A class or enumeration name shall not be hidden by a variable, function or enumerator declaration in the same scope.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-10-6.cpp 313821 2018-03-27 11:16:14Z michal.szczepankiewicz $
#include <cstdint>
namespace NS1 {
class G {};
void G() {} //non-compliant, hides class G
}
namespace NS2 {
enum class H { VALUE=0, };
std::uint8_t H = 17; //non-compliant, hides
//scoped enum H
}
namespace NS3 {
class J {};
enum H //does not hide NS2::H, but non-compliant to A7-2-3
{
J=0, //non-compliant, hides class J
};
}
int main(void)
{
NS1::G();
//NS1::G a; //compilation error, NS1::G is a function
//after a name lookup procedure
class NS1::G a{}; //accessing hidden class type name
enum NS2::H b ; //accessing scoped enum NS2::H
NS2::H = 7;
class NS3::J c{}; //accessing hidden class type name
std::uint8_t z = NS3::J;
}⚠️ C++ Language Standard [3] defines that a class or enumeration name can be hidden
by an explicit declaration (of the same name) of a variable, data member, function, or
enumerator in the same scope, regardless of the declaration order. Such declarations
can be misleading for a developer and can lead to compilation errors.
See also:
• ISO/IEC 14882:2014 [3]: 3.3.10.2: [basic.scope.hiding]
• MISRA C++ 2008 [7]: 2-10-6: If an identifier refers to a type, it shall not also refer
to an object or a function in the same scope.
• HIC++ v4.0 [9]: 3.1.1: Do not hide declarations.C++ Language Standard [3] defines that a class or enumeration name can be hidden
by an explicit declaration (of the same name) of a variable, data member, function, or
enumerator in the same scope, regardless of the declaration order. Such declarations
can be misleading for a developer and can lead to compilation errors.
See also:
• ISO/IEC 14882:2014 [3]: 3.3.10.2: [basic.scope.hiding]
• MISRA C++ 2008 [7]: 2-10-6: If an identifier refers to a type, it shall not also refer
to an object or a function in the same scope.
• HIC++ v4.0 [9]: 3.1.1: Do not hide declarations.
A2-11-1Required · Automated✓ compilable📄 공식 예제Official example
Volatile keyword shall not be used.Volatile keyword shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A2-11-1: Volatile keyword shall not be used. // No code example provided in the official guideline PDF.
⚠️ The volatile keyword disables compiler optimizations for a particular variable or object’s
value in case those values may change in ways not specified by the language (e.g.
object representing a hardware register). It is error prone and often misused by
developers, as they expect this is equal to variable or object’s value being atomic.
Note: The main intention of this rule is to eliminate incorrect usages of volatile keyword
and force developers to precisely document each usage of volatile keyword.
See also:
• JSF December 2005 [8]: AV Rule 205: The volatile keyword shall not be used
unless directly interfacing with hardware.
• HIC++ v4.0 [9]: 18.2.3: Do not share volatile data between threads.
• C++ Core Guidelines [11]: CP .8: Don’t try to use volatile for synchronization.
• C++ Core Guidelines [11]: CP .200: Use volatile only to talk to non-C++ memory .
6.2.13 LiteralsThe volatile keyword disables compiler optimizations for a particular variable or object’s
value in case those values may change in ways not specified by the language (e.g.
object representing a hardware register). It is error prone and often misused by
developers, as they expect this is equal to variable or object’s value being atomic.
Note: The main intention of this rule is to eliminate incorrect usages of volatile keyword
and force developers to precisely document each usage of volatile keyword.
See also:
• JSF December 2005 [8]: AV Rule 205: The volatile keyword shall not be used
unless directly interfacing with hardware.
• HIC++ v4.0 [9]: 18.2.3: Do not share volatile data between threads.
• C++ Core Guidelines [11]: CP .8: Don’t try to use volatile for synchronization.
• C++ Core Guidelines [11]: CP .200: Use volatile only to talk to non-C++ memory .
6.2.13 Literals
A2-13-2Required · Automated✓ compilable📄 공식 예제Official example
String literals with different encoding prefixes shall not be concatenated.String literals with different encoding prefixes shall not be concatenated.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-13-2.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $ char16_t nArray[] = u"Hello" u"World"; // Compliant, "u" stands for char16_t type char32_t nArray2[] = U"Hello" U"World"; // Compliant, "U" stands for char32_t type wchar_t wArray[] = L"Hello" L"World"; // Compliant, "L" stands for wchar_t type - violates A2-13-3 // rule. wchar_t mixed1[] = "Hello" L"World"; // Compliant char32_t mixed2[] = "Hello" U"World"; // Compliant char16_t mixed3[] = "Hello" u"World"; // Compliant // wchar_t mixed1[] = u"Hello" L"World"; // Non-compliant - compilation error // char32_t mixed2[] = u"Hello" U"World"; // Non-compliant - compilation error
⚠️ Concatenation of wide and narrow string literals leads to undefined behavior.
“In translation phase 6 (2.2), adjacent string-literals are concatenated. If both string-
literals have the same encoding-prefix, the resulting concatenated string literal has
that encoding-prefix. If one string-literal has no encoding-prefix, it is treated as a
string-literal of the same encoding-prefix as the other operand. If a UTF-8 string
literal token is adjacent to a wide string literal token, the program is ill-formed.
Any other concatenations are conditionally-supported with implementation-defined
behavior. [ Note: This concatenation is an interpretation, not a conversion. Because
the interpretation happens in translation phase 6 (after each character from a literal has
been translated into a value from the appropriate character set), a string-literal’s initial
rawness has no effect on the interpretation or well-formedness of the concatenation.
-end note ]” [C++14 Language Standard] [3]
See also:
• MISRA C++ 2008 [7]: required 2-13-5 Narrow and wide string literals shall not be
concatenated.
• HIC++ v4.0 [9]: 2.5.1 Do not concatenate strings with different encoding prefixesConcatenation of wide and narrow string literals leads to undefined behavior.
“In translation phase 6 (2.2), adjacent string-literals are concatenated. If both string-
literals have the same encoding-prefix, the resulting concatenated string literal has
that encoding-prefix. If one string-literal has no encoding-prefix, it is treated as a
string-literal of the same encoding-prefix as the other operand. If a UTF-8 string
literal token is adjacent to a wide string literal token, the program is ill-formed.
Any other concatenations are conditionally-supported with implementation-defined
behavior. [ Note: This concatenation is an interpretation, not a conversion. Because
the interpretation happens in translation phase 6 (after each character from a literal has
been translated into a value from the appropriate character set), a string-literal’s initial
rawness has no effect on the interpretation or well-formedness of the concatenation.
-end note ]” [C++14 Language Standard] [3]
See also:
• MISRA C++ 2008 [7]: required 2-13-5 Narrow and wide string literals shall not be
concatenated.
• HIC++ v4.0 [9]: 2.5.1 Do not concatenate strings with different encoding prefixes
A2-13-4Required · Automated✓ compilable📄 공식 예제Official example
String literals shall not be assigned to non-constant pointers.String literals shall not be assigned to non-constant pointers.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-13-4.cpp 307578 2018-02-14 14:46:20Z michal.szczepankiewicz $
int main(void)
{
char* nc1 = "AUTOSAR"; //non-compliant
char nc2[] = "AUTOSAR"; //compliant with A2-13-4, non-compliant with A18
-1-1
char nc3[8] = "AUTOSAR"; //compliant with A2-13-4, non-compliant with A18
-1-1
nc1[3] = 'a'; // undefined behaviour
const char * c1 = "AUTOSAR"; //compliant
const char c2[] = "AUTOSAR"; //compliant with A2-13-4, non-compliant
with A18-1-1
const char c3[8] = "AUTOSAR"; //compliant with A2-13-4, non-compliant
with A18-1-1
//c1[3] = 'a'; //compilation error
return 0;
}⚠️ Since C++0x, there was a change in subclause 2.13.5 for string literals. T o prevent
from calling an inappropriate function that might modify its argument, the type of a
string literal was changed from “array of char” to “array of const char”.
Such a usage is deprecated by the Standard and reported by a compiler as a warning.
This rule is deliberately redundant, in case rules A1-1-1 and A1-4-3 are disabled in a
project.
See also:
• JSF December 2005 [8]: AV Rule 151.1: A string literal shall not be modified.
6.3 Basic concepts
6.3.1 Declarations and definitionsSince C++0x, there was a change in subclause 2.13.5 for string literals. T o prevent
from calling an inappropriate function that might modify its argument, the type of a
string literal was changed from “array of char” to “array of const char”.
Such a usage is deprecated by the Standard and reported by a compiler as a warning.
This rule is deliberately redundant, in case rules A1-1-1 and A1-4-3 are disabled in a
project.
See also:
• JSF December 2005 [8]: AV Rule 151.1: A string literal shall not be modified.
6.3 Basic concepts
6.3.1 Declarations and definitions
A2-13-5Advisory · Automated✓ compilable📄 공식 예제Official example
Hexadecimal constants should be upper case.Hexadecimal constants should be upper case.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-13-5.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
#include <cstdint>
int main(void)
{
std::int16_t a = 0x0f0f; //non-compliant
std::int16_t b = 0x0f0F; //non-compliant
std::int16_t c = 0x0F0F; //compliant
return 0;
}⚠️ Using upper case literals for hexadecimal constants makes the source code consistent
in this matter and removes a potential developer confusion.
See also:
• JSF December 2005 [8]: AV Rule 150: Hexadecimal constants will be
represented using all uppercase letters.Using upper case literals for hexadecimal constants makes the source code consistent
in this matter and removes a potential developer confusion.
See also:
• JSF December 2005 [8]: AV Rule 150: Hexadecimal constants will be
represented using all uppercase letters.
A2-13-6Required · Automated✓ compilable📄 공식 예제Official example
Universal character names shall be used only inside character or string literals.Universal character names shall be used only inside character or string literals.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-13-6.cpp 307578 2018-02-14 14:46:20Z michal.szczepankiewicz $
#include <string>
void F()
{
const std::string c = "\U0001f34c"; // Compliant
}
//non-compliant
void \U0001f615()
{
// }⚠️ Using universal-character-names to define a language identifier can be confusing for a
developer and may be troublesome to use this identifier in the source code.Using universal-character-names to define a language identifier can be confusing for a
developer and may be troublesome to use this identifier in the source code.
A2-3-1Required · Automated✓ compilable📄 공식 예제Official example
Only those characters specified in the C++ Language Standard basic source character set shall be used in the source code.Only those characters specified in the C++ Language Standard basic source character set shall be used in the source code.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A2-3-1.cpp 307578 2018-02-14 14:46:20Z michal.szczepankiewicz $
#include <cstdint>
void Fn() noexcept
{
std::int32_t sum = 0; // Compliant
// std::int32_t £_value = 10; // Non-compliant
// sum += £_value; // Non-compliant
// Variable sum stores £ pounds // Non-compliant
}⚠️ “The basic source character set consists of 96 characters: the space character, the
control characters representing horizontal tab, vertical tab, form feed, and new-line,
plus the following 91 graphical characters: a b c d e f g h i j k l m n o p q r s t u v w x y
z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _ { } [ ] # (
) < > % : ; . ? * + - / ^ & | ~ ! =, \ " ’
” [C++ Language Standard [3]]
Exception:
It is permitted to use other characters inside the text of a wide string and a UTF-8
encoded string literal.
It is also permitted to use a character @ inside comments. See rule A2-7-3.
See also:
• JSF December 2005 [8]: AV Rule 9: Only those characters specified in the C++
basic source character set will be used.
6.2.5 Alternative tokens“The basic source character set consists of 96 characters: the space character, the
control characters representing horizontal tab, vertical tab, form feed, and new-line,
plus the following 91 graphical characters: a b c d e f g h i j k l m n o p q r s t u v w x y
z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _ { } [ ] # (
) < > % : ; . ? * + - / ^ & | ~ ! =, \ " ’
” [C++ Language Standard [3]]
Exception:
It is permitted to use other characters inside the text of a wide string and a UTF-8
encoded string literal.
It is also permitted to use a character @ inside comments. See rule A2-7-3.
See also:
• JSF December 2005 [8]: AV Rule 9: Only those characters specified in the C++
basic source character set will be used.
6.2.5 Alternative tokens
A2-5-1Required · Automated✓ compilable📄 공식 예제Official example
Trigraphs shall not be used.Trigraphs shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-5-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <iostream>
void Fn1()
{
std::cout << "Enter date ??/??/??"; // Non-compliant, ??/??/?? becomes \\??
// after trigraph translation
}
void Fn2()
{
std::cout << "Enter date dd/mm/yy"; // Compliant
}⚠️ Trigraphs are denoted to be a sequence of 2 question marks followed by a specified
third character (e.g. ??’ represents a ~character. They can cause accidental confusion
with other uses of two question marks.
The Trigraphs are: ??=, ??/, ??’, ??(, ??), ??!, ??<, ??>, ??-.
See also:
• MISRA C++2008: Rule 2-3-1 (Required) Trigraphs shall not be used.
• JSF December 2005 [8]: AV Rule 11 Trigraphs will not be used.
• HIC++ v4.0 [9]: 2.2.1 Do not use digraphs or trigraphs.Trigraphs are denoted to be a sequence of 2 question marks followed by a specified
third character (e.g. ??’ represents a ~character. They can cause accidental confusion
with other uses of two question marks.
The Trigraphs are: ??=, ??/, ??’, ??(, ??), ??!, ??<, ??>, ??-.
See also:
• MISRA C++2008: Rule 2-3-1 (Required) Trigraphs shall not be used.
• JSF December 2005 [8]: AV Rule 11 Trigraphs will not be used.
• HIC++ v4.0 [9]: 2.2.1 Do not use digraphs or trigraphs.
A2-5-2Required · Automated✓ compilable📄 공식 예제Official example
Digraphs shall not be used.Digraphs shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A2-5-2.cpp 305382 2018-01-26 06:32:15Z michal.szczepankiewicz $
class A
{
public:
void F2() {}
};
// void fn1(A * a<:10:>) // Non-compliant
// <%
// a<:0:>->f2();
// %>
void Fn2(A * a[10]) // Compliant, equivalent to the above
{
a[0]->F2();
}⚠️ The digraphs are: <%, %>, <:, :>, %:, %:%:.
The use of digraphs may not meet developer expectations.
See also:
• MISRA C++ 2008 [7]: advisory 2-5-1 Digraphs should not be used.
• JSF December 2005 [8]: 4.4.1 AV Rule 12 The following digraphs will not be
used.
• HIC++ v4.0 [9]: 2.2.1 Do not use digraphs or trigraphs.
6.2.7 CommentsThe digraphs are: <%, %>, <:, :>, %:, %:%:.
The use of digraphs may not meet developer expectations.
See also:
• MISRA C++ 2008 [7]: advisory 2-5-1 Digraphs should not be used.
• JSF December 2005 [8]: 4.4.1 AV Rule 12 The following digraphs will not be
used.
• HIC++ v4.0 [9]: 2.2.1 Do not use digraphs or trigraphs.
6.2.7 Comments
A2-7-1Required · Automated✓ compilable📄 공식 예제Official example
The character \ shall not occur as a last character of a C++ comment.The character \ shall not occur as a last character of a C++ comment.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A2-7-1.cpp 305382 2018-01-26 06:32:15Z michal.szczepankiewicz $
#include <cstdint>
void Fn() noexcept
{
std::int8_t idx = 0;
// Incrementing idx before the loop starts // Requirement X.X.X \\
++idx; // Non-compliant - ++idx was unexpectedly commented-out because of \
character occurrence in the end of C++ comment
constexpr std::int8_t limit = 10;
for (; idx <= limit; ++idx)
{
// ...
}
}⚠️ If the last character in a single-line C++ comment is \, then the comment will continue
in the next line. This may lead to sections of code that are unexpectedly commented
out.
See also:
• noneIf the last character in a single-line C++ comment is \, then the comment will continue
in the next line. This may lead to sections of code that are unexpectedly commented
out.
See also:
• none
A2-7-3Required · Automated✓ compilable📄 공식 예제Official example
All declarations of “user-defined” types, static and non-static data members, functions and methods shall be preceded by documentation.All declarations of “user-defined” types, static and non-static data members, functions and methods shall be preceded by documentation.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <stdexcept> //% $Id: A2-7-3.hpp 305382 2018-01-26 06:32:15Z michal.szczepankiewicz $ #include <cstdint> void F1(std::int32_t) noexcept; // Non-compliant documentation std::int32_t F2(std::int16_t input1, std::int32_t input2); // Non-compliant documentation /// @brief Function description /// /// @param input1 input1 parameter description /// @param input2 input2 parameter description /// @throw std::runtime_error conditions to runtime_error occur /// /// @return return value description std::int32_t F3( std::int16_t input1, std::int16_t input2) noexcept(false); // Compliant documentation /// @brief Class responsibility class C // Compliant documentation { public: /// @brief Constructor description /// /// @param input1 input1 parameter description /// @param input2 input2 parameter description C(std::int32_t input1, float input2) : x{input1}, y{input2} {} /// @brief Method description /// /// @return return value descrption std::int32_t const * GetX() const noexcept { return &x; } private: /// @brief Data member descpription std::int32_t x; /// @brief Data member descpription float y; };
⚠️ Every declaration needs to provide a proper documentation.
This is compatible with the C++ standard library documentation. This forces
a programmer to provide a clarification for defined types and its data members
responsibilities, methods and functions usage, their inputs and outputs specification
(e.g. memory management, ownership, valid boundaries), and exceptions that could
be thrown.
See also:
• JSF December 2005 [8]: AV Rule 129: Comments in header files should describe
the externally visible behavior of the functions or classes being documented.
• noneEvery declaration needs to provide a proper documentation.
This is compatible with the C++ standard library documentation. This forces
a programmer to provide a clarification for defined types and its data members
responsibilities, methods and functions usage, their inputs and outputs specification
(e.g. memory management, ownership, valid boundaries), and exceptions that could
be thrown.
See also:
• JSF December 2005 [8]: AV Rule 129: Comments in header files should describe
the externally visible behavior of the functions or classes being documented.
• none
A2-7-5Required · Non-automated✓ compilable📄 공식 예제Official example
Comments shall not document any actions or sources (e.g. tables, figures, paragraphs, etc.) that are outside of the file.Comments shall not document any actions or sources (e.g. tables, figures, paragraphs, etc.) that are outside of the file.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A2-7-5: Comments shall not document any actions or sources (e.g. tables, figures, paragraphs, etc.) that are outside of the file. // No code example provided in the official guideline PDF.
⚠️ Commenting only actions and sources that are inside a particular file reduce
dependencies among files. Comments in a file will require changes only when content
of the file reworked.
Note: This rule does not affect valid assumptions or preconditions for entities within
the file.
See also:
• JSF December 2005 [8]: AV Rule 128: Comments that document actions
or sources (e.g. tables, figures, paragraphs, etc.) outside of the file being
documented will not be allowed.
6.2.8 Header namesCommenting only actions and sources that are inside a particular file reduce
dependencies among files. Comments in a file will require changes only when content
of the file reworked.
Note: This rule does not affect valid assumptions or preconditions for entities within
the file.
See also:
• JSF December 2005 [8]: AV Rule 128: Comments that document actions
or sources (e.g. tables, figures, paragraphs, etc.) outside of the file being
documented will not be allowed.
6.2.8 Header names
A2-8-1Required · Non-automated✓ compilable📄 공식 예제Official example
non-automated) A header file name should reflect the logical entity for which it provides declarations.non-automated) A header file name should reflect the logical entity for which it provides declarations.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A2-8-1: non-automated) A header file name should reflect the logical entity for which it provides declarations. // No code example provided in the official guideline PDF.
⚠️ Naming a header file with a name of a declared type or accordingly to a collection of
free functions or forwarded headers makes include-directives and a project structure
more clear and readable.
See also:
• JSF December 2005 [8]: AV Rule 55: The name of a header file should reflect
the logical entity for which it provides declarations.Naming a header file with a name of a declared type or accordingly to a collection of
free functions or forwarded headers makes include-directives and a project structure
more clear and readable.
See also:
• JSF December 2005 [8]: AV Rule 55: The name of a header file should reflect
the logical entity for which it provides declarations.
A2-8-2Advisory · Non-automated✓ compilable📄 공식 예제Official example
non-automated) An implementation file name should reflect the logical entity for which it provides definitions.non-automated) An implementation file name should reflect the logical entity for which it provides definitions.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A2-8-2: non-automated) An implementation file name should reflect the logical entity for which it provides definitions. // No code example provided in the official guideline PDF.
⚠️ Naming an implementation file with a name of a declared type or accordingly to a
collection of free functions makes a project structure more clear and readable.
See also:
• JSF December 2005 [8]: AV Rule 56: The name of an implementation file
should reflect the logical entity for which it provides definitions and have a “.cpp”
extension (this name will normally be identical to the header file that provides the
corresponding declarations.).
6.2.10 IdentifiersNaming an implementation file with a name of a declared type or accordingly to a
collection of free functions makes a project structure more clear and readable.
See also:
• JSF December 2005 [8]: AV Rule 56: The name of an implementation file
should reflect the logical entity for which it provides definitions and have a “.cpp”
extension (this name will normally be identical to the header file that provides the
corresponding declarations.).
6.2.10 Identifiers
A3A3 (AUTOSAR)A3 (AUTOSAR-original)
A3-1-1Required · Automated
헤더는 자체적으로(self-contained) 포함 순서와 무관하게 컴파일되어야 한다It shall be possible to include any header file in multiple translation units without violating the ODR
❌ 위반 예시Non-compliant example
// shape.h — Point 를 쓰면서 그 정의를 포함하지 않음
struct Shape {
Point origin; // Point 미정의 — 이 헤더를 단독 포함하면 컴파일 에러
};✅ 준수 예시Compliant example
// shape.h — 필요한 의존성을 직접 포함
#include "point.h" // Point 정의 제공
struct Shape {
Point origin;
};⚠️ 근거: 헤더는 어떤 순서로 포함되든 단독으로 컴파일될 수 있어야 하며(자체 완결), 필요한 타입·선언을 직접 포함하지 않으면 그 가용성이 포함하는 쪽의 우연한 포함 순서에 의존하게 된다. 영향: 자체 완결되지 않은 헤더는 다른 헤더보다 먼저 포함되면 컴파일이 깨지는 깨지기 쉬운 빌드를 만들고, 포함 순서를 맞추는 숨은 규칙이 코드 전반에 퍼진다. 대응: 각 헤더가 사용하는 모든 타입·심볼의 정의/선언을 그 헤더에서 직접 #include 해 순서 독립적으로 컴파일되게 한다.Rationale: a header must compile on its own regardless of include order (self-contained), and failing to include the types and declarations it uses makes their availability depend on the accidental include order of the includer. Impact: a non-self-contained header creates a fragile build that breaks when included before another header, spreading hidden ordering rules across the codebase. Fix: have each header directly #include the definitions/declarations of every type and symbol it uses so it compiles order-independently.
A3-3-2Required · Automated✓ compilable
정적/스레드-지역 객체는 상수 초기화(constant initialization) 가능해야 한다Static and thread-local objects shall be constant-initialized
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
static std::string build() { return "config"; }
static std::string g_name = build(); // 동적 초기화 — TU 간 초기화 순서 문제
int main() { std::cout << g_name << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
#include <string>
// 상수 초기화 가능한 전역 + 지연 초기화로 동적 의존을 격리
static constexpr int kLimit = 100;
static const std::string& name() {
static const std::string n = "config"; // 최초 사용 시 초기화(순서 안전)
return n;
}
int main() { std::cout << kLimit << ' ' << name() << '\n'; }⚠️ 근거: 네임스페이스 범위 정적 객체가 런타임 함수 호출로 초기화되면(동적 초기화), 서로 다른 번역단위 간 초기화 순서가 표준으로 정해지지 않는다(static init order fiasco). 영향: 한 전역이 아직 초기화되지 않은 다른 전역에 의존하면 빌드·링크 순서에 따라 미초기화 값을 읽어 비결정적 버그가 생기고, 진단이 어렵다. 대응: 전역은 constexpr/상수식으로 초기화하고, 불가피한 동적 초기화는 함수 지역 static(최초 사용 시 초기화)으로 감싸 순서를 보장한다.Rationale: when a namespace-scope static object is initialized by a runtime function call (dynamic initialization), the initialization order across different translation units is not defined by the standard (the static initialization order fiasco). Impact: if one global depends on another not-yet-initialized global, it reads an uninitialized value depending on build/link order, a nondeterministic and hard-to-diagnose bug. Fix: initialize globals with constexpr/constant expressions, and wrap unavoidable dynamic initialization in a function-local static (initialized on first use) to guarantee order.
A3-1-2Required · Automated✓ compilable📄 공식 예제Official example
Header files, that are defined locally in the project, shall have a file name extension of one of: ".h", ".hpp" or ".hxx".Header files, that are defined locally in the project, shall have a file name extension of one of: ".h", ".hpp" or ".hxx".
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A3-1-2.cpp 266557 2017-02-07 13:08:19Z piotr.tanski $ //#include <h3.h> // Compliant //#include <h1.hpp> // Compliant //#include <h2.hxx> // Compliant //#include <h4.cpp> // Non-compliant //#include <h5.c> // Non-compliant //#include <h6.hdr> // Non-compliant //#include <h7.inc> // Non-compliant
⚠️ This is consistent with developer expectations to provide header files with one of the
standard file name extensions.
See also:
• JSF December 2005 [8]: 4.9.2 AV Rule 53 Header files will always have a file
name extension of ".h".This is consistent with developer expectations to provide header files with one of the
standard file name extensions.
See also:
• JSF December 2005 [8]: 4.9.2 AV Rule 53 Header files will always have a file
name extension of ".h".
A3-1-3Advisory · Automated✓ compilable📄 공식 예제Official example
Implementation files, that are defined locally in the project, should have a file name extension of ".cpp".Implementation files, that are defined locally in the project, should have a file name extension of ".cpp".
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A3-1-3: Implementation files, that are defined locally in the project, should have a file name extension of ".cpp". // No code example provided in the official guideline PDF.
⚠️ This is consistent with developer expectations to provide C++ implementation files with
the standard file name extension.
Note that compilers support various file name extensions for C++ implementation files.
See also:
• JSF December 2005 [8]: 4.9.2 AV Rule 54 Implementation files will always have
a file name extension of ".cpp".This is consistent with developer expectations to provide C++ implementation files with
the standard file name extension.
Note that compilers support various file name extensions for C++ implementation files.
See also:
• JSF December 2005 [8]: 4.9.2 AV Rule 54 Implementation files will always have
a file name extension of ".cpp".
A3-1-4Required · Automated✓ compilable📄 공식 예제Official example
When an array with external linkage is declared, its size shall be stated explicitly.When an array with external linkage is declared, its size shall be stated explicitly.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A3-1-4.hpp 271687 2017-03-23 08:57:35Z piotr.tanski $ #include <cstdint> extern std::int32_t array1[]; // Non-compliant extern std::int32_t array2[42]; // Compliant
⚠️ Although it is possible to declare an array of incomplete type and access its elements,
it is safer to do so when the size of the array can be explicitly determined.
See also:
• MISRA C++ 2008 [7]: Rule 3-1-3 When an array is declared, its size shall either
be stated explicitly or defined implicitly by initialization.Although it is possible to declare an array of incomplete type and access its elements,
it is safer to do so when the size of the array can be explicitly determined.
See also:
• MISRA C++ 2008 [7]: Rule 3-1-3 When an array is declared, its size shall either
be stated explicitly or defined implicitly by initialization.
A3-1-5Required · Automated✓ compilable📄 공식 예제Official example
A function definition shall only be placed in a class definition if (1) the function is intended to be inlined (2) it is a member function template (3) it is a member function of a class template. --- PAGE 57 ---A function definition shall only be placed in a class definition if (1) the function is intended to be inlined (2) it is a member function template (3) it is a member function of a class template. --- PAGE 57 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A3-1-5.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
#include <cstdint>
#include <iostream>
class A
{
public:
//compliant with (2)
template <typename T>
void Foo(T&& t)
{
std::cout << __PRETTY_FUNCTION__ << " defined inside with param: " << t
<< std::endl;
}
//non-compliant with (2)
template <typename T>
void Bar(T&& t);
//compliant with (1)
std::uint32_t GetVal() const noexcept
{
return val;
}
//non-compliant with (1)
std::uint32_t GetVal2() const noexcept;
private:
std::uint32_t val = 5;
};
template <typename T>
void A::Bar(T&& t)
{
std::cout << __PRETTY_FUNCTION__ << " defined outside with param: " << t <<
std::endl;
}
std::uint32_t A::GetVal2() const noexcept
{
return val;
}
template <typename T>
class B
{
public:
B(const T& x) : t(x) {}
//compliant with (3)
void display() const noexcept
{
std::cout << t << std::endl;
}
//non-compliant with (3)
void display2() const noexcept;
private:
T t;
};
template <typename T>
void B<T>::display2() const noexcept
{
std::cout << t << std::endl;
}
int main(void)
{
std::uint32_t tmp = 5;
A a;
a.Foo(3.14f);
a.Bar(5);
std::cout << a.GetVal() << std::endl;
B<std::int32_t> b(7);
b.display();
return 0;
}⚠️ Merging the implementation into the declaration instructs a compiler to inline the
method which may save both time and space for short functions. For templates, it
allows to reduce repetitions of template syntax elements (e.g. parameter list), which
makes code less difficult to read and maintain.
See also:
• JSF December 2005 [8]: AV Rule 109: A function definition should not be placed
in a class specification unless the function is intended to be inlined.Merging the implementation into the declaration instructs a compiler to inline the
method which may save both time and space for short functions. For templates, it
allows to reduce repetitions of template syntax elements (e.g. parameter list), which
makes code less difficult to read and maintain.
See also:
• JSF December 2005 [8]: AV Rule 109: A function definition should not be placed
in a class specification unless the function is intended to be inlined.
A3-1-6Advisory · Automated✓ compilable📄 공식 예제Official example
Trivial accessor and mutator functions should be inlined.Trivial accessor and mutator functions should be inlined.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A3-1-6.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
#include <cstdint>
class A
{
public:
A(std::int32_t l) noexcept : limit{l} {}
//compliant
std::int32_t Limit() const noexcept { return limit; }
//compliant
void SetLimit(std::int32_t l) { limit = l; }
//non-compliant
//std::int32_t Limit() const noexcept
//{
//open file, read data, close file
//return value
//}
//non-compliant
//void SetLimit(std::int32_t l)
//{
//open file, write data, close file
//}
private:
std::int32_t limit;
};⚠️ Inlining trivial accessors and mutators saves time and space, as it reduces multiple
syntax elements that has to be repeated.
See also:
• JSF December 2005 [8]: AV Rule 122: Trivial accessor and mutator functions
should be inlined.
6.3.2 One Definition RuleInlining trivial accessors and mutators saves time and space, as it reduces multiple
syntax elements that has to be repeated.
See also:
• JSF December 2005 [8]: AV Rule 122: Trivial accessor and mutator functions
should be inlined.
6.3.2 One Definition Rule
A3-3-1Required · Automated✓ compilable📄 공식 예제Official example
Objects or functions with external linkage (including members of named namespaces) shall be declared in a header file.Objects or functions with external linkage (including members of named namespaces) shall be declared in a header file.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <stdexcept>
//% $Id: A3-3-1.hpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
extern std::int32_t a1;
extern void F4();
namespace n
{
void F2();
std::int32_t a5; // Compliant, external linkage
}
//% $Id: A3-3-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include "A3-3-1.hpp"
std::int32_t a1 = 0; // Compliant, external linkage
std::int32_t a2 = 0; // Non-compliant, static keyword not used
static std::int32_t a3 = 0; // Compliant, internal linkage
namespace
{
std::int32_t a4 = 0; // Compliant by exception
void F1() // Compliant by exception
{
}
}
namespace n
{
void F2() // Compliant, external linkage
{
}
std::int32_t a6 = 0; // Non-compliant, external linkage
}
extern std::int32_t a7; // Non-compliant, extern object declared in .cpp file
static void F3() // Compliant, static keyword used
{
}
void F4() // Compliant, external linkage
{
a1 = 1;
a2 = 1;
a3 = 1;
a4 = 1;
n::a5 = 1;
n::a6 = 1;
a7 = 1;
}
void F5() // Non-compliant, static keyword not used
{
a1 = 2;
a2 = 2;
a3 = 2;
a4 = 2;
n::a5 = 2;
n::a6 = 2;
a7 = 2;
}
int main(int, char **) // Compliant by exception
{
F1();
n::F2();
F3();
F4();
F5();
}⚠️ Placing the declarations of objects and functions with external linkage in a header file
means that they are intended to be accessible from other translation units.
If external linkage is not needed, then the object or function is supposed to be either
declared in an unnamed namespace or declared static in the implementation file.
This reduces the visibility of objects and functions, which allows to reach a higher
encapsulation and isolation.
Note that members of named namespace are by default external linkage objects.
Exception:
This rule does not apply to main, or to members of unnamed namespaces.
See also:
• MISRA C++ 2008 [7]: Rule 3-3-1 Objects or functions with external linkage shall
be declared in a header file.Placing the declarations of objects and functions with external linkage in a header file
means that they are intended to be accessible from other translation units.
If external linkage is not needed, then the object or function is supposed to be either
declared in an unnamed namespace or declared static in the implementation file.
This reduces the visibility of objects and functions, which allows to reach a higher
encapsulation and isolation.
Note that members of named namespace are by default external linkage objects.
Exception:
This rule does not apply to main, or to members of unnamed namespaces.
See also:
• MISRA C++ 2008 [7]: Rule 3-3-1 Objects or functions with external linkage shall
be declared in a header file.
A3-8-1Required · Automated✓ compilable📄 공식 예제Official example
An object shall not be accessed outside of its lifetime.An object shall not be accessed outside of its lifetime.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <vector>
#include <string>
#include <thread>
//% $Id: A3-8-1.cpp 305786 2018-01-30 08:58:33Z michal.szczepankiewicz $
//
// 1. Pointer to virtual base is passed as function argument after lifetime of
// object has ended.
//
class B
{
};
class C1 : public virtual B // violates M10-1-1
{
};
class C2 : public virtual B // violates M10-1-1
{
};
class D : public C1, public C2
{
};
void f(B const * b){};
void example1()
{
D* d = new D(); // lifetime of d starts (violates A18-5-2)
// Use d
delete d; // lifetime of d ends (violates A18-5-2)
f(d); // Non-compliant - Undefined behavior, even if argument is not used
// by f().
}
//
// 2. Accessing an initializer_list after lifetime of initializing array has
// ended.
// class E
{
std::initializer_list<int> lst;
public:
// Conceptually, this works as if a temporary array {1, 2, 3} was created
// and a reference to this array was passed to the initializer_list. The
// lifetime of the temporary array ends when the constructor finishes.
E() : lst{1, 2, 3} {}
int first() const { return *lst.begin(); }
};
void example2()
{
E e;
std::out << e.first() << "\n"; // Non-compliant
}
//
// 3. Exiting main while running tasks depend on static objects
// void initialize_task()
{
// start some task (separate thread) which depends on some static object.
// ...
}
int main()
{
// static constructors are called
initialize_task();
} // main ends, static destructors are called
// Non-compliant
// Task begins to run and accesses destroyed static object.
//
// 4. Storage reuse without explicit destructor call
// void example4()
{
std::string str;
new (&a) std::vector<int>{}; // Non-compliant: storage of str reused without
// calling its non-trivial destructor.
} // Non-compliant: Destructor of str is implicitly called at scope exit, but
// storage contains object of different type.⚠️ Accessing an object outside of its lifetime, i.e. before its initialization or constructor has
completed, or after its non-trivial destructor has finished, is well defined only for a very
restricted number of cases, as laid out by the language standard. Outside of these
cases it leads to undefined behavior.
Note: The AUTOSAR C++14 guidelines contain several other rules which are special
cases of this rule (see references below). This rule was added to provide generic
coverage for all cases not contained in these specialized rules. This also makes it
easier to provide tracing from other standards with a similar generic rule.
Note: The examples given below are not intended to represent a complete list of
situations where violations of this rule can occur.
See also:
• ISO/IEC 14882:2014 [3]: 3.8: [basic.life]
• JSF December 2005 [8]: AV Rule 70.1: An object shall not be improperly used
before its lifetime begins or after its lifetime ends.
• SEI CERT C++ Coding Standard [10]: EXP54-CPP: Do not access an object
outside of its lifetime.
• A5-1-4 in section 6.5.1
• M7-5-1 in section 6.7.5
• M7-5-2 in section 6.7.5
• A7-5-1 in section 6.7.5
• M12-1-1 in section 6.12.1
6.3.9 TypesAccessing an object outside of its lifetime, i.e. before its initialization or constructor has
completed, or after its non-trivial destructor has finished, is well defined only for a very
restricted number of cases, as laid out by the language standard. Outside of these
cases it leads to undefined behavior.
Note: The AUTOSAR C++14 guidelines contain several other rules which are special
cases of this rule (see references below). This rule was added to provide generic
coverage for all cases not contained in these specialized rules. This also makes it
easier to provide tracing from other standards with a similar generic rule.
Note: The examples given below are not intended to represent a complete list of
situations where violations of this rule can occur.
See also:
• ISO/IEC 14882:2014 [3]: 3.8: [basic.life]
• JSF December 2005 [8]: AV Rule 70.1: An object shall not be improperly used
before its lifetime begins or after its lifetime ends.
• SEI CERT C++ Coding Standard [10]: EXP54-CPP: Do not access an object
outside of its lifetime.
• A5-1-4 in section 6.5.1
• M7-5-1 in section 6.7.5
• M7-5-2 in section 6.7.5
• A7-5-1 in section 6.7.5
• M12-1-1 in section 6.12.1
6.3.9 Types
A3-9-1Required · Automated✓ compilable📄 공식 예제Official example
Fixed width integer types from <cstdint>, indicating the size and signedness, shall be used in place of the basic numerical types.Fixed width integer types from <cstdint>, indicating the size and signedness, shall be used in place of the basic numerical types.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A3-9-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
void F()
{
std::int32_t i1 = 5; // Compliant
int i2 = 10; // Non-compliant
std::int64_t i3 = 250; // Compliant
long int i4 = 50; // Non-compliant
std::int8_t i5 = 16; // Compliant
char i6 = 23; // Non-compliant
}⚠️ The basic numerical types of char, int, short, long are not supposed to be used,
specific-length types from <cstdint> header need be used instead.
Fixed width integer types are:
• std::int8_t
• std::int16_t
• std::int32_t
• std::int64_t
• std::uint8_t
• std::uint16_t
• std::uint32_t
• std::uint64_t
Exception:
The wchar_t does not need a typedef as it always maps to a type that supports wide
characters.
See also:
• MISRA C++ 2008 [7]: Rule 3-9-2 typedefs that indicate size and signedness
should be used in place of the basic numerical types.The basic numerical types of char, int, short, long are not supposed to be used,
specific-length types from <cstdint> header need be used instead.
Fixed width integer types are:
• std::int8_t
• std::int16_t
• std::int32_t
• std::int64_t
• std::uint8_t
• std::uint16_t
• std::uint32_t
• std::uint64_t
Exception:
The wchar_t does not need a typedef as it always maps to a type that supports wide
characters.
See also:
• MISRA C++ 2008 [7]: Rule 3-9-2 typedefs that indicate size and signedness
should be used in place of the basic numerical types.
A4A4 (AUTOSAR)A4 (AUTOSAR-original)
A4-7-1Required · Automated✓ compilable
정수 표현식이 데이터 손실을 일으키지 않게 한다An integer expression shall not lead to data loss
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdint>
int main() {
std::uint32_t wide = 300;
std::uint8_t narrow = wide; // 8비트 초과분 절단 — 300 & 0xFF = 44
std::cout << static_cast<int>(narrow) << '\n'; // 44, 조용한 데이터 손실
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstdint>
int main() {
std::uint32_t wide = 300;
if (wide <= 0xFF) {
std::uint8_t narrow = static_cast<std::uint8_t>(wide);
std::cout << static_cast<int>(narrow) << '\n';
} else {
std::cout << "value does not fit in uint8_t\n"; // 손실 방지
}
}⚠️ 근거: 넓은 정수 타입의 값을 더 좁은 타입에 대입하면 표현 범위를 넘는 상위 비트가 잘려 나가고, 부호 있는/없는 변환에서는 값의 부호·크기가 바뀐다. 영향: 300 을 uint8_t 에 넣으면 44 가 되는 식의 조용한 데이터 손실이 발생해, 길이·카운트·인덱스로 쓰일 때 경계 오류나 잘못된 계산으로 번진다. 대응: 좁은 타입에 넣기 전에 값이 대상 범위에 맞는지 검사하고, 의도한 변환은 static_cast 로 명시한다.Rationale: assigning a value of a wider integer type to a narrower type truncates the high bits beyond the representable range, and signed/unsigned conversions change the sign or magnitude. Impact: putting 300 into a uint8_t yields 44 — a silent data loss that, when used as a length, count, or index, escalates to boundary errors or wrong computations. Fix: check that the value fits the target range before narrowing, and make the intended conversion explicit with static_cast.
A4-10-1Required · Automated✓ compilable
널 포인터 상수로는 nullptr 만 사용한다Only nullptr literal shall be used as the null-pointer-constant
❌ 위반 예시Non-compliant example
#include <iostream>
static void handle(int v) { std::cout << "int " << v << '\n'; }
static void handle(int* p) { std::cout << "ptr " << (p?*p:-1) << '\n'; }
int main() {
handle(0); // 0 을 널 의도로 넘김 → 정수로 해석돼 handle(int) 선택(의도와 반대)
}✅ 준수 예시Compliant example
#include <iostream>
static void handle(int v) { std::cout << "int " << v << '\n'; }
static void handle(int* p) { std::cout << "ptr " << (p?*p:-1) << '\n'; }
int main() {
handle(nullptr); // nullptr 은 포인터 타입 → handle(int*) 가 정확히 선택됨
}⚠️ 근거: NULL 과 0 은 정수 문맥과 포인터 문맥에서 모두 쓰일 수 있는 정수 상수라, 오버로드 해석에서 포인터 버전이 아니라 정수 버전이 선택될 수 있다. 영향: 예제처럼 handle(NULL) 이 의도와 달리 정수 오버로드를 부르면 잘못된 함수가 호출되거나, 템플릿·가변인자 문맥에서 타입이 어긋나 미묘한 버그가 된다. 대응: 널 포인터에는 포인터 타입으로만 추론되는 nullptr 만 사용한다.Rationale: NULL and 0 are integer constants usable in both integer and pointer contexts, so overload resolution may select the integer version rather than the pointer version. Impact: as in the example, handle(NULL) calling the integer overload against intent invokes the wrong function, or in template/variadic contexts mismatches the type — a subtle bug. Fix: use nullptr for null pointers, since it deduces only to a pointer type.
A4-5-1Required · Automated✓ compilable📄 공식 예제Official example
Expressions with type enum or enum class shall not be used as operands to built-in and overloaded operators other than the subscript operator [ ], the assignment operator =, the equality operators == and ! =, the unary & operator, and the relational operators <, <=, >, >=.Expressions with type enum or enum class shall not be used as operands to built-in and overloaded operators other than the subscript operator [ ], the assignment operator =, the equality operators == and ! =, the unary & operator, and the relational operators <, <=, >, >=.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A4-5-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
enum Colour : std::uint8_t
{
Red,
Green,
Blue,
ColoursCount
};
void F1() noexcept(false)
{
Colour colour = Red;
if (colour == Green) // Compliant
{
}
if (colour == (Red + Blue)) // Non-compliant
{
}
if (colour < ColoursCount) // Compliant
{
}
}
enum class Car : std::uint8_t
{
Model1,
Model2,
Model3,
ModelsCount
};
void F2() noexcept(false)
{
Car car = Car::Model1;
if (car != Car::Model2) // Compliant
{
}
if (car == Car::Model3) // Compliant
{
}
// if (car == (Car::Model1 + Car::Model2)) // Non-compliant -
// operator+ not provided for Car enum class, compilation error
//{
//}
if (car < Car::ModelsCount) // Compliant
{
}
}
Car operator+(Car lhs, Car rhs)
{
return Car::Model3;
}
void F3() noexcept(false)
{
Car car = Car::Model3;
if (car == (Car::Model1 + Car::Model2)) // Non-compliant - overloaded
// operator+ provided, no
// compilation error
{
}
}
enum Team : std::uint8_t
{
TeamMember1 = 0,
TeamMember2 = 1,
TeamMember3 = 2,
TeamMember4 = 3,
TeamMembersStart = TeamMember1,
TeamMembersEnd = TeamMember2,
TeamMembersCount = 4
};
void F4(const char * teamMember)
{
// Implementation
}
void F5()
{
const char * team[TeamMembersCount]; // Compliant
// ...
F4(team[TeamMember2]); // Compliant
}⚠️ Enumerations, i.e. enums or enum classes, have implementation-defined
representations and they are not supposed to be used in arithmetic contexts.
Note that only enums can be implicitly used as operands to other built-in operators, like
operators +, −, ∗, etc. Enum class needs to provide definitions of mentioned operators
in order to be used as operand.
Exception:
It is allowed to use the enumeration as operand to all built-in and overloaded operators
if the enumeration satisfies the “BitmaskT ype” concept [16].
See also:
• MISRA C++ 2008 [7]: Rule 4-5-2 Expressions with type enum shall not be
used as operands to built-in operators other than the subscript operator [ ], the
assignment operator =, the equality operators == and !=, the unary & operator,
and the relational operators <, <=, >, >=.Enumerations, i.e. enums or enum classes, have implementation-defined
representations and they are not supposed to be used in arithmetic contexts.
Note that only enums can be implicitly used as operands to other built-in operators, like
operators +, −, ∗, etc. Enum class needs to provide definitions of mentioned operators
in order to be used as operand.
Exception:
It is allowed to use the enumeration as operand to all built-in and overloaded operators
if the enumeration satisfies the “BitmaskT ype” concept [16].
See also:
• MISRA C++ 2008 [7]: Rule 4-5-2 Expressions with type enum shall not be
used as operands to built-in operators other than the subscript operator [ ], the
assignment operator =, the equality operators == and !=, the unary & operator,
and the relational operators <, <=, >, >=.
A5A5 (AUTOSAR)A5 (AUTOSAR-original)
A5-0-1Required · Automated✓ compilable
표현식의 값이 평가 순서에 의존하지 않게 한다The value of an expression shall be the same under any order of evaluation that the standard permits
❌ 위반 예시Non-compliant example
#include <iostream>
static int use(int a, int b) { return a * 10 + b; }
int main() {
int i = 0;
int r = use(i++, i++); // 두 인자 평가 순서 미명세 — 결과 비결정적
std::cout << r << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
static int use(int a, int b) { return a * 10 + b; }
int main() {
int i = 0;
int a = i++; // 부작용을 분리해 순서 확정
int b = i++;
int r = use(a, b);
std::cout << r << '\n'; // 항상 01
}⚠️ 근거: 함수 인자나 한 식 안 여러 피연산자의 평가 순서는(C++17에서 일부 강화됐어도) 일반적으로 미명세라, 같은 객체를 한 식에서 여러 번 수정하면 결과가 정해지지 않는다. 영향: use(i++, i++) 의 값이 컴파일러·최적화에 따라 달라져 이식성·재현성이 깨지고, 같은 스칼라에 부작용이 겹치면 미정의 동작이 된다. 대응: 부작용을 별도 문장으로 분리해 평가 순서를 명시적으로 확정한다.Rationale: the evaluation order of function arguments and of multiple operands within one expression is generally unspecified (even with C++17 tightening), so modifying the same object several times in one expression leaves the result undefined. Impact: the value of use(i++, i++) varies by compiler/optimization, breaking portability and reproducibility, and overlapping side effects on one scalar become undefined behaviour. Fix: split side effects into separate statements to fix the evaluation order explicitly.
A5-1-1Required · Automated✓ compilable
리터럴 값은 명명된 상수로 정의해 사용한다(매직 넘버 금지)Literal values shall not be used apart from type initialization; named constants shall be used instead
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int speed = 130;
if (speed > 120) std::cout << "over limit\n"; // 120 의 의미가 불명확(매직 넘버)
if (speed > 120) std::cout << "log\n"; // 같은 값이 흩어져 변경 누락 위험
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
constexpr int kSpeedLimitKmh = 120; // 의미를 담은 명명 상수
int speed = 130;
if (speed > kSpeedLimitKmh) std::cout << "over limit\n";
if (speed > kSpeedLimitKmh) std::cout << "log\n";
}⚠️ 근거: 코드 곳곳에 흩어진 리터럴(매직 넘버·문자열)은 그 값이 무엇을 뜻하는지, 여러 곳의 같은 값이 같은 개념인지 드러내지 못한다. 영향: 제한값이 바뀌면 흩어진 모든 리터럴을 빠짐없이 고쳐야 하는데 하나라도 놓치면 일관성이 깨지고, 의미 불명으로 리뷰·디버깅이 어렵다. 대응: 의미를 담은 constexpr 명명 상수로 한 번 정의하고 모든 곳에서 그 이름을 참조한다.Rationale: literals scattered through code (magic numbers and strings) fail to convey what the value means or whether identical values in different places represent the same concept. Impact: when a limit changes, every scattered literal must be updated, and missing one breaks consistency, while the unclear meaning hampers review and debugging. Fix: define a meaningful constexpr named constant once and reference that name everywhere.
A5-1-2Required · Automated✓ compilable
스코프를 벗어나는 람다에서 변수를 참조로 캡처하지 않는다Variables shall not be implicitly captured in a lambda expression that outlives its scope
❌ 위반 예시Non-compliant example
#include <iostream>
#include <functional>
static std::function<int()> make() {
int x = 1;
return [&]{ return x; }; // x 참조 캡처 — 함수 종료 시 x 소멸 → 댕글링
}
int main() {
auto f = make();
std::cout << f() << '\n'; // 무효 참조 접근 — 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
#include <functional>
static std::function<int()> make() {
int x = 1;
return [x]{ return x; }; // 값 캡처 — 람다가 사본 소유
}
int main() {
auto f = make();
std::cout << f() << '\n'; // 1
}⚠️ 근거: 참조로 캡처한 변수는 람다 안에 포인터처럼 보관되므로, 그 변수가 람다보다 먼저 소멸하면 람다 내부 참조는 댕글링이 된다. 영향: 지역 변수를 참조 캡처한 람다(또는 std::function)를 반환하면, 호출 시점에 이미 해제된 스택을 읽어 쓰레기 값·크래시가 난다. 대응: 람다가 자신을 만든 스코프보다 오래 살 수 있으면 필요한 값을 값으로 캡처하고, 공유 수명이 필요하면 shared_ptr 를 캡처한다.Rationale: a reference-captured variable is held like a pointer inside the lambda, so if it is destroyed before the lambda, the captured reference dangles. Impact: returning a lambda (or std::function) that reference-captures a local reads already-freed stack at call time, yielding garbage or a crash. Fix: capture needed values by value when the lambda may outlive the scope that created it, and capture a shared_ptr when shared lifetime is required.
A5-2-2Required · Automated✓ compilable
전통적 C 스타일 캐스트를 사용하지 않는다Traditional C-style casts shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
const double d = 3.9;
int n = (int)d; // C 스타일 캐스트 — 어떤 변환인지(절단? const 제거?) 불투명
std::cout << n << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
const double d = 3.9;
int n = static_cast<int>(d); // 의도(수치 변환)가 명확한 C++ 캐스트
std::cout << n << '\n';
}⚠️ 근거: C 스타일 캐스트 (T)x 는 static_cast·const_cast·reinterpret_cast 중 어떤 변환이든 상황에 맞춰 조용히 수행하므로, 코드만 봐서는 어떤 종류의(때로 위험한) 변환이 일어나는지 알 수 없다. 영향: const 제거나 무관한 타입 재해석 같은 위험한 변환이 무해한 수치 변환과 똑같이 보여 숨겨지고, grep 으로 위험한 캐스트를 찾기도 어렵다. 대응: 의도를 드러내는 C++ 캐스트(static_cast 등)를 사용해 변환 종류를 명시하고 컴파일러 검사를 받게 한다.Rationale: a C-style cast (T)x silently performs whichever of static_cast, const_cast, or reinterpret_cast fits the situation, so the code alone does not reveal which (sometimes dangerous) conversion occurs. Impact: dangerous conversions like casting away const or reinterpreting unrelated types look identical to a harmless numeric conversion and are hidden, and dangerous casts are hard to grep for. Fix: use the intent-revealing C++ casts (static_cast, etc.) to make the conversion kind explicit and subject to compiler checks.
A5-2-3Required · Automated✓ compilable
const_cast 로 const/volatile 한정을 제거하지 않는다A cast shall not remove any const or volatile qualification from the type of a pointer or reference
❌ 위반 예시Non-compliant example
#include <iostream>
static void tamper(const int& v) {
int& r = const_cast<int&>(v); // const 제거
r = 9; // 호출자가 진짜 const 객체를 넘겼다면 수정은 미정의 동작
}
int main() {
const int k = 5;
tamper(k);
std::cout << k << '\n'; // 5 또는 9 — 구현/최적화에 따라 불확정
}✅ 준수 예시Compliant example
#include <iostream>
static void update(int& v) { v = 9; } // 수정이 필요하면 비-const 인터페이스
int main() {
int k = 5; // 수정 대상은 비-const 로 선언
update(k);
std::cout << k << '\n'; // 9
}⚠️ 근거: const_cast 로 한정을 제거한 경로를 통해 실제로 const 로 정의된 객체를 수정하는 것은 미정의 동작이다(컴파일러가 const 객체를 상수 폴딩하거나 읽기 전용 메모리에 둘 수 있기 때문). 영향: 수정이 무시되거나, 읽기 전용 페이지에 쓰다 크래시가 나거나, 같은 객체의 두 읽기가 다른 값을 주는 등 진단 없는 결함이 된다. 대응: 객체를 수정해야 하면 처음부터 비-const 로 선언하고 비-const 인터페이스를 제공하며, const 를 벗겨 쓰지 않는다.Rationale: modifying an object that is truly defined as const through a const-cast-stripped path is undefined behaviour, because the compiler may constant-fold it or place it in read-only memory. Impact: the write may be ignored, may crash when writing a read-only page, or two reads of the same object may differ — a defect with no diagnostic. Fix: declare objects that need modification as non-const from the start and provide a non-const interface, never casting away const to write.
A5-2-4Required · Automated✓ compilable
reinterpret_cast 를 사용하지 않는다reinterpret_cast shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdint>
int main() {
float f = 1.5f;
std::uint32_t bits = *reinterpret_cast<std::uint32_t*>(&f); // 엄격 별칭 위반
std::cout << bits << '\n'; // 미정의 동작 — 최적화에 따라 결과가 달라질 수 있음
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstdint>
#include <cstring>
int main() {
float f = 1.5f;
std::uint32_t bits;
std::memcpy(&bits, &f, sizeof bits); // 별칭·정렬 안전한 비트 재해석
std::cout << bits << '\n';
}⚠️ 근거: reinterpret_cast 로 한 타입의 객체를 무관한 타입의 포인터로 보고 역참조하면 엄격 별칭 규칙(strict aliasing)과 정렬 요건을 위반해 미정의 동작이 된다. 영향: 컴파일러는 서로 다른 타입의 포인터가 같은 메모리를 가리키지 않는다고 가정해 최적화하므로, 그 가정을 깬 코드는 최적화 수준에 따라 다른 결과를 내거나 정렬 폴트로 크래시한다. 대응: 비트 단위 재해석이 필요하면 std::memcpy(또는 C++20 std::bit_cast)를 사용해 별칭·정렬 안전하게 처리한다.Rationale: using reinterpret_cast to view an object of one type through a pointer to an unrelated type and dereferencing it violates the strict aliasing rule and alignment requirements, which is undefined behaviour. Impact: the compiler optimizes assuming pointers of different types do not alias, so code breaking that assumption produces different results by optimization level or crashes on an alignment fault. Fix: when bitwise reinterpretation is needed, use std::memcpy (or C++20 std::bit_cast) for aliasing- and alignment-safe handling.
A5-2-6Required · Automated✓ compilable
&& 와 || 의 피연산자는 단순하지 않으면 괄호로 묶는다The operands of a logical && or || shall be parenthesized if the operands contain binary operators
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
bool a = true, b = false, c = true;
if (a && b || c) std::cout << "taken\n"; // && 가 || 보다 우선 — (a&&b)||c 로 해석
// 의도가 a && (b||c) 였다면 결과가 정반대
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
bool a = true, b = false, c = true;
if ((a && b) || c) std::cout << "taken\n"; // 우선순위를 괄호로 명시
}⚠️ 근거: && 는 || 보다 우선순위가 높지만, 이를 외워서 의존하면 a && b || c 가 (a && b) || c 인지 a && (b || c) 인지 독자가 오해하기 쉽다. 영향: 우선순위를 잘못 가정하면 조건이 정반대로 평가되어, 안전 점검·권한 검사 같은 논리에서 치명적 결함이 된다. 대응: 이항 연산자를 포함하는 && / || 의 피연산자를 괄호로 묶어 평가 순서를 코드에 명시한다.Rationale: && has higher precedence than ||, but relying on memorizing this makes readers easily misread whether a && b || c means (a && b) || c or a && (b || c). Impact: a wrong precedence assumption evaluates the condition the opposite way, a critical defect in logic such as safety checks or authorization. Fix: parenthesize the operands of && / || that contain binary operators to make the evaluation order explicit in the code.
A5-3-2Required · Automated✓ compilable
널 포인터를 역참조하지 않는다Null pointers shall not be dereferenced
❌ 위반 예시Non-compliant example
#include <iostream>
#include <map>
struct Node { int v; };
static Node* find(std::map<int,Node>& m, int k) {
auto it = m.find(k);
return it == m.end() ? nullptr : &it->second;
}
int main() {
std::map<int,Node> m;
Node* n = find(m, 7); // 없는 키 → nullptr
n->v = 0; // nullptr 역참조 — 크래시
std::cout << "unreached\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <map>
struct Node { int v; };
static Node* find(std::map<int,Node>& m, int k) {
auto it = m.find(k);
return it == m.end() ? nullptr : &it->second;
}
int main() {
std::map<int,Node> m;
Node* n = find(m, 7);
if (n != nullptr) { n->v = 0; } // 역참조 전 nullptr 검사
else std::cout << "not found\n";
}⚠️ 근거: 어떤 객체도 가리키지 않는 널 포인터를 역참조해 그 대상에 접근하는 것은 미정의 동작이며, 대부분의 플랫폼에서 즉시 세그멘테이션 폴트로 이어진다. 영향: 조회·할당 실패로 널을 반환하는 함수의 결과를 검사 없이 역참조하면 프로그램이 크래시하고, 입력으로 유도되면 서비스 거부 취약점이 된다. 대응: 포인터를 역참조하기 전에 nullptr 인지 검사하거나, 널이 될 수 없도록 참조·옵셔널·보장된 팩토리를 사용한다.Rationale: dereferencing a null pointer — which points to no object — to access its target is undefined behaviour and on most platforms causes an immediate segmentation fault. Impact: dereferencing without checking the result of a function that returns null on lookup or allocation failure crashes the program, and when input-driven becomes a denial-of-service vulnerability. Fix: check for nullptr before dereferencing, or use references, optionals, or guaranteed factories so the pointer cannot be null.
A5-6-1Required · Automated✓ compilable
0으로 나누는 일이 없도록 한다The right hand operand of the integer division or remainder operators shall not be equal to zero
❌ 위반 예시Non-compliant example
#include <iostream>
static int average(int sum, int count) {
return sum / count; // count==0 이면 0 나눗셈 — 미정의 동작(대개 크래시)
}
int main() {
std::cout << average(100, 0) << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <optional>
static std::optional<int> average(int sum, int count) {
if (count == 0) return std::nullopt; // 분모 0 을 먼저 차단
return sum / count;
}
int main() {
auto a = average(100, 0);
std::cout << (a ? std::to_string(*a) : "undefined (count=0)") << '\n';
}⚠️ 근거: 정수 나눗셈 / 과 나머지 % 의 우변(분모)이 0 이면 결과가 수학적으로 정의되지 않아 표준은 미정의 동작으로 규정하며, 대부분의 하드웨어에서 정수 나눗셈 예외로 프로세스가 즉시 종료된다. 영향: 카운트·길이 등 0 이 될 수 있는 값을 검사 없이 분모로 쓰면 런타임 크래시가 나고, 분모가 외부 입력이면 서비스 거부로 악용된다. 대응: 나누기 전에 분모가 0 이 아님을 검사하고, 0 인 경우를 옵셔널·오류 코드 등으로 명시 처리한다.Rationale: when the right operand (divisor) of integer division / or remainder % is zero, the result is mathematically undefined, so the standard makes it undefined behaviour, and most hardware raises an integer-divide exception that immediately terminates the process. Impact: using a possibly-zero value such as a count or length as a divisor without checking causes a runtime crash, and an input-controlled divisor can be exploited for denial of service. Fix: check that the divisor is non-zero before dividing and handle the zero case explicitly with an optional or error code.
A5-16-1Required · Automated✓ compilable
삼항 연산자를 다른 식의 하위 표현식으로 사용하지 않는다The ternary conditional operator shall not be used as a sub-expression
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
bool cond = true; int base = 100, factor = 3;
int r = base + (cond ? 10 : 20) * factor; // 삼항이 큰 식에 묻혀 우선순위 혼동
std::cout << r << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
bool cond = true; int base = 100, factor = 3;
int adj = cond ? 10 : 20; // 삼항을 독립 문장으로 분리
int r = base + adj * factor;
std::cout << r << '\n';
}⚠️ 근거: 삼항 연산자를 더 큰 산술·논리 식의 하위 표현식으로 끼워 넣으면, 삼항의 경계와 연산자 우선순위가 시각적으로 명확하지 않아 의미를 오독하기 쉽다. 영향: base + (cond?10:20) * factor 에서 곱셈이 삼항 결과에만 적용되는지 헷갈려 괄호를 잘못 두면 계산이 어긋나고, 안전필수 로직에서 결함이 된다. 대응: 삼항 결과를 의미 있는 이름의 별도 변수에 담아 한 단계씩 평가가 드러나게 한다.Rationale: embedding the ternary operator as a sub-expression of a larger arithmetic or logical expression makes the boundary of the ternary and the operator precedence visually unclear, easy to misread. Impact: in base + (cond?10:20) * factor it is confusing whether the multiplication applies only to the ternary result, and misplacing parentheses skews the computation — a defect in safety-critical logic. Fix: assign the ternary result to a separate well-named variable so the evaluation is revealed one step at a time.
A5-0-2Required · Automated✓ compilable📄 공식 예제Official example
The condition of an if-statement and the condition of an iteration statement shall have type bool.The condition of an if-statement and the condition of an iteration statement shall have type bool.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <stdexcept>
// $Id: A5-0-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <memory>
extern std::int32_t * Fn();
extern std::int32_t Fn2();
extern bool Fn3();
void F() noexcept(false)
{
std::int32_t* ptr = nullptr;
while ((ptr = Fn()) != nullptr) // Compliant
{
// Code
}
// The following is a cumbersome but compliant example
do
{
std::int32_t* ptr = Fn();
if (nullptr == ptr)
{
break;
}
// Code
} while (true); // Compliant
std::unique_ptr<std::int32_t> uptr;
if (!uptr) // Compliant - std::unique_ptr defines an explicit conversion to
// type bool.
{
// Code
}
while (std::int32_t length = Fn2()) // Compliant by exception
{
// Code
}
while (bool flag = Fn3()) // Compliant
{
// Code
}
if (std::int32_t * ptr = Fn())
; // Compliant by exception
if (std::int32_t length = Fn2())
; // Compliant by exception
if (bool flag = Fn3())
; // Compliant
std::uint8_t u = 8;
if (u)
; // Non-compliant
bool boolean1 = false;
bool boolean2 = true;
if (u && (boolean1 <= boolean2))
; // Non-compliant
for (std::int32_t x = 10; x; --x)
; // Non-compliant
}⚠️ If an expression with type other than bool is used in the condition of an if-statement
or iteration-statement, then its result will be implicitly converted to bool. The condition
expression shall contain an explicit test (yielding a result of type bool) in order to clarify
the intentions of the developer.
Note that if a type defines an explicit conversion to type bool, then it is said to be
“contextually converted to bool” (Section 4.0(4) of ISO/IEC 14882:2014 [3]) and can be
used as a condition of an if-statement or iteration statement.
Exception:
A condition of the form type-specifier-seq declarator is not required to have type bool.
This exception is introduced because alternative mechanisms for achieving the same
effect are cumbersome and error-prone.
See also:
• MISRA C++ 2008 [7]: 5-0-13 The condition of an if-statement and the condition
of an iteration statement shall have type bool.If an expression with type other than bool is used in the condition of an if-statement
or iteration-statement, then its result will be implicitly converted to bool. The condition
expression shall contain an explicit test (yielding a result of type bool) in order to clarify
the intentions of the developer.
Note that if a type defines an explicit conversion to type bool, then it is said to be
“contextually converted to bool” (Section 4.0(4) of ISO/IEC 14882:2014 [3]) and can be
used as a condition of an if-statement or iteration statement.
Exception:
A condition of the form type-specifier-seq declarator is not required to have type bool.
This exception is introduced because alternative mechanisms for achieving the same
effect are cumbersome and error-prone.
See also:
• MISRA C++ 2008 [7]: 5-0-13 The condition of an if-statement and the condition
of an iteration statement shall have type bool.
A5-0-3Required · Automated✓ compilable📄 공식 예제Official example
The declaration of objects shall contain no more than two levels of pointer indirection.The declaration of objects shall contain no more than two levels of pointer indirection.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-0-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
using IntPtr = std::int8_t *;
struct S
{
std::int8_t* s1; // Compliant
std::int8_t** s2; // Compliant
std::int8_t*** s3; // Non-compliant
};
S* ps1; // Compliant
S** ps2; // Compliant
S*** ps3; // Non-compliant
std::int8_t** (*pfunc1)(); // Compliant
std::int8_t** (**pfunc2)(); // Compliant
std::int8_t** (***pfunc3)(); // Non-compliant
std::int8_t*** (**pfunc4)(); // Non-compliant
void Fn(std::int8_t * par1, // Compliant
std::int8_t** par2, // Compliant
std::int8_t*** par3, // Non-compliant
IntPtr* par4, // Compliant
IntPtr* const* const par5, // Non-compliant
std::int8_t* par6[], // Compliant
std::int8_t** par7[]) // Non-compliant
{
std::int8_t* ptr1; // Compliant
std::int8_t** ptr2; // Compliant
std::int8_t*** ptr3; // Non-compliant
IntPtr* ptr4; // Compliant
IntPtr* const* const ptr5 = nullptr; // Non-compliant
std::int8_t* ptr6[10]; // Compliant
std::int8_t** ptr7[10]; // Compliant
}
// Explanation of types
// 1) par1 and ptr1 are of type pointer to std::int8_t.
// 2) par2 and ptr2 are of type pointer to pointer to std::int8_t.
// 3) par3 and ptr3 are of type pointer to a pointer to a pointer
// to std::int8_t.
// This is three levels and is non-compliant.
// 4) par4 and ptr4 are expanded to a type of pointer to a pointer to
// std::int8_t.
// 5) par5 and ptr5 are expanded to a type of const pointer to a const
// pointer
// to a pointer to std::int8_t. This is three levels and is non-compliant.
// 6) par6 is of type pointer to pointer to std::int8_t because arrays
// are converted
// to a pointer to the initial element of the array.
// 7) ptr6 is of type pointer to array of std::int8_t.
// 8) par7 is of type pointer to pointer to pointer to
// std::int8_t because arrays are
// converted to a pointer to the initial element of the array. This is
// three
// levels and is non-compliant.
// 9) ptr7 is of type array of pointer to pointer to std::int8_t. This
// is compliant.⚠️ Use of more than two levels of indirection can seriously impair the ability to understand
the behavior of the code, and therefore should be avoided.
See also:
• MISRA C++ 2008 [7]: 5-0-19 The declaration of objects shall contain no more
than two levels of pointer indirection.Use of more than two levels of indirection can seriously impair the ability to understand
the behavior of the code, and therefore should be avoided.
See also:
• MISRA C++ 2008 [7]: 5-0-19 The declaration of objects shall contain no more
than two levels of pointer indirection.
A5-0-4Required · Automated✓ compilable📄 공식 예제Official example
Pointer arithmetic shall not be used with pointers to non-final classes.Pointer arithmetic shall not be used with pointers to non-final classes.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <string>
#include <cstddef>
// $Id: A5-0-4.cpp 309849 2018-03-02 09:36:31Z christof.meerwald $
#include <algorithm>
#include <array>
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <vector>
class Base
{
public:
virtual ~Base() noexcept = 0;
virtual void Do() = 0;
};
class Derived1 final : public Base
{
public:
void Do() final
{
// ...
}
private:
std::int32_t m_value { 0 };
};
class Derived2 final : public Base
{
public:
void Do() final
{
// ...
}
private:
std::string m_value { };
};
void Foo(Base *start, size_t len)
{
// Non-Compliant: pointer arithmetic on non-final pointer type
for (Base *iter = start; iter != start + len; ++iter)
{
iter->Do();
}
}
void Foo(const std::vector<std::unique_ptr<Base>> &v)
{
// Compliant: uses std::unique_ptr for polymorphic objects
std::for_each(v.begin(), v.end(),
[] (const std::unique_ptr<Base> &ptr) {
ptr->Do();
});
}
void DoOpt(Base *obj)
{
if (obj != nullptr)
{
obj->Do();
}
}
void Bar()
{
std::array<Derived1, 2> arr1;
Base *base1 { arr1.data() };
Foo(base1, arr1.size());
DoOpt(&arr1[1]); // Compliant: pointer arithmetic on final class
DoOpt(&base1[1]); // Non-Compliant: pointer arithmetic on base class
std::array<Derived2, 2> arr2;
Base *base2 { arr2.data() };
Foo(base2, arr2.size());
DoOpt(arr2.data() + 1); // Compliant: pointer arithmetic on final class
DoOpt(base2 + 1); // Non-Compliant: pointer arithmetic on base class
std::vector<std::unique_ptr<Base>> v;
v.push_back(std::make_unique<Derived1>());
v.push_back(std::make_unique<Derived2>());
Foo(v);
}⚠️ Pointer arithmetic is only well defined if the pointed-to type of the pointer equals the
element type of the array it points into, otherwise the behavior is undefined. This
property can only be guaranteed if the pointer operand is a pointer to non-class type
or a pointer to final class type.
Note: This also applies to the subscripting operator as E1[E2] is defined in terms of
pointer arithmetic as *((E1)+(E2)).
See also:
• SEI CERT C++ Coding Standard [10]: CTR56-CPP: Do not use pointer arithmetic
on polymorphic objects.
• JSF December 2005 [8]: AV Rule 96: Arrays shall not be treated polymorphically .
• C++ Core Guidelines [11]: T .82: Do not mix hierarchies and arrays.Pointer arithmetic is only well defined if the pointed-to type of the pointer equals the
element type of the array it points into, otherwise the behavior is undefined. This
property can only be guaranteed if the pointer operand is a pointer to non-class type
or a pointer to final class type.
Note: This also applies to the subscripting operator as E1[E2] is defined in terms of
pointer arithmetic as *((E1)+(E2)).
See also:
• SEI CERT C++ Coding Standard [10]: CTR56-CPP: Do not use pointer arithmetic
on polymorphic objects.
• JSF December 2005 [8]: AV Rule 96: Arrays shall not be treated polymorphically .
• C++ Core Guidelines [11]: T .82: Do not mix hierarchies and arrays.
A5-1-3Required · Automated✓ compilable📄 공식 예제Official example
Parameter list (possibly empty) shall be included in every lambda expression.Parameter list (possibly empty) shall be included in every lambda expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-1-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
void Fn()
{
std::int32_t i = 0;
std::int32_t j = 0;
auto lambda1 = [&i, &j] { ++i, ++j; }; // Non-compliant
auto lambda2 = [&i, &j]() {
++i;
++j;
}; // Compliant
}⚠️ The lambda-declarator is optional in a lambda expression and results in a closure that
can be called without any parameters.
T o avoid any visual ambiguity with other C++ constructs, it is recommended to explicitly
include (), even though it is not strictly required.
See also:
• HIC++ v4.0 [9]: 5.1.5 Include a (possibly empty) parameter list in every lambda
expressionThe lambda-declarator is optional in a lambda expression and results in a closure that
can be called without any parameters.
T o avoid any visual ambiguity with other C++ constructs, it is recommended to explicitly
include (), even though it is not strictly required.
See also:
• HIC++ v4.0 [9]: 5.1.5 Include a (possibly empty) parameter list in every lambda
expression
A5-1-4Required · Automated✓ compilable📄 공식 예제Official example
A lambda expression object shall not outlive any of its reference-captured objects.A lambda expression object shall not outlive any of its reference-captured objects.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-1-4.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <functional>
std::function<std::int32_t()> F()
{
std::int32_t i = 12;
return ([&i]() -> std::int32_t {
i = 100;
return i;
}); // Non-compliant
}
std::function<std::int32_t()> G()
{
std::int32_t i = 12;
return ([i]() mutable -> std::int32_t { return ++i; }); // Compliant
}
void Fn()
{
auto lambda1 = F();
std::int32_t i = lambda1(); // Undefined behavior
auto lambda2 = G();
i = lambda2(); // lambda2() returns 13
}⚠️ When an object is captured by reference in a lambda, lifetime of the object is not tied
to the lifetime of the lambda.
If a lambda object leaves the scope of one of its reference-captured object, the
execution of the lambda expression results in an undefined behavior once the
reference-captured object is accessed.
See also:
• SEI CERT C++ [10]: EXP61-CPP . A lambda object must not outlive any of its
reference captured objects.
• C++ Core Guidelines [11]: F .53: Avoid capturing by reference in lambdas that will
be used nonlocally , including returned, stored on the heap, or passed to another
thread.When an object is captured by reference in a lambda, lifetime of the object is not tied
to the lifetime of the lambda.
If a lambda object leaves the scope of one of its reference-captured object, the
execution of the lambda expression results in an undefined behavior once the
reference-captured object is accessed.
See also:
• SEI CERT C++ [10]: EXP61-CPP . A lambda object must not outlive any of its
reference captured objects.
• C++ Core Guidelines [11]: F .53: Avoid capturing by reference in lambdas that will
be used nonlocally , including returned, stored on the heap, or passed to another
thread.
A5-1-6Advisory · Automated✓ compilable📄 공식 예제Official example
Return type of a non-void return type lambda expression should be explicitly specified.Return type of a non-void return type lambda expression should be explicitly specified.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-1-6.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
void Fn() noexcept
{
auto lambda1 = []() -> std::uint8_t {
std::uint8_t ret = 0U;
// ...
return ret;
}; // Compliant
auto lambda2 = []() {
// ...
return 0U;
}; // Non-compliant - returned type is not specified
auto x = lambda1(); // Type of x is std::uint8_t
auto y = lambda2(); // What is the type of y?
}⚠️ If a non-void return type lambda expression does not specify its return type, then it may
be confusing which type it returns. It leads to developers confusion.
Note that, while the return type is specified, implicit conversion between type of
returned value and return type specified in the lambda expression may occur. This
problem should not be ignored.
See also:
• noneIf a non-void return type lambda expression does not specify its return type, then it may
be confusing which type it returns. It leads to developers confusion.
Note that, while the return type is specified, implicit conversion between type of
returned value and return type specified in the lambda expression may occur. This
problem should not be ignored.
See also:
• none
A5-1-7Required · Automated✓ compilable📄 공식 예제Official example
A lambda shall not be an operand to decltype or typeid.A lambda shall not be an operand to decltype or typeid.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-1-7.cpp 289815 2017-10-06 11:19:11Z michal.szczepankiewicz $
#include <cstdint>
#include <functional>
#include <vector>
void Fn()
{
auto lambda1 = []() -> std::int8_t { return 1; };
auto lambda2 = []() -> std::int8_t { return 1; };
if (typeid(lambda1) == typeid(lambda2)) // Non-compliant - types of lambda1
// and lambda2 are different
{
// ...
}
std::vector<decltype(lambda1)> v; // Non-compliant
// v.push_back([]() { return 1; }); // Compilation error, type of pushed
// lambda is different than decltype(lambda1)
// using mylambda_t = decltype([](){ return 1; }); // Non-compliant -
// compilation error
auto lambda3 = []() { return 2; };
using lambda3_t = decltype(lambda3); // Non-compliant - lambda3_t type can
// not be used for lambda expression
// declarations
// lambda3_t lambda4 = []() { return 2; }; // Conversion error at
// compile-time
std::function<std::int32_t()> f1 = []() { return 3; };
std::function<std::int32_t()> f2 = []() { return 3; };
if (typeid(f1) == typeid(f2)) // Compliant - types are equal
{
// ...
}
}
template <typename T>
void Foo(T t);
void Bar()
{
Foo([]() {}); // Compliant
}⚠️ “The type of the lambda-expression (which is also the type of the closure object) is a
unique, unnamed non-union class type [...]” [C++14 Language Standard] [3]
Each lambda expression has a different unique underlying type, and therefore the type
is not to be used as a decltype or typeid argument. It is allowed to use it as a template
parameter and a function argument.
See also:
• none“The type of the lambda-expression (which is also the type of the closure object) is a
unique, unnamed non-union class type [...]” [C++14 Language Standard] [3]
Each lambda expression has a different unique underlying type, and therefore the type
is not to be used as a decltype or typeid argument. It is allowed to use it as a template
parameter and a function argument.
See also:
• none
A5-1-8Advisory · Automated✓ compilable📄 공식 예제Official example
Lambda expressions should not be defined inside another lambda expression.Lambda expressions should not be defined inside another lambda expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-1-8.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
void Fn1()
{
std::int16_t x = 0;
auto f1 = [&x]() {
auto f2 = []() {}; // Non-compliant
f2();
auto f4 = []() {}; // Non-compliant
f4();
}; // Non-compliant
f1();
}
void Fn2()
{
auto f5 = []() {
// Implementation
}; // Compliant
f5();
}⚠️ Defining lambda expressions inside other lambda expressions reduces readability of
the code.
See also:
• noneDefining lambda expressions inside other lambda expressions reduces readability of
the code.
See also:
• none
A5-1-9Advisory · Automated✓ compilable📄 공식 예제Official example
Identical unnamed lambda expressions shall be replaced with a named function or a named lambda expression.Identical unnamed lambda expressions shall be replaced with a named function or a named lambda expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-1-9.cpp 307019 2018-02-09 15:16:47Z christof.meerwald $
#include <algorithm>
#include <cstdint>
#include <vector>
void Fn1(const std::vector<int16_t> &v)
{
// Non-compliant: identical unnamed lambda expression
if (std::none_of(v.begin(), v.end(),
[] (int16_t i) { return i < 0; }))
{
// ...
}
else if (std::all_of(v.begin(), v.end(),
[] (int16_t i) { return i < 0; }))
{
// ...
}
}
void Fn2(const std::vector<int16_t> &v)
{
// Compliant: re-using lambda expression
auto is_negative = [] (int16_t i) { return i < 0; };
if (std::none_of(v.begin(), v.end(), is_negative))
{
// ...
}
else if (std::all_of(v.begin(), v.end(), is_negative))
{
// ...
}
}⚠️ Code duplication reduces readability and maintainability as it might not be obvious that
the lambda expressions are identical and any changes need to be applied in more than
one place.
See also:
• C++ Core Guidelines [11]: T .141: Use an unnamed lambda if you need a simple
function object in one place only .
6.5.2 Postfix expressionsCode duplication reduces readability and maintainability as it might not be obvious that
the lambda expressions are identical and any changes need to be applied in more than
one place.
See also:
• C++ Core Guidelines [11]: T .141: Use an unnamed lambda if you need a simple
function object in one place only .
6.5.2 Postfix expressions
A5-10-1Required · Automated✓ compilable📄 공식 예제Official example
A pointer to member virtual function shall only be tested for equality with null-pointer-constant.A pointer to member virtual function shall only be tested for equality with null-pointer-constant.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-10-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
class A
{
public:
virtual ~A() = default;
void F1() noexcept {}
void F2() noexcept {}
virtual void F3() noexcept {}
};
void Fn()
{
bool b1 = (&A::F1 == &A::F2); // Compliant
bool b2 = (&A::F1 == nullptr); // Compliant
bool b3 = (&A::F3 == nullptr); // Compliant
bool b4 = (&A::F3 != nullptr); // Compliant
bool b5 = (&A::F3 == &A::F1); // Non-compliant
}⚠️ The result of equality comparison between pointer to member virtual function and
anything other than null-pointer-constant (i.e. nullptr, see: A4-10-1) is unspecified.
See also:
• HIC++ v4.0 [9]: 5.7.2 Ensure that a pointer to member that is a virtual function is
only compared (==) with nullptr.
• JSF December 2005 [8]: AV Rule 97.1 Neither operand of an equality operator
(== or !=) shall be a pointer to a virtual member function.
6.5.14 Logical AND operatorThe result of equality comparison between pointer to member virtual function and
anything other than null-pointer-constant (i.e. nullptr, see: A4-10-1) is unspecified.
See also:
• HIC++ v4.0 [9]: 5.7.2 Ensure that a pointer to member that is a virtual function is
only compared (==) with nullptr.
• JSF December 2005 [8]: AV Rule 97.1 Neither operand of an equality operator
(== or !=) shall be a pointer to a virtual member function.
6.5.14 Logical AND operator
A5-2-1Advisory · Automated✓ compilable📄 공식 예제Official example
dynamic_cast should not be used.dynamic_cast should not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-2-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
class A
{
public:
virtual void F() noexcept;
};
class B : public A
{
public:
void F() noexcept override {}
};
void Fn(A * aptr) noexcept
{
// ...
B* bptr = dynamic_cast<B *>(aptr); // Non-compliant
if (bptr != nullptr)
{
// Use B class interface
}
else
{
// Use A class interface
}
}⚠️ Implementations of dynamic_cast mechanism are unsuitable for use with real-time
systems where low memory usage and determined performance are essential.
If dynamic casting is essential for your program, usage of its custom implementation
should be considered. Also, usage of the dynamic_cast can be replaced with
polymorphism, i.e. virtual functions.
See also:
• JSF December 2005 [8]: AV Rule 178: Down casting (casting from base to
derived class) shall only be allowed through one of the following mechanism:
Virtual functions that act like dynamic casts (most likely useful in relatively simple
cases); Use of the visitor (or similar) pattern (most likely useful in complicated
cases).
• C++ Core Guidelines [11]: C.146: Use dynamic_cast where class hierarchy
navigation is unavoidable.
• Journal of Computing Science and Engineering, Damian Dechev, Rabi
Mahapatra, Bjarne Stroustrup: Practical and Verifiable C++ Dynamic Cast for
Hard Real-Time Systems.
• Software-Practice and Experience, Michael Gibbs and Bjarne Stroustrup: Fast
dynamic casting.Implementations of dynamic_cast mechanism are unsuitable for use with real-time
systems where low memory usage and determined performance are essential.
If dynamic casting is essential for your program, usage of its custom implementation
should be considered. Also, usage of the dynamic_cast can be replaced with
polymorphism, i.e. virtual functions.
See also:
• JSF December 2005 [8]: AV Rule 178: Down casting (casting from base to
derived class) shall only be allowed through one of the following mechanism:
Virtual functions that act like dynamic casts (most likely useful in relatively simple
cases); Use of the visitor (or similar) pattern (most likely useful in complicated
cases).
• C++ Core Guidelines [11]: C.146: Use dynamic_cast where class hierarchy
navigation is unavoidable.
• Journal of Computing Science and Engineering, Damian Dechev, Rabi
Mahapatra, Bjarne Stroustrup: Practical and Verifiable C++ Dynamic Cast for
Hard Real-Time Systems.
• Software-Practice and Experience, Michael Gibbs and Bjarne Stroustrup: Fast
dynamic casting.
A5-2-5Required · Automated✓ compilable📄 공식 예제Official example
An array or container shall not be accessed beyond its range.An array or container shall not be accessed beyond its range.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <stdexcept>
// $Id: A5-2-5.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <array>
#include <cstdint>
#include <iostream>
void Fn1() noexcept
{
constexpr std::int32_t arraySize = 16;
std::int32_t array[arraySize]{0};
std::int32_t elem1 =
array[0]; // Compliant - access with constant literal that
// is less than ArraySize
std::int32_t elem2 =
array[12]; // Compliant - access with constant literal that
// is less than ArraySize
for (std::int32_t idx = 0; idx < 20; ++idx)
{
std::int32_t elem3 =
array[idx]; // Non-compliant - access beyond ArraySize
// bounds, which has 16 elements
}
std::int32_t shift = 25;
std::int32_t elem4 =
*(array + shift); // Non-compliant - access beyond ArraySize bounds
std::int32_t index = 0;
std::cin >> index;
std::int32_t elem5 =
array[index]; // Non-compliant - index may exceed the ArraySize bounds
if (index < arraySize)
{
std::int32_t elem6 = array[index]; // Compliant - range check coded
}
}
void Fn2() noexcept
{
constexpr std::int32_t arraySize = 32;
std::array<std::int32_t, arraySize> array;
array.fill(0);
std::int32_t elem1 =
array[10]; // Compliant - access with constant literal that
// is less than ArraySize
std::int32_t index = 40;
std::int32_t elem2 =
array[index]; // Non-compliant - access beyond ArraySize bounds
try
{
std::int32_t elem3 =
array.at(50); // Compliant - at() method provides a
// range check, throwing an exception if
// input exceeds the bounds
}
catch (std::out_of_range&)
{
// Handle an error
}
for (auto&& e : array) // The std::array provides a possibility to iterate
// over its elements with range-based loop
{
// Iterate over all elements
}
}⚠️ T o avoid undefined behavior, range checks should be coded to ensure that container
access via iterator arithmetic or subscript operator is within defined bounds. This could
also be achieved by accessing an array via a subscript operator with constant indices
only .
When copying data via standard library algorithms (such as std::copy or
std::transform), the target destination must be guaranteed to be large enough
to hold the data.
Note: This rule applies to C-style arrays and all other containers (including
std::basic_string) that access their elements via iterators or via an index. The
term iterator includes pointers.
Note: Calculating an iterator one past the last element of the array is well defined, but
dereferencing such an iterator is not.
See also:
• HIC++ v4.0 [9]: 5.2.1: Ensure that pointer or array access is demonstrably within
bounds of a valid object.T o avoid undefined behavior, range checks should be coded to ensure that container
access via iterator arithmetic or subscript operator is within defined bounds. This could
also be achieved by accessing an array via a subscript operator with constant indices
only .
When copying data via standard library algorithms (such as std::copy or
std::transform), the target destination must be guaranteed to be large enough
to hold the data.
Note: This rule applies to C-style arrays and all other containers (including
std::basic_string) that access their elements via iterators or via an index. The
term iterator includes pointers.
Note: Calculating an iterator one past the last element of the array is well defined, but
dereferencing such an iterator is not.
See also:
• HIC++ v4.0 [9]: 5.2.1: Ensure that pointer or array access is demonstrably within
bounds of a valid object.
A5-3-1Required · Non-automated✓ compilable📄 공식 예제Official example
Evaluation of the operand to the typeid operator shall not contain side effects.Evaluation of the operand to the typeid operator shall not contain side effects.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-3-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <typeinfo>
bool SideEffects() noexcept
{
// Implementation
return true;
}
class A
{
public:
static A& F1() noexcept { return a; }
virtual ~A() {}
private:
static A a;
};
A A::a;
void F2() noexcept(false)
{
typeid(SideEffects()); // Non-compliant - sideEffects() function not called
typeid(A::F1()); // Non-compliant - A::f1() functions called to determine
// the polymorphic type
}⚠️ The operand of typeid operator is evaluated only if it is a function call which returns a
reference to a polymorphic type.
Providing side effects to typeid operator, which takes place only under special
circumstances, makes the code more difficult to maintain.
See also:
• HIC++ v4.0 [9]: 5.1.6 Do not code side effects into the right-hand operands of:
&&, ||, sizeof, typeid or a function passed to condition_variable::wait.The operand of typeid operator is evaluated only if it is a function call which returns a
reference to a polymorphic type.
Providing side effects to typeid operator, which takes place only under special
circumstances, makes the code more difficult to maintain.
See also:
• HIC++ v4.0 [9]: 5.1.6 Do not code side effects into the right-hand operands of:
&&, ||, sizeof, typeid or a function passed to condition_variable::wait.
A5-3-3Required · Automated✓ compilable📄 공식 예제Official example
Pointers to incomplete class types shall not be deleted.Pointers to incomplete class types shall not be deleted.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-3-3.cpp 309184 2018-02-26 20:38:28Z jan.babst $ // Non-compliant: At the point of deletion, pimpl points // to an incomplete class type. class Bad { class Impl; Impl* pimpl; public: // ... ~Bad() { delete pimpl; } // violates A18-5-2 }; // Compliant: At the point of deletion, pimpl points to // a complete class type. // In a header file ... class Good { class Impl; Impl* pimpl; public: // ... ~Good(); }; // In an implementation file ... class Good::Impl { // ... }; // Good::Impl is a complete type now Good::~Good() { delete pimpl; // violates A18-5-2 } // Compliant: Contemporary solution using std::unique_ptr // and conforming to A18-5-2. // Note that std::unique_ptr<Impl> requires Impl to be a complete type // at the point where pimpl is deleted and thus automatically enforces // A5-3-3. This is the reason why the destructor of Better must be defined in an // implementation file when Better::Impl is a complete type, even if the // definition is just the default one. // In a header file ... #include <memory> class Better { class Impl; std::unique_ptr<Impl> pimpl; public: // ... ~Better(); }; // In an implementation file ... class Better::Impl { // ... }; // Better::Impl is a complete type now Better::~Better() = default;
⚠️ Incomplete class types are forward declared class types, for which the compiler has
not yet seen a definition. It is undefined behavior if a pointer to an incomplete class
type is deleted, and the class has a non-trivial destructor or a deallocation function.
This rule prohibits deletion of such a pointer even in the harmless case of a trivially
destructible class type without a deallocation function, since a non-trivial destructor or
a deallocation function may be added later as the code evolves.
See also:
• ISO/IEC 14882:2014 [3]: 5.3.5: [expr.delete]
• SEI CERT C++ Coding Standard [10]: EXP57-CPP: Do not cast or delete pointers
to incomplete classes.
6.5.5 Pointer-to-memberIncomplete class types are forward declared class types, for which the compiler has
not yet seen a definition. It is undefined behavior if a pointer to an incomplete class
type is deleted, and the class has a non-trivial destructor or a deallocation function.
This rule prohibits deletion of such a pointer even in the harmless case of a trivially
destructible class type without a deallocation function, since a non-trivial destructor or
a deallocation function may be added later as the code evolves.
See also:
• ISO/IEC 14882:2014 [3]: 5.3.5: [expr.delete]
• SEI CERT C++ Coding Standard [10]: EXP57-CPP: Do not cast or delete pointers
to incomplete classes.
6.5.5 Pointer-to-member
A5-5-1Required · Automated✓ compilable📄 공식 예제Official example
A pointer to member shall not access non-existent class members.A pointer to member shall not access non-existent class members.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A5-5-1.cpp 302200 2017-12-20 17:17:08Z michal.szczepankiewicz $
class A
{
public:
virtual ~A() = default;
};
class AA : public A
{
public:
virtual ~AA() = default;
virtual void foo() { }
using ptr = void (AA:: *)();
};
class B
{
public:
static AA::ptr foo_ptr2;
};
AA::ptr B::foo_ptr2;
int main(void)
{
A* a = new A();
void (A:: *foo_ptr1)() = static_cast<void(A:: *)()>(&AA::foo);
(a->*foo_ptr1)(); // non-compliant
delete a;
AA* aa = new AA();
(aa->*B::foo_ptr2)(); // non-compliant, not explicitly initialized
delete aa;
return 0;
}⚠️ Usage of a pointer-to-member expression leads to undefined behavior in the following
cases:
• The pointer to member is a null pointer.
• The dynamic type of the object does not contain the member to which the called
pointer to member refers.
See also:
• SEI CERT C++ Coding Standard [10]: OOP55-CPP: Do not use pointer-to-
member operators to access nonexistent members
6.5.6 Multiplicative operatorsUsage of a pointer-to-member expression leads to undefined behavior in the following
cases:
• The pointer to member is a null pointer.
• The dynamic type of the object does not contain the member to which the called
pointer to member refers.
See also:
• SEI CERT C++ Coding Standard [10]: OOP55-CPP: Do not use pointer-to-
member operators to access nonexistent members
6.5.6 Multiplicative operators
A6A6 (AUTOSAR)A6 (AUTOSAR-original)
A6-4-1Required · Automated✓ compilable
enum 을 다루는 switch 는 모든 열거자에 대한 case 를 가진다A switch statement shall have a case for each enumerator of the controlling enum
❌ 위반 예시Non-compliant example
#include <iostream>
enum class State { Idle, Run, Stop };
static const char* name(State s) {
switch (s) {
case State::Idle: return "idle";
case State::Run: return "run";
// State::Stop 누락 — Stop 이 들어오면 아무 case 도 안 탐
}
return "?";
}
int main() { std::cout << name(State::Stop) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
enum class State { Idle, Run, Stop };
static const char* name(State s) {
switch (s) {
case State::Idle: return "idle";
case State::Run: return "run";
case State::Stop: return "stop"; // 모든 열거자 명시 처리
}
return "?";
}
int main() { std::cout << name(State::Stop) << '\n'; }⚠️ 근거: 열거형을 다루는 switch 에 모든 열거자 case 를 두면, 나중에 열거자가 추가됐을 때 컴파일러가 처리되지 않은 case 를 경고(-Wswitch)로 잡아준다. 영향: 일부 열거자를 빠뜨리면 새 값이 추가돼도 조용히 처리가 누락되어, 상태 기계·명령 디스패치에서 의도치 않은 기본 동작이나 오류가 발생한다. 대응: default 로 뭉뚱그리기보다 모든 열거자를 명시적으로 처리해, 열거형 변경 시 컴파일러가 미처리 case 를 알려주게 한다.Rationale: having a case for every enumerator in a switch on an enum lets the compiler warn (-Wswitch) about an unhandled case when an enumerator is later added. Impact: omitting some enumerators silently drops handling when a new value is added, causing unintended default behaviour or errors in state machines and command dispatch. Fix: handle every enumerator explicitly rather than lumping them under default, so the compiler flags unhandled cases when the enum changes.
A6-5-3Advisory · Automated✓ compilable
do-while 문을 사용하지 않는다Do statements should not be used
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int n = 0;
do {
std::cout << "body runs at least once\n"; // 조건이 처음부터 거짓이어도 1회 실행
} while (n > 0);
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int n = 0;
while (n > 0) {
std::cout << "body\n"; // 선조건 — 조건이 거짓이면 한 번도 실행 안 함
}
std::cout << "loop checked condition first\n";
}⚠️ 근거: do-while 은 조건 검사가 본문 뒤에 있어 본문이 항상 최소 한 번 실행되는데, 코드를 위에서 아래로 읽는 독자는 이 사실을 간과하기 쉽다. 영향: 입력이 비어 있거나 조건이 처음부터 거짓인 경우에도 본문이 한 번 실행되어, 빈 컬렉션 처리·경계 조건에서 예기치 않은 부작용이 발생한다. 대응: 조건을 먼저 검사하는 while 또는 for 로 바꿔 0회 실행 가능성을 코드 형태로 드러낸다.Rationale: in a do-while the condition is checked after the body, so the body always runs at least once, a fact readers scanning top to bottom easily overlook. Impact: even with empty input or a condition false from the start, the body executes once, causing unexpected side effects when handling empty collections or boundary conditions. Fix: switch to a while or for loop that checks the condition first, making the zero-iteration possibility visible in the code structure.
A6-6-1Required · Automated✓ compilable
goto 문을 사용하지 않는다The goto statement shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int* buf = new int[10];
bool err = true;
if (err) goto cleanup; // 비선형 점프 — 흐름 분석을 어렵게 함
buf[0] = 1;
cleanup:
delete[] buf;
std::cout << "done\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
int main() {
auto buf = std::make_unique<int[]>(10); // RAII — 모든 경로에서 자동 정리
bool err = true;
if (!err) { buf[0] = 1; }
std::cout << "done\n"; // goto 없이 구조적 제어로 정리 보장
}⚠️ 근거: goto 는 함수 안 임의 지점으로 제어를 옮겨 비선형 흐름을 만들고, 객체 수명·초기화를 건너뛰는 점프는 분석과 추론을 어렵게 한다. 영향: goto 기반 정리 패턴은 라벨이 늘수록 흐름이 얽혀 자원 해제 누락·이중 해제 같은 결함을 부르고, 정적 분석·검토를 방해한다. 대응: RAII 로 정리를 객체 소멸자에 위임하고, 분기·반복·조기 return 같은 구조적 제어문으로 흐름을 선형적으로 표현한다.Rationale: goto transfers control to an arbitrary point in a function, creating non-linear flow, and jumps that skip object lifetimes or initialization make analysis and reasoning hard. Impact: goto-based cleanup patterns tangle as labels multiply, inviting defects like missed or double resource release, and hinder static analysis and review. Fix: delegate cleanup to object destructors via RAII and express flow linearly with structured control statements such as branches, loops, and early return.
A6-2-1Required · Automated✓ compilable📄 공식 예제Official example
Move and copy assignment operators shall either move or respectively copy base classes and data members of a class, without any side effects.Move and copy assignment operators shall either move or respectively copy base classes and data members of a class, without any side effects.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A6-2-1.cpp 305786 2018-01-30 08:58:33Z michal.szczepankiewicz $
#include <cstdint>
#include <utility>
class A
{
public:
A& operator=(const A& oth) // Compliant
{
if(&oth == this)
{
return *this;
}
x = oth.x;
return *this;
}
private:
std::int32_t x;
};
class B
{
public:
~B() { delete ptr; }
//compliant
B& operator=(B&& oth)
{
if(&oth == this)
{
return *this;
}
ptr = std::move(oth.ptr);
// Compliant - this is not a side-effect, in this
// case it is essential to leave moved-from object
// in a valid state, otherwise double deletion will
// occur.
return *this;
}
private:
std::int32_t* ptr;
};
class C
{
public:
C& operator=(const C& oth)
{
if(&oth == this)
{
return *this;
}
x = oth.x % 2; // Non-compliant - unrelated side-effect
return *this;
}
private:
std::int32_t x;
};
class D
{
public:
explicit D(std::uint32_t a) : a(a), noOfModifications(0) {}
D& operator=(const D& oth)
{
if(&oth == this)
{
return *this;
}
a = oth.a;
//compliant, not copying the debug information about number of
modifications
return *this;
}
void SetA(std::uint32_t aa)
{
++noOfModifications;
a = aa;
}
std::uint32_t GetA() const noexcept
{
return a;
}
private:
std::uint32_t a;
std::uint64_t noOfModifications;
};⚠️ It is expected behavior that the move/copy assigned operator are only used to
move/copy the object of the class type and possibly set moved-from object to a valid
state. Those operators are not supposed to provide any performance overhead or side
effects that could affect moving or copying the object.
Note: Class members that are not essential for a class invariant may not need to be
moved/copied (e.g. caches, debug information).
See also:
• JSF December 2005 [8]: AV Rule 83: An assignment operator shall assign
all data members and bases that affect the class invariant (a data element
representing a cache, for example, would not need to be copied).It is expected behavior that the move/copy assigned operator are only used to
move/copy the object of the class type and possibly set moved-from object to a valid
state. Those operators are not supposed to provide any performance overhead or side
effects that could affect moving or copying the object.
Note: Class members that are not essential for a class invariant may not need to be
moved/copied (e.g. caches, debug information).
See also:
• JSF December 2005 [8]: AV Rule 83: An assignment operator shall assign
all data members and bases that affect the class invariant (a data element
representing a cache, for example, would not need to be copied).
A6-2-2Required · Automated✓ compilable📄 공식 예제Official example
Expression statements shall not be explicit calls to constructors of temporary objects only.Expression statements shall not be explicit calls to constructors of temporary objects only.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <string>
// $Id: A6-2-2.cpp 326655 2018-07-20 14:58:55Z christof.meerwald $
#include <cstdint>
#include <fstream>
#include <mutex>
class A
{
public:
void SetValue1(std::int32_t value)
{
std::lock_guard<std::mutex> {m_mtx}; // Non-compliant: temporary object
// Assignment to m_value is not protected by lock
m_value = value;
}
void SetValue2(std::int32_t value)
{
std::lock_guard<std::mutex> guard{m_mtx}; // Compliant: local variable
m_value = value;
}
private:
mutable std::mutex m_mtx;
std::int32_t m_value;
};
void Print(std::string const & fname, std::string const & s)
{
// Compliant: Not only constructing a temporary object
std::ofstream{fname}.write(s.c_str(), s.length());
}⚠️ The developer’s intention might have been to define an unnamed local variable
that would live until the end of the scope to implement the RAII pattern (Resource
Acquisition Is Initialization). But as there are no unnamed variables in C++, it is in
fact only creating a temporary object that gets destroyed again at the end of the full
expression.
See also:
• C++ Core Guidelines [11]: ES.84: Don’t (try to) declare a local variable with no
name
• C++ Core Guidelines [11]: CP .44: Remember to name your lock_guards and
unique_locksThe developer’s intention might have been to define an unnamed local variable
that would live until the end of the scope to implement the RAII pattern (Resource
Acquisition Is Initialization). But as there are no unnamed variables in C++, it is in
fact only creating a temporary object that gets destroyed again at the end of the full
expression.
See also:
• C++ Core Guidelines [11]: ES.84: Don’t (try to) declare a local variable with no
name
• C++ Core Guidelines [11]: CP .44: Remember to name your lock_guards and
unique_locks
A6-5-1Required · Automated✓ compilable📄 공식 예제Official example
A for-loop that loops through all elements of the container and does not use its loop-counter shall not be used.A for-loop that loops through all elements of the container and does not use its loop-counter shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A6-5-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <iterator>
void Fn() noexcept
{
constexpr std::int8_t arraySize = 7;
std::uint32_t array[arraySize] = {0, 1, 2, 3, 4, 5, 6};
for (std::int8_t idx = 0; idx < arraySize; ++idx) // Compliant
{
array[idx] = idx;
}
for (std::int8_t idx = 0; idx < arraySize / 2;
++idx) // Compliant - for does not loop though all elements
{
// ...
}
for (std::uint32_t * iter = std::begin(array); iter != std::end(array);
++iter) // Non-compliant
{
// ...
}
for (std::int8_t idx = 0; idx < arraySize; ++idx) // Non-compliant
{
// ...
}
for (std::uint32_t value :
array) // Compliant - equivalent to non-compliant loops above
{
// ...
}
for (std::int8_t idx = 0; idx < arraySize; ++idx) // Compliant
{
if ((idx % 2) == 0)
{
// ...
}
}
}⚠️ A for-loop that simply loops through all elements of the container and does not use its
loop-counter is equivalent to a range-based for statement that reduces the amount of
code to maintain correct loop semantics.
See also:
• HIC++ v4.0 [9]: 6.2.1 Implement a loop that only uses element values as a range-
based loop.
• C++ Core Guidelines [11]: ES.55: Avoid the need for range checking.
• C++ Core Guidelines [11]: ES.71: Prefer a range-for-statement to a for-statement
when there is a choice.A for-loop that simply loops through all elements of the container and does not use its
loop-counter is equivalent to a range-based for statement that reduces the amount of
code to maintain correct loop semantics.
See also:
• HIC++ v4.0 [9]: 6.2.1 Implement a loop that only uses element values as a range-
based loop.
• C++ Core Guidelines [11]: ES.55: Avoid the need for range checking.
• C++ Core Guidelines [11]: ES.71: Prefer a range-for-statement to a for-statement
when there is a choice.
A6-5-2Required · Automated✓ compilable📄 공식 예제Official example
A for loop shall contain a single loop-counter which shall not have floating-point type.A for loop shall contain a single loop-counter which shall not have floating-point type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A6-5-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
namespace
{
constexpr std::int32_t xlimit = 20;
constexpr std::int32_t ylimit = 15;
constexpr float zlimit = 2.5F;
constexpr std::int32_t ilimit = 100;
}
void Fn() noexcept
{
std::int32_t y = 0;
for (std::int32_t x = 0; x < xlimit && y < ylimit;
x++, y++) // Non-compliant, two loop-counters
{
// ...
}
for (float z = 0.0F; z != zlimit;
z += 0.1F) // Non-compliant, float with !=
{
// ...
}
for (float z = 0.0F; z < zlimit; z += 0.1F) // Non-compliant, float with <
{
// ...
}
for (std::int32_t i = 0; i < ilimit; ++i) // Compliant
{
// ...
}
}⚠️ A for loop without a loop-counter is simply a while loop. If this is the desired behavior,
then a while loop is more appropriate.
Floating types, as they should not be tested for equality/inequality , are not to be used
as loop-counters.
See also:
• MISRA C++ 2008 [7]: Rule 6-5-1 A for loop shall contain a single loop-counter
which shall not have floating type.
• C++ Core Guidelines [11]: ES.72: Prefer a for-statement to a while-statement
when there is an obvious loop variable.A for loop without a loop-counter is simply a while loop. If this is the desired behavior,
then a while loop is more appropriate.
Floating types, as they should not be tested for equality/inequality , are not to be used
as loop-counters.
See also:
• MISRA C++ 2008 [7]: Rule 6-5-1 A for loop shall contain a single loop-counter
which shall not have floating type.
• C++ Core Guidelines [11]: ES.72: Prefer a for-statement to a while-statement
when there is an obvious loop variable.
A6-5-4Advisory · Automated✓ compilable📄 공식 예제Official example
For-init-statement and expression should not perform actions other than loop-counter initialization and modification.For-init-statement and expression should not perform actions other than loop-counter initialization and modification.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A6-5-4.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
#include <cstdint>
void Fn() noexcept
{
for (std::int32_t x = 0, MAX=10; x < MAX; x++) // compliant with A6-5-2, but
non-compliant with advisory A6-5-4
{
// ...
}
}⚠️ If only a loop-counter is used in the for-init-statement and expression, it increases
readability and it is easier to understand and maintain code.
See also:
• JSF December 2005 [8]: AV Rule 198: The initialization expression in a for
loop will perform no actions other than to initialize the value of a single for loop
parameter.
• JSF December 2005 [8]: AV Rule 199: The increment expression in a for loop
will perform no action other than to change a single loop parameter to the next
value for the loop.
6.6.6 Jump statementsIf only a loop-counter is used in the for-init-statement and expression, it increases
readability and it is easier to understand and maintain code.
See also:
• JSF December 2005 [8]: AV Rule 198: The initialization expression in a for
loop will perform no actions other than to initialize the value of a single for loop
parameter.
• JSF December 2005 [8]: AV Rule 199: The increment expression in a for loop
will perform no action other than to change a single loop parameter to the next
value for the loop.
6.6.6 Jump statements
A7A7 (AUTOSAR)A7 (AUTOSAR-original)
A7-1-1Required · Automated✓ compilable
변경되지 않는 변수/멤버는 const(또는 constexpr)로 선언한다Constexpr or const specifiers shall be used for immutable data declaration
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int radius = 5; // 이후 수정이 없는데도 비-const — 실수로 바뀔 여지
double area = 3.14159 * radius * radius;
std::cout << area << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
const int radius = 5; // 불변 의도를 const 로 강제
double area = 3.14159 * radius * radius;
std::cout << area << '\n';
}⚠️ 근거: 초기화 후 값이 바뀌지 않는 변수에 const(컴파일 타임 상수면 constexpr)를 붙이면, 그 불변 의도가 코드에 드러나고 컴파일러가 우발적 수정을 차단한다. 영향: 불변 값을 비-const 로 두면 나중에 실수로 대입되거나, 독자가 그 값이 변할 수 있다고 오해해 불필요한 방어 코드를 더하게 된다. 대응: 변경되지 않는 지역·멤버·매개변수를 const/constexpr 로 선언해 불변성을 강제하고 의도를 명확히 한다.Rationale: marking a variable whose value never changes after initialization as const (constexpr if a compile-time constant) reveals the immutable intent in the code and lets the compiler block accidental modification. Impact: leaving an immutable value non-const allows a later mistaken assignment, or leads readers to assume it can change and add unnecessary defensive code. Fix: declare unchanging locals, members, and parameters as const/constexpr to enforce immutability and clarify intent.
A7-1-6Required · Automated✓ compilable
typedef 대신 using 별칭을 사용한다The typedef specifier shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <map>
#include <string>
typedef std::map<int, std::string> Table; // 구식 typedef — 템플릿 별칭 불가
int main() {
Table t; t[1] = "one";
std::cout << t[1] << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <map>
#include <string>
using Table = std::map<int, std::string>; // using 별칭 — 읽기 쉽고 일관적
template <typename V> using IntMap = std::map<int, V>; // 별칭 템플릿도 가능
int main() {
Table t; t[1] = "one";
IntMap<double> d; d[2] = 2.5;
std::cout << t[1] << ' ' << d[2] << '\n';
}⚠️ 근거: using 별칭은 "별명 = 실제타입" 형태로 좌→우로 자연스럽게 읽히고, typedef 가 지원하지 못하는 별칭 템플릿(template using)까지 표현할 수 있다. 영향: typedef 와 using 을 섞어 쓰면 스타일이 불일치하고, 함수 포인터·배열 같은 복잡한 타입의 typedef 는 읽기 어려워 오해를 부른다. 대응: 타입 별칭은 일관되게 using 으로 작성해 가독성과 템플릿 별칭 지원을 확보한다.Rationale: a using alias reads naturally left to right as "alias = actual type" and can even express alias templates (template using), which typedef cannot. Impact: mixing typedef and using is stylistically inconsistent, and typedefs of complex types like function pointers or arrays are hard to read and misleading. Fix: write type aliases consistently with using for readability and alias-template support.
A7-1-7Required · Automated✓ compilable
한 선언문에는 하나의 변수/이름만 선언한다Each expression statement and identifier declaration shall be placed on a separate line
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int* a, b; // 직관과 달리 a 만 포인터, b 는 int — 오해 유발
int x = 0;
a = &x; b = 5;
std::cout << *a << ' ' << b << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int* a; // 한 줄에 하나씩 — 타입이 명확
int b;
int x = 0;
a = &x; b = 5;
std::cout << *a << ' ' << b << '\n';
}⚠️ 근거: 한 선언문에 여러 이름을 적으면 포인터·참조 표기(*, &)가 첫 이름에만 적용되는 등 타입이 직관과 달라, int* a, b; 에서 b 가 포인터가 아니라 int 라는 사실이 가려진다. 영향: 선언을 잘못 읽으면 b 를 포인터로 착각해 잘못 사용하거나, 초기화를 한 변수에만 적용하는 실수가 생긴다. 대응: 한 선언문에는 하나의 변수만 선언하고 각 선언을 별도 줄에 두어 타입을 분명히 한다.Rationale: declaring multiple names in one statement applies pointer/reference notation (*, &) only to the first name, so in int* a, b; the fact that b is an int rather than a pointer is hidden. Impact: misreading the declaration leads to mistaking b for a pointer and misusing it, or applying initialization to only one variable by mistake. Fix: declare one variable per statement on its own line to make types clear.
A7-2-2Required · Automated✓ compilable
열거형의 기반 타입(underlying type)을 명시한다Enumeration underlying base type shall be explicitly defined
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdint>
enum class Mode { A, B, C }; // 기반 타입 미명시 — 크기·표현이 불확실
int main() {
std::cout << sizeof(Mode) << '\n'; // 구현정의 크기(보통 int=4)
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstdint>
enum class Mode : std::uint8_t { A, B, C }; // 기반 타입 명시 — 1바이트로 고정
int main() {
std::cout << sizeof(Mode) << '\n'; // 1 — 직렬화·ABI 안정
}⚠️ 근거: 범위 지정 enum 의 기반 타입을 명시하지 않으면 기본값(보통 int)에 맡겨져 열거형의 크기와 비트 표현이 불확실해진다. 영향: 직렬화·메모리 매핑·하드웨어 레지스터·다른 언어와의 ABI 경계에서 기대한 폭과 실제 폭이 어긋나 데이터가 깨지고, 좁은 저장이 필요한 임베디드에서 메모리를 낭비한다. 대응: enum class Mode : std::uint8_t 처럼 기반 타입을 명시해 크기와 표현을 고정한다.Rationale: not specifying the underlying type of a scoped enum leaves it to the default (usually int), making the size and bit representation of the enum uncertain. Impact: at serialization, memory mapping, hardware registers, or an ABI boundary with another language, the expected and actual widths mismatch and corrupt data, and it wastes memory in embedded systems that need narrow storage. Fix: specify the underlying type, as in enum class Mode : std::uint8_t, to fix the size and representation.
A7-2-3Required · Automated✓ compilable
열거형은 범위 지정 enum class 로 선언한다Enumerations shall be declared as scoped enum classes
❌ 위반 예시Non-compliant example
#include <iostream>
enum Color { Red, Green, Blue }; // 비범위 — 열거자가 전역으로 새고 int 로 암시 변환
int main() {
int x = Red; // 암시적 정수 변환 — 타입 안전성 없음
if (x == Green - 1) std::cout << "fragile compare\n"; // 열거자 산술
}✅ 준수 예시Compliant example
#include <iostream>
enum class Color { Red, Green, Blue }; // 범위 지정 — 이름 충돌·암시 변환 차단
int main() {
Color c = Color::Red;
if (c == Color::Red) std::cout << "type-safe compare\n";
}⚠️ 근거: 비범위 enum 은 열거자 이름이 둘러싼 범위로 그대로 새어 나와 다른 이름과 충돌할 수 있고, 값이 정수로 암시 변환되어 의미 없는 산술·비교가 허용된다. 영향: 전역 이름 오염으로 Red 같은 흔한 이름이 충돌하고, enum 값이 정수처럼 다뤄져 서로 다른 열거형이 뒤섞이거나 잘못된 비교가 컴파일을 통과한다. 대응: enum class 로 선언해 열거자를 enum 범위 안에 가두고 암시적 정수 변환을 막아 타입 안전성을 확보한다.Rationale: an unscoped enum leaks its enumerator names into the enclosing scope where they can collide with other names, and its values implicitly convert to integers, allowing meaningless arithmetic and comparison. Impact: global name pollution makes common names like Red collide, and treating enum values as integers lets different enums mix or wrong comparisons compile. Fix: declare it as an enum class to confine enumerators to the enum scope and block implicit integer conversion, securing type safety.
A7-5-2Required · Automated✓ compilable
함수는 직접/간접 재귀를 사용하지 않는다Functions shall not call themselves, either directly or indirectly
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdint>
static std::uint64_t fib(int n) { // 직접 재귀 — 최대 스택 깊이를 정적으로 보장 못함
return (n < 2) ? n : fib(n-1) + fib(n-2);
}
int main() { std::cout << fib(20) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
#include <cstdint>
static std::uint64_t fib(int n) { // 반복 — 상수 스택, 선형 시간
std::uint64_t a = 0, b = 1;
for (int i = 0; i < n; ++i) { std::uint64_t t = a + b; a = b; b = t; }
return a;
}
int main() { std::cout << fib(20) << '\n'; }⚠️ 근거: 재귀 함수는 호출 깊이가 입력에 따라 달라져, 최악의 경우 스택 사용량을 컴파일 타임에 정적으로 한정하기 어렵다. 영향: 안전필수·임베디드 시스템에서는 깊은(또는 무한) 재귀가 스택 오버플로우를 일으켜 인접 메모리를 침범하거나 시스템을 정지시키는데, 이는 사전 검증으로 막아야 할 결함이다. 대응: 재귀를 반복(루프)과 명시적 자료구조(스택·큐)로 변환해 메모리 사용량을 정적으로 한정 가능하게 만든다.Rationale: a recursive function has a call depth that varies with input, making it hard to statically bound the worst-case stack usage at compile time. Impact: in safety-critical and embedded systems, deep (or infinite) recursion causes a stack overflow that invades adjacent memory or halts the system — a defect that must be prevented by up-front verification. Fix: convert recursion into iteration (loops) with an explicit data structure (stack or queue) so memory usage can be statically bounded.
A7-6-1Required · Automated✓ compilable
[[noreturn]] 함수는 반환하지 않아야 한다Functions declared with the [[noreturn]] attribute shall not return
❌ 위반 예시Non-compliant example
#include <cstdlib>
[[noreturn]] void fail(bool recoverable) {
if (recoverable) return; // [[noreturn]] 인데 일부 경로에서 반환 — 미정의 동작
std::abort();
}
int main() { (void)&fail; } // 실행 회피(반환 경로 미트리거). 패턴 자체가 결함✅ 준수 예시Compliant example
#include <cstdlib>
#include <stdexcept>
[[noreturn]] void fail(bool recoverable) {
if (recoverable) throw std::runtime_error("recoverable handled elsewhere");
std::abort(); // 모든 경로가 throw 또는 종료 — 절대 반환 안 함
}
int main() { (void)&fail; }⚠️ 근거: [[noreturn]] 속성은 그 함수가 호출자에게 결코 제어를 돌려주지 않는다고 컴파일러·호출자에게 약속하며, 컴파일러는 이를 믿고 호출 지점 뒤를 도달 불가로 간주해 최적화한다. 영향: 실제로 그 함수가 반환하면 약속이 깨져 미정의 동작이 되고, 호출 뒤가 없다고 가정해 제거·재배치된 코드 때문에 예측 불가능한 흐름·손상이 발생한다. 대응: [[noreturn]] 함수가 모든 경로에서 throw 하거나 abort/exit/무한 루프로 끝나도록 보장해 절대 반환하지 않게 한다.Rationale: the [[noreturn]] attribute promises the compiler and callers that the function never returns control, and the compiler relies on this to treat code after the call site as unreachable and optimize accordingly. Impact: if the function actually returns, the promise is broken — undefined behaviour — and code removed or rearranged on the assumption that nothing follows the call leads to unpredictable flow and corruption. Fix: ensure a [[noreturn]] function ends on every path by throwing or via abort/exit/an infinite loop so it never returns.
A7-1-2Required · Automated✓ compilable📄 공식 예제Official example
The constexpr specifier shall be used for values that can be determined at compile time.The constexpr specifier shall be used for values that can be determined at compile time.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <algorithm>
//% $Id: A7-1-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
std::int32_t Pow1(std::int32_t number)
{
return (number * number);
}
constexpr std::int32_t Pow2(
std::int32_t number) // Possible compile-time computing
// because of constexpr specifier
{
return (number * number);
}
void Fn()
{
constexpr std::int16_t i1 = 20; // Compliant, evaluated at compile-time
const std::int16_t i2 = 20; // Non-compliant, possible run-time evaluation
std::int32_t twoSquare =
Pow1(2); // Non-compliant, possible run-time evaluation
const std::int32_t threeSquare =
Pow1(3); // Non-compliant, possible run-time evaluation
// static_assert(threeSquare == 9, "pow1(3) did not succeed."); // Value
// can not be static_assert-ed
constexpr std::int32_t fiveSquare =
Pow2(5); // Compliant, evaluated at compile time
static_assert(fiveSquare == 25,
"pow2(5) did not succeed."); // Compliant, constexpr
// evaluated at compile time
// constexpr std::int32_t int32Max =
// std::numeric_limits<std::int32_t>::max() + 1; //
// Compliant - compilation error due to
// compile-time evaluation (integer overflow)
}
class A
{
public:
static constexpr double pi = 3.14159265; // Compliant - value of PI can be
// determined in compile time
// constexpr double e = 2.71828182; // Non-compliant - constexprs need
// to be static members, compilation error
constexpr A() = default; // Compliant
};⚠️ The constexpr specifier declares that it is possible to evaluate the value of the function
or variable at compile time, e.g. integral type overflow/underflow, configuration options
or some physical constants. The compile-time evaluation can have no side effects so
it is more reliable than const expressions.
Note that the constexpr specifier in an object declaration implies const, and when used
in a function declaration it implies inline.
Note also that since 2014 C++ Language Standard constexpr specifier in member
function declaration no longer implicitly implies that the member function is const.
See also:
• C++ Core Guidelines [11]: Con.5: Use constexpr for values that can be computed
at compile time.The constexpr specifier declares that it is possible to evaluate the value of the function
or variable at compile time, e.g. integral type overflow/underflow, configuration options
or some physical constants. The compile-time evaluation can have no side effects so
it is more reliable than const expressions.
Note that the constexpr specifier in an object declaration implies const, and when used
in a function declaration it implies inline.
Note also that since 2014 C++ Language Standard constexpr specifier in member
function declaration no longer implicitly implies that the member function is const.
See also:
• C++ Core Guidelines [11]: Con.5: Use constexpr for values that can be computed
at compile time.
A7-1-3Required · Automated✓ compilable📄 공식 예제Official example
CV-qualifiers shall be placed on the right hand side of the type that is a typedef or a using name.CV-qualifiers shall be placed on the right hand side of the type that is a typedef or a using name.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A7-1-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #include <cstdint> using IntPtr = std::int32_t *; using IntConstPtr = std::int32_t * const; using ConstIntPtr = const std::int32_t *; void Fn(const std::uint8_t& input) // Compliant { std::int32_t value1 = 10; std::int32_t value2 = 20; const IntPtr ptr1 = &value1; // Non-compliant - deduced type is std::int32_t * // const, not const std::int32_t * // ptr1 = &value2; // Compilation error, ptr1 is read-only variable IntPtr const ptr2 = &value1; // Compliant - deduced type is std::int32_t * const // ptr2 = &value2; // Compilation error, ptr2 is read-only variable IntConstPtr ptr3 = &value1; // Compliant - type is std::int32_t * const, no // additional qualifiers needed // ptr3 = &value2; // Compilation error, ptr3 is read-only variable ConstIntPtr ptr4 = &value1; // Compliant - type is const std::int32_t * const ConstIntPtr ptr5 = &value1; // Non-compliant, type is const // std::int32_t * const, not const const // std::int32_t * ConstIntPtr const ptr6 = &value1; // Compliant - type is const std::int32_t * const }
⚠️ If the type is a typedef or a using name, placing const or volatile qualifier on the left
hand side may result in confusion over what part of the type the qualification applies
to.
See also:
• HIC++ v4.0 [9]: 7.1.4 Place CV-qualifiers on the right hand side of the type they
apply toIf the type is a typedef or a using name, placing const or volatile qualifier on the left
hand side may result in confusion over what part of the type the qualification applies
to.
See also:
• HIC++ v4.0 [9]: 7.1.4 Place CV-qualifiers on the right hand side of the type they
apply to
A7-1-4Required · Automated✓ compilable📄 공식 예제Official example
The register keyword shall not be used.The register keyword shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A7-1-4.cpp 289448 2017-10-04 11:11:03Z michal.szczepankiewicz $ #include <cstdint> std::int32_t F1(register std::int16_t number) noexcept // Non-compliant { return ((number * number) + number); } void F2(std::int16_t number) noexcept // Compliant { register std::int8_t x = 10; // Non-compliant std::int32_t result = F1(number); // Compliant // ... }
⚠️ This feature was deprecated in the 2011 C++ Language Standard [2] and may be
withdrawn in a later version.
Moreover, most compilers ignore register specifier and perform their own register
assignments.
See also:
• JSF December 2005 [8]: AV Rule 140 The register storage class specifier shall
not be used.
• HIC++ v4.0 [9]: 1.3.2 Do not use the register keywordThis feature was deprecated in the 2011 C++ Language Standard [2] and may be
withdrawn in a later version.
Moreover, most compilers ignore register specifier and perform their own register
assignments.
See also:
• JSF December 2005 [8]: AV Rule 140 The register storage class specifier shall
not be used.
• HIC++ v4.0 [9]: 1.3.2 Do not use the register keyword
A7-1-5Required · Automated✓ compilable📄 공식 예제Official example
The auto specifier shall not be used apart from following cases: (1) to declare that a variable has the same type as return type of a function call, (2) to declare that a variable has the same type as initializer of non-fundamental type, (3) to declare parameters of a generic lambda expression, (4) to declare a function template using trailing return type syntax.The auto specifier shall not be used apart from following cases: (1) to declare that a variable has the same type as return type of a function call, (2) to declare that a variable has the same type as initializer of non-fundamental type, (3) to declare parameters of a generic lambda expression, (4) to declare a function template using trailing return type syntax.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef>
// $Id: A7-1-5.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <vector>
class A
{
};
void F1() noexcept
{
auto x1 = 5; // Non-compliant - initializer is of fundamental type
auto x2 = 0.3F; // Non-compliant - initializer is of fundamental type
auto x3 = {8}; // Non-compliant - initializer is of fundamental type
std::vector<std::int32_t> v;
auto x4 = v.size(); // Compliant with case (1) - x4 is of size_t type that
// is returned from v.size() method
auto a = A{}; // Compliant with case (2)
auto lambda1 = []() -> std::uint16_t {
return 5U;
}; // Compliant with case (2) - lambda1 is of non-fundamental lambda
// expression type
auto x5 = lambda1(); // Compliant with case (1) - x5 is of
// std::uint16_t type
}
void F2() noexcept
{
auto lambda1 = [](auto x, auto y) -> decltype(x + y) {
return (x + y);
}; // Compliant with cases (2) and (3)
auto y1 = lambda1(5.0, 10); // Compliant with case (1)
}
template <typename T, typename U>
auto F3(T t, U u) noexcept -> decltype(t + u) // Compliant with case (4)
{
return (t + u);
}
template <typename T>
class B
{
public:
T Fn(T t);
};
template <typename T>
auto B<T>::Fn(T t) -> T // Compliant with case (4)
{
// ...
return t;
}⚠️ Using the auto specifier may lead to unexpected type deduction results, and therefore
to developers confusion. In most cases using the auto specifier makes the code less
readable.
Note that it is allowed to use the auto specifier in following cases:
1. When declaring a variable that is initialized with a function call or initializer of
non-fundamental type. Using the auto specifier for implicit type deduction in such
cases will ensure that no unexpected implicit conversions will occur. In such case,
explicit type declaration would not aid readability of the code.
2. When declaring a generic lambda expression with auto parameters
3. When declaring a function template using trailing return type syntax
See also:
• HIC++ v4.0 [9]: 7.1.8 Use auto id = expr when declaring a variable to have the
same type as its initializer function call.
• C++ Core Guidelines [11]: Use auto.
• Google C++ Style Guide [12]: Use auto to avoid type names that are noisy ,
obvious, or unimportant.Using the auto specifier may lead to unexpected type deduction results, and therefore
to developers confusion. In most cases using the auto specifier makes the code less
readable.
Note that it is allowed to use the auto specifier in following cases:
1. When declaring a variable that is initialized with a function call or initializer of
non-fundamental type. Using the auto specifier for implicit type deduction in such
cases will ensure that no unexpected implicit conversions will occur. In such case,
explicit type declaration would not aid readability of the code.
2. When declaring a generic lambda expression with auto parameters
3. When declaring a function template using trailing return type syntax
See also:
• HIC++ v4.0 [9]: 7.1.8 Use auto id = expr when declaring a variable to have the
same type as its initializer function call.
• C++ Core Guidelines [11]: Use auto.
• Google C++ Style Guide [12]: Use auto to avoid type names that are noisy ,
obvious, or unimportant.
A7-1-8Required · Automated✓ compilable📄 공식 예제Official example
A non-type specifier shall be placed before a type specifier in a declaration.A non-type specifier shall be placed before a type specifier in a declaration.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A7-1-8.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #include <cstdint> typedef std::int32_t int1; // Compliant std::int32_t typedef int2; // Non-compliant class C { public: virtual inline void F1(); // Compliant inline virtual void F2(); // Compliant void virtual inline F3(); // Non-compliant private: std::int32_t mutable x; // Non-compliant mutable std::int32_t y; // Compliant };
⚠️ Placing a non-type specifier, i.e. typedef, friend, constexpr, register, static, extern,
thread_local, mutable, inline, virtual, explicit, before type specifiers makes the source
code more readable.
See also:
• HIC++ v4.0 [9]: 7.1.3 Do not place type specifiers before non-type specifiers in a
declaration.Placing a non-type specifier, i.e. typedef, friend, constexpr, register, static, extern,
thread_local, mutable, inline, virtual, explicit, before type specifiers makes the source
code more readable.
See also:
• HIC++ v4.0 [9]: 7.1.3 Do not place type specifiers before non-type specifiers in a
declaration.
A7-1-9Required · Automated✓ compilable📄 공식 예제Official example
A class, structure, or enumeration shall not be declared in the definition of its type.A class, structure, or enumeration shall not be declared in the definition of its type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A7-1-9.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
#include <cstdint>
enum class DIRECTION
{
UP,
DOWN
} dir; //non-compliant
class Foo
{
public:
enum class ONE {AA, BB}; //compliant
static constexpr enum class TWO {CC, DD} sVar = TWO::CC; // non-compliant
static constexpr ONE sVar2 = ONE::AA; //compliant
};
struct Bar
{
std::uint32_t a;
} barObj; //non-compliant
struct Bar2
{
std::uint32_t a;
} bar2Obj, *bar2Ptr; //non-compliant, also with A7-1-7
struct Foo2
{
std::uint32_t f;
};
Foo2 foo2Obj; //compliant⚠️ Combining a type definition with a declaration of another entity can lead to readability
problems and can be confusing for a developer.
See also:
• JSF December 2005 [8]: AV Rule 141: A class, structure, or enumeration will not
be declared in the definition of its type.
• C++ Core Guidelines [11]: C.7: Don’t define a class or enum and declare a
variable of its type in the same statement.
6.7.2 Enumeration declarationCombining a type definition with a declaration of another entity can lead to readability
problems and can be confusing for a developer.
See also:
• JSF December 2005 [8]: AV Rule 141: A class, structure, or enumeration will not
be declared in the definition of its type.
• C++ Core Guidelines [11]: C.7: Don’t define a class or enum and declare a
variable of its type in the same statement.
6.7.2 Enumeration declaration
A7-2-1Required · Automated✓ compilable📄 공식 예제Official example
An expression with enum underlying type shall only have values corresponding to the enumerators of the enumeration.An expression with enum underlying type shall only have values corresponding to the enumerators of the enumeration.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A7-2-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
enum class E : std::uint8_t
{
Ok = 0,
Repeat,
Error
};
E Convert1(std::uint8_t number) noexcept
{
E result = E::Ok; // Compliant
switch (number)
{
case 0:
{
result = E::Ok; // Compliant
break;
}
case 1:
{
result = E::Repeat; // Compliant
break;
}
case 2:
{
result = E::Error; // Compliant
break;
}
case 3:
{
constexpr std::int8_t val = 3;
result = static_cast<E>(val); // Non-compliant - value 3 does not
// correspond to any of E's
// enumerators
break;
}
default:
{
result =
static_cast<E>(0); // Compliant - value 0 corresponds to E::Ok
break;
}
}
return result;
}
E Convert2(std::uint8_t userInput) noexcept
{
E result = static_cast<E>(userInput); // Non-compliant - the range of
// userInput may not correspond to
// any of E's enumerators
return result;
}
E Convert3(std::uint8_t userInput) noexcept
{
E result = E::Error;
if (userInput < 3)
{
result = static_cast<E>(userInput); // Compliant - the range of
// userInput checked before casting
// it to E enumerator
}
return result;
}⚠️ It is unspecified behavior if the evaluation of an expression with enum underlying type
yields a value which does not correspond to one of the enumerators of the enumeration.
Additionally , other rules in this standard assume that objects of enum type only contain
values corresponding to the enumerators. This rule ensures the validity of these
assumptions.
One way of ensuring compliance when converting to an enumeration is to use a switch
statement.
See also:
• MISRA C++ 2008 [7]: Rule 7-2-1 An expression with enum underlying type shall
only have values corresponding to the enumerators of the enumeration.It is unspecified behavior if the evaluation of an expression with enum underlying type
yields a value which does not correspond to one of the enumerators of the enumeration.
Additionally , other rules in this standard assume that objects of enum type only contain
values corresponding to the enumerators. This rule ensures the validity of these
assumptions.
One way of ensuring compliance when converting to an enumeration is to use a switch
statement.
See also:
• MISRA C++ 2008 [7]: Rule 7-2-1 An expression with enum underlying type shall
only have values corresponding to the enumerators of the enumeration.
A7-2-4Required · Automated✓ compilable📄 공식 예제Official example
In an enumeration, either (1) none, (2) the first or (3) all enumerators shall be initialized.In an enumeration, either (1) none, (2) the first or (3) all enumerators shall be initialized.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A7-2-4.cpp 271715 2017-03-23 10:13:51Z piotr.tanski $
#include <cstdint>
enum class Enum1 : std::uint32_t
{
One,
Two = 2, // Non-compliant
Three
};
enum class Enum2 : std::uint32_t // Compliant (none)
{
One,
Two,
Three
};
enum class Enum3 : std::uint32_t // Compliant (the first)
{
One = 1,
Two,
Three
};
enum class Enum4 : std::uint32_t // Compliant (all)
{
One = 1,
Two = 2,
Three = 3
};⚠️ Explicit initialization of only some enumerators in an enumeration, and relying on
compiler to initialize the remaining ones, may lead to developer‘s confusion.
See also:
• MISRA C++ 2008 [7]: Rule 8-5-3 In an enumerator list, the = construct shall not
be used to explicitly initialize members other than the first, unless all items are
explicitly initialized.
• HIC++ v4.0 [9]: 7.2.2 Initialize none, the first only or all enumerators in an
enumeration.Explicit initialization of only some enumerators in an enumeration, and relying on
compiler to initialize the remaining ones, may lead to developer‘s confusion.
See also:
• MISRA C++ 2008 [7]: Rule 8-5-3 In an enumerator list, the = construct shall not
be used to explicitly initialize members other than the first, unless all items are
explicitly initialized.
• HIC++ v4.0 [9]: 7.2.2 Initialize none, the first only or all enumerators in an
enumeration.
A7-2-5Advisory · Non-automated✓ compilable📄 공식 예제Official example
Enumerations should be used to represent sets of related named constants.Enumerations should be used to represent sets of related named constants.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A7-2-5.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $ #include <cstdint> //compliant enum class WebpageColors: std::uint32_t { Red, Blue, Green }; //non-compliant enum class Misc: std::uint32_t { Yellow, Monday, Holiday };
⚠️ Explicit declaration of constants as an enumeration clearly shows that they are related,
which enhances readability and maintenance.
Note: Using switch statement on an enumeration is a common case and such an
approach helps to detect errors, see M6-4-6.
See also:
• JSF December 2005 [8]: AV Rule 148: Enumeration types shall be used instead
of integer types (and constants) to select from a limited series of choices.
• C++ Core Guidelines [11]: Enum.2: Use enumerations to represent sets of
related named constants.
6.7.3 NamespacesExplicit declaration of constants as an enumeration clearly shows that they are related,
which enhances readability and maintenance.
Note: Using switch statement on an enumeration is a common case and such an
approach helps to detect errors, see M6-4-6.
See also:
• JSF December 2005 [8]: AV Rule 148: Enumeration types shall be used instead
of integer types (and constants) to select from a limited series of choices.
• C++ Core Guidelines [11]: Enum.2: Use enumerations to represent sets of
related named constants.
6.7.3 Namespaces
A7-3-1Required · Automated✓ compilable📄 공식 예제Official example
All overloads of a function shall be visible from where it is called.All overloads of a function shall be visible from where it is called.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A7-3-1.cpp 312801 2018-03-21 16:17:05Z michal.szczepankiewicz $
#include <cstdint>
class Base
{
public:
void P(uint32_t);
virtual void V(uint32_t);
virtual void V(double);
};
class NonCompliant : public Base
{
public:
//hides P(uint32_t) when calling from the
//derived class
void P(double);
//hides V(uint32_t) when calling from the
//derived class
void V(double) override;
};
class Compliant : public Base
{
public:
//both P(uint32_t) and P(double) available
//from the derived class
using Base::P;
void P(double);
//both P(uint32_t) and P(double)
using Base::V;
void V(double) override;
};
void F1()
{
NonCompliant d{};
d.P(0U); // D::P (double) called
Base& b{d};
b.P(0U); // NonCompliant::P (uint32_t) called
d.V(0U); // D::V (double) called
b.V(0U); // NonCompliant::V (uint32_t) called
}
void F2()
{
Compliant d{};
d.P(0U); // Compliant::P (uint32_t) called
Base& b{d};
b.P(0U); // Compliant::P (uint32_t) called
d.V(0U); // Compliant::V (uint32_t) called
b.V(0U); // Compliant::V (uint32_t) called
}
namespace NS
{
void F(uint16_t);
}
//includes only preceding declarations into
//the current scope
using NS::F;
namespace NS
{
void F(uint32_t);
}
void B(uint32_t b)
{
//non-compliant, only F(uint16_t) is available
//in this scope
F(b);
}⚠️ Additional identifiers introduced by a using declaration makes only prior declarations
of this identifier visible. Any potential subsequent declarations will not be added to the
current scope, which may lead to unexpected results and developers confusion.
Overriding or overloading a member function in a derived class causes other member
functions with the same name to be hidden. Thus, a potential function call may result
in a different function being called depending on if the call was made using the derived
or base class reference/pointer. Introducing hidden names into the derived class by a
using declaration helps to avoid such misleading situations.
See also:
• MISRA C++ 2008 [7]: 7-3-5: Multiple declarations for an identifier in the same
namespace shall not straddle a using-declaration for that identifier.
• HIC++ v4.0 [9]: 13.1.1: Ensure that all overloads of a function are visible from
where it is called.Additional identifiers introduced by a using declaration makes only prior declarations
of this identifier visible. Any potential subsequent declarations will not be added to the
current scope, which may lead to unexpected results and developers confusion.
Overriding or overloading a member function in a derived class causes other member
functions with the same name to be hidden. Thus, a potential function call may result
in a different function being called depending on if the call was made using the derived
or base class reference/pointer. Introducing hidden names into the derived class by a
using declaration helps to avoid such misleading situations.
See also:
• MISRA C++ 2008 [7]: 7-3-5: Multiple declarations for an identifier in the same
namespace shall not straddle a using-declaration for that identifier.
• HIC++ v4.0 [9]: 13.1.1: Ensure that all overloads of a function are visible from
where it is called.
A7-4-1Required · Automated✓ compilable📄 공식 예제Official example
The asm declaration shall not be used.The asm declaration shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A7-4-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
std::int32_t Fn1(std::int32_t b) noexcept
{
std::int32_t ret = 0;
// ...
asm("pushq %%rax \n"
"movl %0, %%eax \n"
"addl %1, %%eax \n"
"movl %%eax, %0 \n"
"popq %%rax"
: "=r"(ret)
: "r"(b)); // Non-compliant
return ret;
}
std::int32_t Fn2(std::int32_t b) noexcept
{
std::int32_t ret = 0;
// ...
ret += b; // Compliant - equivalent to asm(...) above
return ret;
}⚠️ Inline assembly code restricts the portability of the code.
See also:
• HIC++ v4.0 [9]: 7.5.1 Do not use the asm declaration.Inline assembly code restricts the portability of the code.
See also:
• HIC++ v4.0 [9]: 7.5.1 Do not use the asm declaration.
A7-5-1Required · Automated✓ compilable📄 공식 예제Official example
A function shall not return a reference or a pointer to a parameter that is passed by reference to const.A function shall not return a reference or a pointer to a parameter that is passed by reference to const.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A7-5-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
class A
{
public:
explicit A(std::uint8_t n) : number(n) {}
~A() { number = 0U; }
// Implementation
private:
std::uint8_t number;
};
const A& Fn1(const A& ref) noexcept // Non-compliant - the function returns a
// reference to const reference parameter
// which may bind to temporary objects.
// According to C++14 Language Standard, it
// is undefined whether a temporary object is introduced for const
// reference
// parameter
{
// ...
return ref;
}
const A& Fn2(A& ref) noexcept // Compliant - non-const reference parameter does
// not bind to temporary objects, it is allowed
// that the function returns a reference to such
// a parameter
{
// ...
return ref;
}
const A * Fn3(const A& ref) noexcept // Non-compliant - the function returns a
// pointer to const reference parameter
// which may bind to temporary objects.
// According to C++14 Language Standard, it
// is undefined whether a temporary object is introduced for const
// reference
// parameter
{
// ...
return &ref;
}
template <typename T>
T& Fn4(T& v) // Compliant - the function will not bind to temporary objects
{
// ...
return v;
}
void F() noexcept
{
A a{5};
const A& ref1 = Fn1(a); // fn1 called with an lvalue parameter from an
// outer scope, ref1 refers to valid object
const A& ref2 = Fn2(a); // fn2 called with an lvalue parameter from an
// outer scope, ref2 refers to valid object
const A * ptr1 = Fn3(a); // fn3 called with an lvalue parameter from an
// outer scope, ptr1 refers to valid object
const A& ref3 = Fn4(a); // fn4 called with T = A, an lvalue parameter from
// an outer scope, ref3 refers to valid object
const A& ref4 = Fn1(A{10}); // fn1 called with an rvalue parameter
// (temporary), ref3 refers to destroyed object
// A const& ref5 = fn2(A{10}); // Compilation
// error - invalid initialization of non-const
// reference
const A * ptr2 = Fn3(A{15}); // fn3 called with an rvalue parameter
// (temporary), ptr2 refers to destroyted
// object
// const A& ref6 = fn4(A{20}); // Compilation error - invalid
// initialization of non-const reference
}⚠️ “[...] Where a parameter is of const reference type a temporary object is introduced if
needed (7.1.6, 2.13, 2.13.5, 8.3.4, 12.2). ” [C++14 Language Standard [3]]
Any attempt to dereferencing an object which outlived its scope will lead to undefined
behavior.
References to const bind to both lvalues and rvalues, so functions that accept
parameters passed by reference to const should expect temporary objects too.
Returning a pointer or a reference to such an object leads to undefined behavior on
accessing it.
See also:
• MISRA C++ 2008 [7]: A function shall not return a reference or a pointer to a
parameter that is passed by reference or const reference.“[...] Where a parameter is of const reference type a temporary object is introduced if
needed (7.1.6, 2.13, 2.13.5, 8.3.4, 12.2). ” [C++14 Language Standard [3]]
Any attempt to dereferencing an object which outlived its scope will lead to undefined
behavior.
References to const bind to both lvalues and rvalues, so functions that accept
parameters passed by reference to const should expect temporary objects too.
Returning a pointer or a reference to such an object leads to undefined behavior on
accessing it.
See also:
• MISRA C++ 2008 [7]: A function shall not return a reference or a pointer to a
parameter that is passed by reference or const reference.
A8A8 (AUTOSAR)A8 (AUTOSAR-original)
A8-4-1Required · Automated✓ compilable
함수를 C 스타일 가변인자(...)로 정의하지 않는다Functions shall not be defined using the ellipsis notation
❌ 위반 예시Non-compliant example
#include <cstdarg>
#include <iostream>
static long total(int count, ...) { // 타입 검사 없는 C 가변인자
va_list ap; va_start(ap, count);
long s = 0;
for (int i = 0; i < count; ++i) s += va_arg(ap, int); // double 을 넘기면 미정의
va_end(ap);
return s;
}
int main() { std::cout << total(2, 10, 3.5) << '\n'; } // 두 번째 인자 타입 불일치✅ 준수 예시Compliant example
#include <iostream>
template <typename... Args> // 가변 템플릿 — 타입·개수가 컴파일 타임에 검증됨
static auto total(Args... args) { return (args + ... + 0); }
int main() { std::cout << total(10, 3.5) << '\n'; }⚠️ 근거: ... 가변인자는 전달된 인자의 타입·개수 정보가 컴파일러에 남지 않아, va_arg 가 지정한 타입과 실제 인자가 다르면 검사 없이 잘못된 비트를 읽는다. 영향: 호출자가 형식과 다른 타입을 넘기면 쓰레기 값·크래시·정보 유출이 발생하고, 인자 개수 불일치도 진단되지 않는다. 대응: 가변 템플릿(fold expression)이나 std::initializer_list 로 대체해 타입과 개수를 컴파일 타임에 검증되게 한다.Rationale: ellipsis varargs keep no type or count information about the passed arguments, so va_arg reads wrong bits unchecked when the requested type differs from the actual argument. Impact: passing a type different from the format yields garbage, crashes, or information disclosure, and an argument-count mismatch goes undiagnosed. Fix: replace with variadic templates (fold expressions) or std::initializer_list so types and counts are checked at compile time.
A8-4-7Required · Automated✓ compilable
작고 trivially copyable 한 입력 매개변수는 값으로 전달한다Small trivially copyable input parameters shall be passed by value
❌ 위반 예시Non-compliant example
#include <iostream>
static int scale(const int& x, const int& f) { // 작은 타입에 const 참조 — 불필요한 간접화
return x * f;
}
int main() { std::cout << scale(6, 7) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
static int scale(int x, int f) { // 값 전달 — 직접 접근, 별칭 가능성 없음
return x * f;
}
int main() { std::cout << scale(6, 7) << '\n'; }⚠️ 근거: int 처럼 작고 trivially copyable 한 타입은 복사 비용이 레지스터 한 개 수준이라, 참조로 받으면 오히려 포인터 한 단계 간접 접근과 잠재적 별칭(aliasing) 가능성만 더해진다. 영향: 불필요한 const 참조는 컴파일러가 값이 다른 경로로 바뀌지 않는다고 가정하지 못하게 해 최적화를 방해하고, 인터페이스 의도를 모호하게 한다. 대응: 작고 복사 비용이 낮은 입력 매개변수는 값으로 전달하고, 크거나 복사가 비싼 타입만 const 참조로 받는다.Rationale: a small trivially copyable type like int costs about one register to copy, so passing it by reference instead adds a level of pointer indirection and potential aliasing. Impact: an unnecessary const reference prevents the compiler from assuming the value is not changed through another path, hindering optimization and obscuring interface intent. Fix: pass small, cheap-to-copy input parameters by value, reserving const reference for large or expensive-to-copy types.
A8-5-2Required · Automated✓ compilable
초기화에는 중괄호 초기화(braced-init)를 사용한다Braced-initialization shall be used for variable initialization
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int x = 3.9; // double→int 좁히기 변환이 조용히 일어남 → 3, 소수부 소실
std::cout << x << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int x{3}; // 중괄호 초기화 — 좁히기 변환을 컴파일 오류로 차단(int x{3.9}; 는 에러)
std::cout << x << '\n';
}⚠️ 근거: 중괄호 초기화 {} 는 좁히기 변환(narrowing, 예: double→int, 넓은 정수→좁은 정수)을 컴파일 오류로 금지하는 반면, = 나 () 초기화는 이를 조용히 허용한다. 영향: int x = 3.9; 가 경고 없이 3 이 되는 것처럼 데이터 손실이 진단 없이 통과해, 정밀도·범위가 중요한 계산에서 결함이 된다. 대응: 변수 초기화에 일관되게 {} 를 사용해 좁히기 변환을 컴파일 타임에 잡아낸다.Rationale: braced-initialization {} forbids narrowing conversions (e.g. double to int, wide to narrow integer) as a compile error, whereas = or () initialization allows them silently. Impact: data loss passes with no diagnostic — like int x = 3.9; becoming 3 without a warning — a defect in computations where precision or range matters. Fix: use {} consistently for variable initialization to catch narrowing conversions at compile time.
A8-2-1Required · Automated✓ compilable📄 공식 예제Official example
When declaring function templates, the trailing return type syntax shall be used if the return type depends on the type of parameters. --- PAGE 153 ---When declaring function templates, the trailing return type syntax shall be used if the return type depends on the type of parameters. --- PAGE 153 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-2-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
template <typename T>
class A
{
public:
using Type = std::int32_t;
Type F(T const&) noexcept;
Type G(T const&) noexcept;
};
template <typename T>
typename A<T>::Type A<T>::F(T const&) noexcept // Non-compliant
{
// Implementation
}
template <typename T>
auto A<T>::G(T const&) noexcept -> Type // Compliant
{
// Implementation
}⚠️ Use of trailing return type syntax avoids a fully qualified return type of a function along
with the typename keyword.
See also:
• HIC++ v4.0 [9]: 7.1.7 Use a trailing return type in preference to type
disambiguation using typename.
6.8.3 Meaning of declaratorsUse of trailing return type syntax avoids a fully qualified return type of a function along
with the typename keyword.
See also:
• HIC++ v4.0 [9]: 7.1.7 Use a trailing return type in preference to type
disambiguation using typename.
6.8.3 Meaning of declarators
A8-4-10Required · Automated✓ compilable📄 공식 예제Official example
A parameter shall be passed by reference if it can’t be NULLA parameter shall be passed by reference if it can’t be NULL
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-4-10.cpp 307966 2018-02-16 16:03:46Z christof.meerwald $ #include <cstdint> #include <numeric> #include <vector> // Non-Compliant: non-optional parameter passed by pointer int32_t Sum(const std::vector<int32_t> *v) { return std::accumulate(v->begin(), v->end(), 0); } // Compliant: non-optional parameter passed by reference int32_t Sum(const std::vector<int32_t> &v) { return std::accumulate(v.begin(), v.end(), 0); }
⚠️ Passing a parameter by pointer suggests that it can be NULL. If it can’t be NULL (i.e.
it’s not optional) it should therefore be passed by reference instead. Only parameters
that can be NULL shall be passed by pointer.
Note: The C++ Library Fundamentals TS v2 defines std::observer_ptr as a near
drop-in replacement for raw pointers that makes it explicit that the object is not owned
by the pointer.
Note: boost::optional supports reference types, and in C++17 std::optional
can be used in conjunction with std::reference_wrapper (using std::optional
with a value type would create an undesirable copy of the object)
See also:
• C++ Core Guidelines [11]: F .60: Prefer T* over T& when "no argument" is a valid
option
• JSF December 2005 [8]: AV Rule 118: Arguments should be passed via pointers
if NULL values are possible.
• JSF December 2005 [8]: AV Rule 118.1: An object should be passed as const T*
if its value should not be modified.
• JSF December 2005 [8]: AV Rule 118.2: An object should be passed as T* if its
value may be modified.Passing a parameter by pointer suggests that it can be NULL. If it can’t be NULL (i.e.
it’s not optional) it should therefore be passed by reference instead. Only parameters
that can be NULL shall be passed by pointer.
Note: The C++ Library Fundamentals TS v2 defines std::observer_ptr as a near
drop-in replacement for raw pointers that makes it explicit that the object is not owned
by the pointer.
Note: boost::optional supports reference types, and in C++17 std::optional
can be used in conjunction with std::reference_wrapper (using std::optional
with a value type would create an undesirable copy of the object)
See also:
• C++ Core Guidelines [11]: F .60: Prefer T* over T& when "no argument" is a valid
option
• JSF December 2005 [8]: AV Rule 118: Arguments should be passed via pointers
if NULL values are possible.
• JSF December 2005 [8]: AV Rule 118.1: An object should be passed as const T*
if its value should not be modified.
• JSF December 2005 [8]: AV Rule 118.2: An object should be passed as T* if its
value may be modified.
A8-4-11Required · Automated✓ compilable📄 공식 예제Official example
A smart pointer shall only be used as a parameter type if it expresses lifetime semanticsA smart pointer shall only be used as a parameter type if it expresses lifetime semantics
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-4-11.cpp 307966 2018-02-16 16:03:46Z christof.meerwald $
#include <cstdint>
#include <memory>
#include <numeric>
#include <vector>
class A
{
public:
void do_stuff();
};
// Non-Compliant: passing object as smart pointer
void foo(std::shared_ptr<A> a)
{
if (a)
{
a->do_stuff();
}
else
{
// ...
}
}
// Compliant: passing as raw pointer instead
void bar(A *a)
{
if (a != nullptr)
{
a->do_stuff();
}
else
{
// ...
}
}
class B
{
public:
void add_a(std::shared_ptr<A> a)
{
m_v.push_back(a);
}
private:
std::vector<std::shared_ptr<A>> m_v;
};
// Compliant: storing the shared pointer (affecting lifetime)
void bar(B &b, std::shared_ptr<A> a)
{
b.add_a(a);
}⚠️ If the object passed into the function is merely used without affecting the lifetime, it is
preferable to pass it by reference or raw pointer instead.
Keeping a copy of a std::shared_ptr or moving a std::unique_ptr would be
examples that affect the lifetime.
Note: When an object whose lifetime is managed by a non-local smart pointer is
passed by reference or raw pointer, care needs to be taken that the lifetime of
the object doesn’t end during the duration of the called function. In the case of a
std::shared_ptr this can be achieved by keeping a local copy of the shared_ptr.
Exception:
A non-owning smart pointer, like std::observer_ptr from the C++ Library
Fundamentals TS v2, that documents the non-owning property of the parameter does
not violate this rule.
See also:
• C++ Core Guidelines [11]: R.30: T ake smart pointers as parameters only to
explicitly express lifetime semantics.
• C++ Core Guidelines [11]: R.37: Do not pass a pointer or reference obtained
from an aliased smart pointer.
• C++ Core Guidelines [11]: F .7: For general use, take T* or T& arguments rather
than smart pointers.
• A18-5-2 in section 6.18.5If the object passed into the function is merely used without affecting the lifetime, it is
preferable to pass it by reference or raw pointer instead.
Keeping a copy of a std::shared_ptr or moving a std::unique_ptr would be
examples that affect the lifetime.
Note: When an object whose lifetime is managed by a non-local smart pointer is
passed by reference or raw pointer, care needs to be taken that the lifetime of
the object doesn’t end during the duration of the called function. In the case of a
std::shared_ptr this can be achieved by keeping a local copy of the shared_ptr.
Exception:
A non-owning smart pointer, like std::observer_ptr from the C++ Library
Fundamentals TS v2, that documents the non-owning property of the parameter does
not violate this rule.
See also:
• C++ Core Guidelines [11]: R.30: T ake smart pointers as parameters only to
explicitly express lifetime semantics.
• C++ Core Guidelines [11]: R.37: Do not pass a pointer or reference obtained
from an aliased smart pointer.
• C++ Core Guidelines [11]: F .7: For general use, take T* or T& arguments rather
than smart pointers.
• A18-5-2 in section 6.18.5
A8-4-12Required · Automated✓ compilable📄 공식 예제Official example
A std::unique_ptr shall be passed to a function as: (1) a copy to express the function assumes ownership (2) an lvalue reference to express that the function replaces the managed object.A std::unique_ptr shall be passed to a function as: (1) a copy to express the function assumes ownership (2) an lvalue reference to express that the function replaces the managed object.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility> #include <stdexcept> // $Id: A8-4-12.cpp 308795 2018-02-23 09:27:03Z michal.szczepankiewicz $ #include <memory> #include <iostream> //compliant, transfers an ownership void Value(std::unique_ptr<int> v) { } //compliant, replaces the managed object void Lv1(std::unique_ptr<int>& v) { v.reset(); } //non-compliant, does not replace the managed object void Lv2(std::unique_ptr<int>& v) {} //compliant by exception void Rv1(std::unique_ptr<int>&& r) { std::unique_ptr<int> v(std::move(r)); } //non-compliant void Rv2(std::unique_ptr<int>&& r) {} int main(void) { auto sp = std::make_unique<int>(7); Value(std::move(sp)); //sp is empty auto sp2 = std::make_unique<int>(9); Rv1(std::move(sp2)); //sp2 is empty, because it was moved from in Rv1 function auto sp3 = std::make_unique<int>(9); Rv2(std::move(sp3)); //sp3 is not empty, because it was not moved from in Rv1 function return 0; }
⚠️ Transferring ownership in the (1) case is unconditional. A temporary std::unique_ptr is
constructed implicitly and move-initialized from the caller’s std::unique_ptr and then
passed to the function. This guarantees that the caller’s std::unique_ptr object is
empty .
Passing an lvalue reference is suggested to be used if a called function is supposed
to replace the object managed by the passed std::unique_ptr, e.g. call assignment
operator or reset method. Otherwise, it is recommended to pass an lvalue reference
to the underlying object instead, see A8-4-11, A8-4-10.
Note: Passing a const lvalue reference to std::unique_ptr does not take ownership
and does not allow to replace the managed object. Also, the const qualifier does not
apply to the underlying object, but to the smart pointer itself. It is suggested to pass a
const lvalue reference to the underlying object instead, see A8-4-11, A8-4-10.
Exception:
It is allowed to transfer ownership by passing a std::unique_ptr by an rvalue reference
in case this reference is moved into a std::unique_ptr object inside the called function.
See also:
• HIC++ v4.0 [9]: 8.2.4: Do not pass std::unique_ptr by const reference.
• C++ Core Guidelines [11]: R.32: T ake a unique_ptr<widget> parameter to
express that a function assumes ownership of a widget.
• C++ Core Guidelines [11]: R.33: T ake a unique_ptr<widget>& parameter to
express that a function reseats the widget.
• C++ Core Guidelines [11]: I.11: Never transfer ownership by a raw pointer (T*) or
reference (T&).Transferring ownership in the (1) case is unconditional. A temporary std::unique_ptr is
constructed implicitly and move-initialized from the caller’s std::unique_ptr and then
passed to the function. This guarantees that the caller’s std::unique_ptr object is
empty .
Passing an lvalue reference is suggested to be used if a called function is supposed
to replace the object managed by the passed std::unique_ptr, e.g. call assignment
operator or reset method. Otherwise, it is recommended to pass an lvalue reference
to the underlying object instead, see A8-4-11, A8-4-10.
Note: Passing a const lvalue reference to std::unique_ptr does not take ownership
and does not allow to replace the managed object. Also, the const qualifier does not
apply to the underlying object, but to the smart pointer itself. It is suggested to pass a
const lvalue reference to the underlying object instead, see A8-4-11, A8-4-10.
Exception:
It is allowed to transfer ownership by passing a std::unique_ptr by an rvalue reference
in case this reference is moved into a std::unique_ptr object inside the called function.
See also:
• HIC++ v4.0 [9]: 8.2.4: Do not pass std::unique_ptr by const reference.
• C++ Core Guidelines [11]: R.32: T ake a unique_ptr<widget> parameter to
express that a function assumes ownership of a widget.
• C++ Core Guidelines [11]: R.33: T ake a unique_ptr<widget>& parameter to
express that a function reseats the widget.
• C++ Core Guidelines [11]: I.11: Never transfer ownership by a raw pointer (T*) or
reference (T&).
A8-4-13Required · Automated✓ compilable📄 공식 예제Official example
A std::shared_ptr shall be passed to a function as: (1) a copy to express the function shares ownership (2) an lvalue reference to express that the function replaces the managed object (3) a const lvalue reference to express that the function retains a reference count. --- PAGE 169 ---A std::shared_ptr shall be passed to a function as: (1) a copy to express the function shares ownership (2) an lvalue reference to express that the function replaces the managed object (3) a const lvalue reference to express that the function retains a reference count. --- PAGE 169 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-4-13.cpp 308795 2018-02-23 09:27:03Z michal.szczepankiewicz $ #include <memory> #include <iostream> //compliant, explicit ownership sharing void Value(std::shared_ptr<int> v) { } //compliant, replaces the managed object void Lv1(std::shared_ptr<int>& v) { v.reset(); } //non-compliant, does not replace the managed object //shall be passed by int& so that API that does not //extend lifetime of an object is not polluted //with smart pointers void Lv2(std::shared_ptr<int>& v) { ++(*v); } //compliant, shared_ptr copied in the called function void Clv1(const std::shared_ptr<int>& v) { Value(v); } //non-compliant, const lvalue reference not copied //to a shared_ptr object on any code path //shall be passed by const int& void Clv2(const std::shared_ptr<int>& v) { std::cout << *v << std::endl; } //non-compliant void Rv1(std::shared_ptr<int>&& r) {}
⚠️ Passing a std::shared_ptr by value (1) is clear and makes ownership sharing explicit.
Passing an lvalue reference (2) to std::shared_ptr is suggested to be used if a called
function replaces the managed object on at least one code path, e.g. call assignment
operator or reset method. Otherwise, it is recommended to pass an lvalue reference
to the underlying object instead, see A8-4-11, A8-4-10.
Functions that take a const lvalue reference (3) to std::shared_ptr as a parameter are
supposed to copy it to another std::shared_ptr on at least one code path, otherwise
the parameter should be passed by a const lvalue reference to the underlying object
instead, see A8-4-11, A8-4-10.
See also:
• C++ Core Guidelines [11]: R.34: T ake a shared_ptr<widget> parameter to
express that a function is part owner.
• C++ Core Guidelines [11]: R.35: T ake a shared_ptr<widget>& parameter to
express that a function might reseat the shared pointer.
• C++ Core Guidelines [11]: R.36: T ake a const shared_ptr<widget>& parameter
to express that it might retain a reference count to the object.Passing a std::shared_ptr by value (1) is clear and makes ownership sharing explicit.
Passing an lvalue reference (2) to std::shared_ptr is suggested to be used if a called
function replaces the managed object on at least one code path, e.g. call assignment
operator or reset method. Otherwise, it is recommended to pass an lvalue reference
to the underlying object instead, see A8-4-11, A8-4-10.
Functions that take a const lvalue reference (3) to std::shared_ptr as a parameter are
supposed to copy it to another std::shared_ptr on at least one code path, otherwise
the parameter should be passed by a const lvalue reference to the underlying object
instead, see A8-4-11, A8-4-10.
See also:
• C++ Core Guidelines [11]: R.34: T ake a shared_ptr<widget> parameter to
express that a function is part owner.
• C++ Core Guidelines [11]: R.35: T ake a shared_ptr<widget>& parameter to
express that a function might reseat the shared pointer.
• C++ Core Guidelines [11]: R.36: T ake a const shared_ptr<widget>& parameter
to express that it might retain a reference count to the object.
A8-4-14Required · Non-automated✓ compilable📄 공식 예제Official example
Interfaces shall be precisely and strongly typed.Interfaces shall be precisely and strongly typed.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-4-14.cpp 326058 2018-07-16 07:52:31Z christof.meerwald $ #include <cstdint> #include <chrono> // Non-compliant: unit of duration not obvious void Sleep(std::uint32_t duration); // Compliant: strongly typed void Sleep(std::chrono::seconds duration); // Non-compliant: list of related parameters with same type void SetAlarm(std::uint32_t year, std::uint32_t month, std::uint32_t day, std::uint32_t hour, std::uint32_t minute, std::uint32_t second); // Compliant: strongly typed void SetAlarm(std::chrono::system_clock::time_point const & when);
⚠️ Using precise and strong types in interfaces helps using them correctly .
A large number of parameters of fundamental type (particularly of arithmetic type) can
be an indication of bad interface design as it does not make it obvious what the units
are, and there is no way for the compiler to warn when parameters are passed in the
wrong order (as the types are the same or implicitly convertible).
When several parameters are related, combining the parameters into a separate user-
defined type should be considered.
Similarly , a type of pointer to void does not provide any type safety and alternatives
like a pointer to a common base class or using a (potentially constrained) template
parameter should be considered.
See also:
• C++ Core Guidelines [11]: I.4: Make interfaces precisely and strongly typed
6.8.5 InitializersUsing precise and strong types in interfaces helps using them correctly .
A large number of parameters of fundamental type (particularly of arithmetic type) can
be an indication of bad interface design as it does not make it obvious what the units
are, and there is no way for the compiler to warn when parameters are passed in the
wrong order (as the types are the same or implicitly convertible).
When several parameters are related, combining the parameters into a separate user-
defined type should be considered.
Similarly , a type of pointer to void does not provide any type safety and alternatives
like a pointer to a common base class or using a (potentially constrained) template
parameter should be considered.
See also:
• C++ Core Guidelines [11]: I.4: Make interfaces precisely and strongly typed
6.8.5 Initializers
A8-4-2Required · Automated✓ compilable📄 공식 예제Official example
All exit paths from a function with non-void return type shall have an explicit return statement with an expression.All exit paths from a function with non-void return type shall have an explicit return statement with an expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-4-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #include <cstdint> #include <stdexcept> std::int32_t F1() noexcept // Non-compliant { } std::int32_t F2(std::int32_t x) noexcept(false) { if (x > 100) { throw std::logic_error("Logic Error"); // Compliant by exception } return x; // Compliant } std::int32_t F3(std::int32_t x, std::int32_t y) { if (x > 100 || y > 100) { throw std::logic_error("Logic Error"); // Compliant by exception } if (y > x) { return (y - x); // Compliant } return (x - y); // Compliant }
⚠️ In a function with non-void return type, return expression gives the value that the
function returns. The absence of a return with an expression leads to undefined
behavior (and the compiler may not give an error).
Exception:
A function may additionally exit due to exception handling (i.e. a throw statement).
See also:
• MISRA C++ 2008 [7]: Rule 8-4-3 All exit paths from a function with non-void
return type shall have an explicit return statement with an expression.
• SEI CERT C++ [10]: MSC52-CPP . Value-returning functions must return a value
from all exit paths.In a function with non-void return type, return expression gives the value that the
function returns. The absence of a return with an expression leads to undefined
behavior (and the compiler may not give an error).
Exception:
A function may additionally exit due to exception handling (i.e. a throw statement).
See also:
• MISRA C++ 2008 [7]: Rule 8-4-3 All exit paths from a function with non-void
return type shall have an explicit return statement with an expression.
• SEI CERT C++ [10]: MSC52-CPP . Value-returning functions must return a value
from all exit paths.
A8-4-3Advisory · Non-automated✓ compilable📄 공식 예제Official example
Common ways of passing parameters should be used.Common ways of passing parameters should be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility> // $Id: A8-4-3.cpp 308906 2018-02-23 15:34:15Z christof.meerwald $ #include <algorithm> #include <array> #include <cstdint> #include <numeric> #include <string> #include <vector> // Compliant: passing cheap-to-copy parameter by value int32_t Increment(int32_t i) { return i + 1; } // Compliant: passing expensive to copy parameter by reference to const int32_t Sum(const std::vector<int32_t> &v) { return std::accumulate(v.begin(), v.end(), 0); } // Compliant: passing in-out parameter by reference void Decrement(int32_t &i) { --i; } // Compliant: returning out parameter by value std::string GetGreeting() { return "Hello"; } struct A { std::string text; std::array<std::string, 1000> arr; }; // Expensive to move "out" parameter passed by reference. If // intentional, violation of A8-4-8 needs to be explained void InitArray(std::array<std::string, 1000> &arr, const std::string &text) { std::for_each(arr.begin(), arr.end(), [&text] (std::string &s) { s = text; }); } // Compliant: passing in-out parameter by reference void PopulateA(A &a) { InitArray(a.arr, a.text); }
⚠️ Using common and well-understood parameter passing patterns as summarised in the
following table helps meeting developer expectations.
cheap to copy or move only cheap to move expensive to move
in f(X) f(const X &)
in/out f(X &)
out X f() f(X &)
consume f(X &&)
forward template<typename T> f(T &&)
Parameter passing
See also:
• C++ Core Guidelines [11]: F .16: Prefer simple and conventional ways of passing
informationUsing common and well-understood parameter passing patterns as summarised in the
following table helps meeting developer expectations.
cheap to copy or move only cheap to move expensive to move
in f(X) f(const X &)
in/out f(X &)
out X f() f(X &)
consume f(X &&)
forward template<typename T> f(T &&)
Parameter passing
See also:
• C++ Core Guidelines [11]: F .16: Prefer simple and conventional ways of passing
information
A8-4-4Advisory · Automated✓ compilable📄 공식 예제Official example
Multiple output values from a function should be returned as a struct or tuple.Multiple output values from a function should be returned as a struct or tuple.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-4-4.cpp 289816 2017-10-06 11:19:42Z michal.szczepankiewicz $ #include <tuple> // Non-compliant, remainder returned as the output parameter int Divide1(int dividend, int divisor, int& remainder) { remainder = dividend % divisor; return dividend / divisor; } // Compliant, both quotient and remainder returned as a tuple std::tuple<int, int> Divide2(int dividend, int divisor) { return std::make_tuple(dividend / divisor, dividend % divisor); } // Compliant since C++17, return tuple using list-initialization // std::tuple<int, int> Divide3(int dividend, int divisor) //{ // return { dividend / divisor, dividend % divisor }; //} int main() { int quotient, remainder; std::tie(quotient, remainder) = Divide2(26, 5); // store in local variables // auto [quotient, remainder] = Divide3(26, 5); // since C++17, by // structured bindings return 0; }
⚠️ Returning multiple values from a function using a struct or tuple clearly states output
parameters and allows to avoid confusion of passing them as a reference in a function
call. Returning a struct or tuple will not have an additional overhead for compilers that
support return-value-optimization.
In C++14, a returned tuple can be conveniently processed using std::tie at the call
site, which will put the tuple elements directly into existing local variables. In C++17,
structured bindings allow to initialize local variables directly from members or elements
of a returned struct or tuple.
Note: For return types representing an abstraction, a struct should be preferred over a
generic tuple.
Note: This rule applies equally to std::pair, which is a special kind of tuple for
exactly two elements.
See also:
• C++ Core Guidelines [11]: F .21: T o return multiple ”out” values, prefer returning
a tuple or struct.Returning multiple values from a function using a struct or tuple clearly states output
parameters and allows to avoid confusion of passing them as a reference in a function
call. Returning a struct or tuple will not have an additional overhead for compilers that
support return-value-optimization.
In C++14, a returned tuple can be conveniently processed using std::tie at the call
site, which will put the tuple elements directly into existing local variables. In C++17,
structured bindings allow to initialize local variables directly from members or elements
of a returned struct or tuple.
Note: For return types representing an abstraction, a struct should be preferred over a
generic tuple.
Note: This rule applies equally to std::pair, which is a special kind of tuple for
exactly two elements.
See also:
• C++ Core Guidelines [11]: F .21: T o return multiple ”out” values, prefer returning
a tuple or struct.
A8-4-5Required · Automated✓ compilable📄 공식 예제Official example
”consume” parameters declared as X && shall always be moved from. --- PAGE 159 ---”consume” parameters declared as X && shall always be moved from. --- PAGE 159 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility>
// $Id: A8-4-5.cpp 305588 2018-01-29 11:07:35Z michal.szczepankiewicz $
#include <string>
#include <vector>
class A
{
public:
explicit A(std::vector<std::string> &&v)
: m_v{std::move(v)} // Compliant, move from consume parameter
{
}
private:
std::vector<std::string> m_v;
};
class B
{
public:
explicit B(std::vector<std::string> &&v)
: m_v{v} // Non-Compliant, consume parameter not moved from
{
}
std::vector<std::string> m_v;
};⚠️ A ”consume” parameter is declared with a type of rvalue reference to non-const non-
template type (X &&). This documents that the value will be consumed in the function
(i.e. left in a moved-from state) and requires an explicit ’std::move’ at the call site if
an lvalue is passed to the function (an rvalue reference can implicitly bind only to an
rvalue).
Note: Other operations may be performed on the ”consume” parameter before being
moved.
See also:
• C++ Core Guidelines [11]: F .18: For ”consume” parameters, pass by X&& and
std::move the parameterA ”consume” parameter is declared with a type of rvalue reference to non-const non-
template type (X &&). This documents that the value will be consumed in the function
(i.e. left in a moved-from state) and requires an explicit ’std::move’ at the call site if
an lvalue is passed to the function (an rvalue reference can implicitly bind only to an
rvalue).
Note: Other operations may be performed on the ”consume” parameter before being
moved.
See also:
• C++ Core Guidelines [11]: F .18: For ”consume” parameters, pass by X&& and
std::move the parameter
A8-4-6Required · Automated✓ compilable📄 공식 예제Official example
”forward” parameters declared as T && shall always be forwarded. --- PAGE 160 ---”forward” parameters declared as T && shall always be forwarded. --- PAGE 160 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility>
// $Id: A8-4-6.cpp 305588 2018-01-29 11:07:35Z michal.szczepankiewicz $
#include <string>
#include <vector>
class A
{
public:
explicit A(std::vector<std::string> &&v);
};
class B
{
public:
explicit B(const std::vector<std::string> &v);
};
template<typename T, typename ... Args>
T make(Args && ... args)
{
return T{std::forward<Args>(args) ...}; // Compliant, forwarding args
}
int main()
{
make<A>(std::vector<std::string>{ });
std::vector<std::string> v;
make<B>(v);
}⚠️ A ”forward” parameter is declared with a type of forwarding reference (i.e. an rvalue
reference to non-const template type (T &&)). As a forwarding reference can bind to
both lvalues and rvalues, preserving lvalue-ness and cv qualifications, it is useful when
forwarding a value to another function using ”std::forward”.
However, as the parameter can bind to anything, it should only be used for forwarding
without performing any other operations on the parameter.
Note: A forwarding parameter can also be declared via ”auto &&” in a generic lambda
See also:
• C++ Core Guidelines [11]: F .19: For ”forward” parameters, pass by TP&& and
only std::forward the parameter
• A18-9-2 in section 6.18.9A ”forward” parameter is declared with a type of forwarding reference (i.e. an rvalue
reference to non-const template type (T &&)). As a forwarding reference can bind to
both lvalues and rvalues, preserving lvalue-ness and cv qualifications, it is useful when
forwarding a value to another function using ”std::forward”.
However, as the parameter can bind to anything, it should only be used for forwarding
without performing any other operations on the parameter.
Note: A forwarding parameter can also be declared via ”auto &&” in a generic lambda
See also:
• C++ Core Guidelines [11]: F .19: For ”forward” parameters, pass by TP&& and
only std::forward the parameter
• A18-9-2 in section 6.18.9
A8-4-8Required · Automated✓ compilable📄 공식 예제Official example
Output parameters shall not be used.Output parameters shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility> // $Id: A8-4-8.cpp 306164 2018-02-01 15:04:53Z christof.meerwald $ #include <iostream> #include <vector> // Compliant, return value std::vector<int> SortOutOfPlace(const std::vector<int>& inVec); // Non-compliant: return value as an out-parameter void FindAll(const std::vector<int>& inVec, std::vector<int>& outVec); struct B { }; struct BB { B GetB() const& { return obj; } B&& GetB() && { return std::move(obj); } B obj; }; // Non-compliant: returns a dangling reference BB&& MakeBb1() { return std::move(BB()); } // Compliant: uses compiler copy-ellision BB MakeBb2() { return BB(); } int main() { BB x = MakeBb2(); auto cpd = x.GetB(); // copied value auto mvd = MakeBb2().GetB(); // moved value return 0; }
⚠️ Output parameters are passed to a function as non-const references or pointers that
can denote either in-out or out-only parameter. Using return value prevents from
possible misuse of such a parameter.
Note: Prefer returning non-value types (i.e. types in a inheritance hierarchy) as
std::shared_ptr or std::unique_ptr.
See also:
• C++ Core Guidelines [11]: F .20: For ”out” output values, prefer return values to
output parameters.Output parameters are passed to a function as non-const references or pointers that
can denote either in-out or out-only parameter. Using return value prevents from
possible misuse of such a parameter.
Note: Prefer returning non-value types (i.e. types in a inheritance hierarchy) as
std::shared_ptr or std::unique_ptr.
See also:
• C++ Core Guidelines [11]: F .20: For ”out” output values, prefer return values to
output parameters.
A8-4-9Required · Automated✓ compilable📄 공식 예제Official example
”in-out” parameters declared as T & shall be modified.”in-out” parameters declared as T & shall be modified.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-4-9.cpp 306178 2018-02-01 15:52:25Z christof.meerwald $ #include <cstdint> #include <numeric> #include <string> #include <vector> // Non-Compliant: does not modify the "in-out" parameter int32_t Sum(std::vector<int32_t> &v) { return std::accumulate(v.begin(), v.end(), 0); } // Compliant: Modifying "in-out" parameter void AppendNewline(std::string &s) { s += '\n'; } // Non-Compliant: Replacing parameter value void GetFileExtension(std::string &ext) { ext = ".cpp"; }
⚠️ An ”in-out” parameter is declared with a type of reference to non-const. This means
that a fully constructed object is passed into the function that can be read as well as
modified.
Note: Completely replacing the passed in object without reading any data from it would
make it an ”out” parameter instead and is not considered compliant with this rule, also
see rule: A8-4-8
See also:
• C++ Core Guidelines [11]: F .17: For ”in-out” parameters, pass by reference to
non-const
• JSF December 2005 [8]: AV Rule 117.2: An object should be passed as T& if the
function may change the value of the object.An ”in-out” parameter is declared with a type of reference to non-const. This means
that a fully constructed object is passed into the function that can be read as well as
modified.
Note: Completely replacing the passed in object without reading any data from it would
make it an ”out” parameter instead and is not considered compliant with this rule, also
see rule: A8-4-8
See also:
• C++ Core Guidelines [11]: F .17: For ”in-out” parameters, pass by reference to
non-const
• JSF December 2005 [8]: AV Rule 117.2: An object should be passed as T& if the
function may change the value of the object.
A8-5-0Required · Automated✓ compilable📄 공식 예제Official example
All memory shall be initialized before it is read.All memory shall be initialized before it is read.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-5-0.cpp 307536 2018-02-14 12:35:11Z jan.babst $ #include <cstdint> #include <string> static std::int32_t zero; // Compliant - Variable with static storage duration // is zero-initialized. void local() { std::int32_t a; // No initialization std::int32_t b{}; // Compliant - zero initialization b = a; // Non-compliant - uninitialized memory read a = zero; // Compliant - a is zero now b = a; // Compliant - read from initialized memory std::string s; // Compliant - default constructor is a called // read from s } void dynamic() { // Note: These examples violate A18-5-2 auto const a = new std::int32_t; // No initialization auto const b = new std::int32_t{}; // Compliant - zero initialization *b = *a; // Non-compliant - uninitialized memory read *a = zero; // Compliant - a is zero now *b = *a; // Compliant - read from initialized memory delete b; delete a; auto const s = new std::string; // Compliant - default constructor is a called // read from *s delete s; } // Members of Bad are default-initialized by the (implicitly generated) default // constructor. Note that this violates A12-1-1. struct Bad { std::int32_t a; std::int32_t b; }; // Compliant - Members of Good are explicitly initialized. // This also complies to A12-1-1. struct Good { std::int32_t a{0}; std::int32_t b{0}; }; void members() { Bad bad; // Default constructor is called, but members a not initialized bad.b = bad.a; // Non-compliant - uninitialized memory read bad.a = zero; // Compliant - bad.a is zero now bad.b = bad.a; // Compliant - read from initialized memory Good good; // Default constructor is called and initializes members std::int32_t x = good.a; // Compliant std::int32_t y = good.b; // Compliant }
⚠️ Objects with automatic or dynamic storage duration are default-initialized if no initializer
is specified. Default initialization produces indeterminate values for objects of neither
class nor array types. Default initialization of array types leads to default initialization
of each array element. Reading from indeterminate values may produce undefined
behavior.
Thus, all local variables, member variables, or objects allocated dynamically must
be explicitly initialized before their values are read, unless they are of class type or
array of non-fundamental type. It is recommended practice to initialize all such objects
immediately when they are defined.
Note: Zero-initialization will happen before any other initialization for any objects with
static or thread-local storage duration. Thus, such objects need not be explicitly
initialized.
See also:
• MISRA C++ 2008 [7]: 8-5-1: All variables shall have a defined value before they
are used.
• HIC++ v4.0 [9]: 8.4.1: Do not access an invalid object or an object with
indeterminate value
• JSF December 2005 [8]: AV Rule 142: All variables shall be initialized before
use.
• SEI CERT C++ Coding Standard [10]: EXP53-CPP: Do not read uninitialized
memory
• C++ Core Guidelines [11]: ES.20: Always initialize an object
• ISO/IEC 14882:2014 [3]: 8.5: [dcl.init]Objects with automatic or dynamic storage duration are default-initialized if no initializer
is specified. Default initialization produces indeterminate values for objects of neither
class nor array types. Default initialization of array types leads to default initialization
of each array element. Reading from indeterminate values may produce undefined
behavior.
Thus, all local variables, member variables, or objects allocated dynamically must
be explicitly initialized before their values are read, unless they are of class type or
array of non-fundamental type. It is recommended practice to initialize all such objects
immediately when they are defined.
Note: Zero-initialization will happen before any other initialization for any objects with
static or thread-local storage duration. Thus, such objects need not be explicitly
initialized.
See also:
• MISRA C++ 2008 [7]: 8-5-1: All variables shall have a defined value before they
are used.
• HIC++ v4.0 [9]: 8.4.1: Do not access an invalid object or an object with
indeterminate value
• JSF December 2005 [8]: AV Rule 142: All variables shall be initialized before
use.
• SEI CERT C++ Coding Standard [10]: EXP53-CPP: Do not read uninitialized
memory
• C++ Core Guidelines [11]: ES.20: Always initialize an object
• ISO/IEC 14882:2014 [3]: 8.5: [dcl.init]
A8-5-1Required · Automated✓ compilable📄 공식 예제Official example
In an initialization list, the order of initialization shall be following: (1) virtual base classes in depth and left to right order of the inheritance graph, (2) direct base classes in left to right order of inheritance list, (3) non-static data members in the order they were declared in the class definition.In an initialization list, the order of initialization shall be following: (1) virtual base classes in depth and left to right order of the inheritance graph, (2) direct base classes in left to right order of inheritance list, (3) non-static data members in the order they were declared in the class definition.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-5-1.cpp 271696 2017-03-23 09:23:09Z piotr.tanski $
#include <cstdint>
#include <string>
class A
{
};
class B
{
};
class C : public virtual B, public A
{
public:
C() : B(), A(), s() {} // Compliant
// C() : A(), B() { } // Non-compliant - incorrect order of initialization
private:
std::string s;
};
class D
{
};
class E
{
};
class F : public virtual A, public B, public virtual D, public E
{
public:
F() : A(), D(), B(), E(), number1(0), number2(0U) {} // Compliant
F(F const& oth)
: B(), E(), A(), D(), number1(oth.number1), number2(oth.number2)
{
} // Non-compliant - incorrect
// order of initialization
private:
std::int32_t number1;
std::uint8_t number2;
};⚠️ T o avoid confusion and possible use of uninitialized data members, it is recommended
that the initialization list matches the actual initialization order.
Regardless of the order of member initializers in a initialization list, the order of
initialization is always:
• Virtual base classes in depth and left to right order of the inheritance graph.
• Direct non-virtual base classes in left to right order of inheritance list.
• Non-static member data in order of declaration in the class definition.
Note that “The order of derivation is relevant only to determine the order of default
initialization by constructors and cleanup by destructors. ” [C++14 Language Standard
[3]]
See also:
• HIC++ v4.0 [9]:12.4.4 Write members in an initialization list in the order in which
they are declaredT o avoid confusion and possible use of uninitialized data members, it is recommended
that the initialization list matches the actual initialization order.
Regardless of the order of member initializers in a initialization list, the order of
initialization is always:
• Virtual base classes in depth and left to right order of the inheritance graph.
• Direct non-virtual base classes in left to right order of inheritance list.
• Non-static member data in order of declaration in the class definition.
Note that “The order of derivation is relevant only to determine the order of default
initialization by constructors and cleanup by destructors. ” [C++14 Language Standard
[3]]
See also:
• HIC++ v4.0 [9]:12.4.4 Write members in an initialization list in the order in which
they are declared
A8-5-3Required · Automated✓ compilable📄 공식 예제Official example
A variable of type auto shall not be initialized using {} or ={} braced-initialization.A variable of type auto shall not be initialized using {} or ={} braced-initialization.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A8-5-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <initializer_list>
void Fn() noexcept
{
auto x1(10); // Compliant - the auto-declared variable is of type int, but
// not compliant with A8-5-2.
auto x2{10}; // Non-compliant - according to C++14 standard the
// auto-declared variable is of type std::initializer_list.
// However, it can behave differently on different compilers.
auto x3 = 10; // Compliant - the auto-declared variable is of type int, but
// non-compliant with A8-5-2.
auto x4 = {10}; // Non-compliant - the auto-declared variable is of type
// std::initializer_list, non-compliant with A8-5-2.
std::int8_t x5{10}; // Compliant
}⚠️ If an initializer of a variable of type auto is enclosed in braces, then the result of type
deduction may lead to developer confusion, as the variable initialized using {} or ={} will
always be of std::initializer_list type.
Note that some compilers, e.g. GCC or Clang, can implement this differently -
initializing a variable of type auto using {} will deduce an integer type, and initializing
using ={} will deduce a std::initializer_list type. This is desirable type deduction which
will be introduced into the C++ Language Standard with C++17.
See also:
• Effective Modern C++ [13]: Item 2. Understand auto type deduction.
• Effective Modern C++ [13]: Item 7. Distinguish between () and {} when creating
objects.If an initializer of a variable of type auto is enclosed in braces, then the result of type
deduction may lead to developer confusion, as the variable initialized using {} or ={} will
always be of std::initializer_list type.
Note that some compilers, e.g. GCC or Clang, can implement this differently -
initializing a variable of type auto using {} will deduce an integer type, and initializing
using ={} will deduce a std::initializer_list type. This is desirable type deduction which
will be introduced into the C++ Language Standard with C++17.
See also:
• Effective Modern C++ [13]: Item 2. Understand auto type deduction.
• Effective Modern C++ [13]: Item 7. Distinguish between () and {} when creating
objects.
A8-5-4Advisory · Automated✓ compilable📄 공식 예제Official example
If a class has a user-declared constructor that takes a parameter of type std::initializer_list, then it shall be the only constructor apart from special member function constructors.If a class has a user-declared constructor that takes a parameter of type std::initializer_list, then it shall be the only constructor apart from special member function constructors.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef> #include <stdexcept> // $Id: A8-5-4.cpp 319328 2018-05-15 10:30:25Z michal.szczepankiewicz $ #include <cstdint> #include <initializer_list> #include <vector> #include <iostream> //non-compliant, there are other constructors //apart from initializer_list one defined class A { public: A() = default; A(std::size_t num1, std::size_t num2) : x{num1}, y{num2} {} A(std::initializer_list<std::size_t> list) : x{list.size()}, y{list.size()} { } private: std::size_t x; std::size_t y; }; class B { public: B() = default; B(std::initializer_list<std::size_t> list) : collection{list} { } private: std::vector<std::size_t> collection; }; void F1() noexcept { A a1{}; // Calls A::A() A a2{{}}; // Calls A::A(std::initializer_list<std::size_t>) A a3{0, 1}; // Calls A::A(std::initializer_list<std::size_t>), not recommended A a4({0, 1});// Calls A::A(std::initializer_list<std::size_t>), recommended A a5(0, 1); // Calls A::A(std::size_t, std::size_t), compliant with A8-5-2 by exception } void F2() noexcept { B b1{}; // Calls B::B() B b2{{}}; // Calls B::B(std::initializer_list<std::size_t>) B b3{1, 2}; // Calls B::B(std::initializer_list<std::size_t>), not recommended B b4({1, 2}); // Calls B::B(std::initializer_list<std::size_t>), recommended }
⚠️ If an object is initialized using {} braced-initialization, the compiler strongly prefers
constructor taking parameter of type std::initializer_list to other constructors.
Thus, if it is defined in the class, it is initially a sole member of the candidate set of
the two-phase overload resolution. Only if no viable std::initializer_list is found,
the rest of constructors are considered in the second overload resolution.
Such a case can be non-intuitive for developers and can lead to reviewers’ confusion
on which constructor was intended to be called.
If other constructors (besides the std::initializer_list one and special member
functions) are declared in a class, then it is suggested to use, e.g. the std::vector<int
>( {1,1} ) syntax instead of std::vector<int> v{1, 1} , which makes the intent clear.
See also:
• Effective Modern C++ [13]: Item 7. Distinguish between () and {} when creating
objects.
• ISO/IEC 14882:2014 [3]: 13.3.1.7: [over.match.list]
6.9 Classes
6.9.3 Member functionIf an object is initialized using {} braced-initialization, the compiler strongly prefers
constructor taking parameter of type std::initializer_list to other constructors.
Thus, if it is defined in the class, it is initially a sole member of the candidate set of
the two-phase overload resolution. Only if no viable std::initializer_list is found,
the rest of constructors are considered in the second overload resolution.
Such a case can be non-intuitive for developers and can lead to reviewers’ confusion
on which constructor was intended to be called.
If other constructors (besides the std::initializer_list one and special member
functions) are declared in a class, then it is suggested to use, e.g. the std::vector<int
>( {1,1} ) syntax instead of std::vector<int> v{1, 1} , which makes the intent clear.
See also:
• Effective Modern C++ [13]: Item 7. Distinguish between () and {} when creating
objects.
• ISO/IEC 14882:2014 [3]: 13.3.1.7: [over.match.list]
6.9 Classes
6.9.3 Member function
M0M0 (MISRA 유래)M0 (MISRA-origin)
M0-1-1Required · Automated✓ compilable
도달할 수 없는(unreachable) 코드를 두지 않는다A project shall not contain unreachable code
❌ 위반 예시Non-compliant example
#include <iostream>
static int f(int x) {
return x;
std::cout << "after return\n"; // return 뒤 — 절대 실행되지 않는 죽은 코드
}
int main() { std::cout << f(3) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
static int f(int x) {
std::cout << "before return\n"; // 의미 있는 위치로 이동
return x;
}
int main() { std::cout << f(3) << '\n'; }⚠️ 근거: return·throw·break 뒤에 오는, 어떤 입력으로도 실행될 수 없는 코드는 흐름상 도달 불가능하다. 영향: 도달 불가 코드는 보통 잘못된 조기 return 이나 흐름 오류의 신호이며, 실행될 것으로 믿고 작성한 로깅·정리 코드가 조용히 무시되어 버그가 숨는다. 대응: 도달 불가 코드를 제거하거나, 실행되어야 한다면 분기·순서를 바로잡아 도달 가능하게 만든다(컴파일러 -Wunreachable 계열 경고 활용).Rationale: code following return, throw, or break that can never execute under any input is flow-unreachable. Impact: unreachable code usually signals a misplaced early return or a flow error, and logging or cleanup written in the belief it would run is silently ignored, hiding bugs. Fix: remove unreachable code, or if it should run, correct the branching/ordering to make it reachable (using compiler -Wunreachable-style warnings).
M0-1-3Required · Automated✓ compilable
사용되지 않는 변수를 두지 않는다A project shall not contain unused variables
❌ 위반 예시Non-compliant example
#include <iostream>
static int compute() { return 42; }
int main() {
int tmp = compute(); // 선언·초기화했지만 어디서도 사용 안 됨
int base = 10;
std::cout << base << '\n'; // tmp 는 죽은 변수
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int base = 10;
std::cout << base << '\n'; // 필요한 변수만 유지
}⚠️ 근거: 선언·초기화만 되고 한 번도 읽히지 않는 변수는 그 계산이 결과에 기여하지 않는 죽은 코드다. 영향: 미사용 변수는 흔히 빠뜨린 사용(예: tmp 를 써야 할 자리에 다른 값을 씀)이라는 진짜 버그의 신호이고, 코드를 어지럽혀 리뷰·유지보수를 방해한다. 대응: 미사용 변수를 제거하고, 부작용 때문에 호출은 필요하지만 결과가 불필요하면 결과를 받지 않도록 한다(또는 [[maybe_unused]] 로 의도 표시).Rationale: a variable that is declared and initialized but never read is dead code whose computation does not contribute to the result. Impact: an unused variable often signals a real bug of missed use (e.g. writing another value where tmp should have been used) and clutters the code, hindering review and maintenance. Fix: remove unused variables, and when a call is needed for its side effect but its result is not, do not capture the result (or mark intent with [[maybe_unused]]).
M0-3-2Required · Automated✓ compilable
함수가 오류 정보를 반환하면 호출부에서 검사한다If a function generates error information, then that error information shall be tested
❌ 위반 예시Non-compliant example
#include <iostream>
#include <fstream>
int main() {
std::ofstream f("/root/forbidden/out.txt"); // 열기 실패 가능(권한)
f << "data"; // 실패 상태 미검사 — 쓰기가 조용히 버려짐
std::cout << "thought it wrote\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <fstream>
int main() {
std::ofstream f("/root/forbidden/out.txt");
if (!f) { std::cout << "open failed\n"; return 1; } // 실패를 즉시 검사
f << "data";
std::cout << "wrote\n";
}⚠️ 근거: 오류 정보를 반환·설정하는 함수(또는 스트림 상태 플래그)의 결과를 검사하지 않으면, 실패가 발생했는지 알 수 없는 채로 다음 단계로 넘어간다. 영향: 파일 열기 실패 후에도 쓰기를 계속하면 데이터가 조용히 사라지고, 실패가 누적되어 일관성 깨짐·데이터 손상으로 이어지며 사후 원인 추적이 어렵다. 대응: 오류를 알리는 반환값·상태를 호출 직후 검사해 실패 경로를 명시적으로 처리한다.Rationale: not testing the result of a function that returns or sets error information (or a stream state flag) moves on to the next step without knowing whether a failure occurred. Impact: continuing to write after a file open fails silently discards data, and accumulated failures lead to broken consistency and corruption that is hard to trace afterward. Fix: test the error-indicating return value or state right after the call and handle the failure path explicitly.
M0-1-10Advisory · Automated✓ compilable📄 공식 예제Official example
Every defined function should be called at least once.Every defined function should be called at least once.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-1-10: Every defined function should be called at least once. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: This rule enforces developers to statically and explicitly use every function in
the source code. A function does not necessarily need to be called at run-time. Rule
M0-1-1 detects all unreachable code occurrences.See MISRA C++ 2008 [7]
Note: This rule enforces developers to statically and explicitly use every function in
the source code. A function does not necessarily need to be called at run-time. Rule
M0-1-1 detects all unreachable code occurrences.
M0-1-2Required · Automated✓ compilable📄 공식 예제Official example
A project shall not contain infeasible paths.A project shall not contain infeasible paths.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-1-2: A project shall not contain infeasible paths. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: A path can also be infeasible because of a call to constexpr function which
returned value, known statically , will never fulfill the condition of a condition statement.See MISRA C++ 2008 [7]
Note: A path can also be infeasible because of a call to constexpr function which
returned value, known statically , will never fulfill the condition of a condition statement.
M0-1-4Required · Automated✓ compilable📄 공식 예제Official example
A project shall not contain non-volatile POD variables having only one use.A project shall not contain non-volatile POD variables having only one use.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-1-4: A project shall not contain non-volatile POD variables having only one use. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M0-1-8Required · Automated✓ compilable📄 공식 예제Official example
All functions with void return type shall have external side effect(s).All functions with void return type shall have external side effect(s).
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-1-8: All functions with void return type shall have external side effect(s). // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M0-1-9Required · Automated✓ compilable📄 공식 예제Official example
There shall be no dead code.There shall be no dead code.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-1-9: There shall be no dead code. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
See also:
• JSF December 2005 [8]: AV Rule 181: Redundant explicit casts will not be used.See MISRA C++ 2008 [7]
See also:
• JSF December 2005 [8]: AV Rule 181: Redundant explicit casts will not be used.
M0-2-1Required · Automated✓ compilable📄 공식 예제Official example
An object shall not be assigned to an overlapping object.An object shall not be assigned to an overlapping object.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-2-1: An object shall not be assigned to an overlapping object. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.0.3 Runtime failuresSee MISRA C++ 2008 [7]
6.0.3 Runtime failures
M0-3-1Required · Non-automated✓ compilable📄 공식 예제Official example
Minimization of run-time failures shall be ensured by the use of at least one of: (a) static analysis tools/techniques; (b) dynamic analysis tools/techniques; (c) explicit coding of checks to handle run-time faults.Minimization of run-time failures shall be ensured by the use of at least one of: (a) static analysis tools/techniques; (b) dynamic analysis tools/techniques; (c) explicit coding of checks to handle run-time faults.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-3-1: Minimization of run-time failures shall be ensured by the use of at least one of: (a) static analysis tools/techniques; (b) dynamic analysis tools/techniques; (c) explicit coding of checks to handle run-time faults. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M0-4-1Required · Non-automated✓ compilable📄 공식 예제Official example
Use of scaled-integer or fixed-point arithmetic shall be documented.Use of scaled-integer or fixed-point arithmetic shall be documented.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-4-1: Use of scaled-integer or fixed-point arithmetic shall be documented. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M0-4-2Required · Non-automated✓ compilable📄 공식 예제Official example
Use of floating-point arithmetic shall be documented.Use of floating-point arithmetic shall be documented.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M0-4-2: Use of floating-point arithmetic shall be documented. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5M5 (MISRA 유래)M5 (MISRA-origin)
M5-0-2Advisory · Automated✓ compilable
연산자 우선순위 의존을 괄호로 제한한다Limited dependence should be placed on operator precedence rules in expressions
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int a = 1, b = 2, c = 1, d = 6;
int r = a + b << c & d; // +, <<, & 우선순위를 외워야 의미 파악
std::cout << r << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int a = 1, b = 2, c = 1, d = 6;
int r = ((a + b) << c) & d; // 괄호로 평가 순서를 명시
std::cout << r << '\n';
}⚠️ 근거: +, <<, & 처럼 우선순위가 직관적이지 않은 연산자들을 한 식에 섞으면, 괄호 없이는 평가 순서를 외워야만 의미를 알 수 있다. 영향: 독자나 유지보수자가 우선순위를 잘못 가정하면 식의 의미를 오독해 결함을 넣고, 특히 비트·시프트 연산이 섞이면 산술 우선순위와 헷갈리기 쉽다. 대응: 우선순위가 자명하지 않은 복합 표현식은 괄호로 평가 순서를 명시해 의도를 코드에 드러낸다.Rationale: mixing operators with non-intuitive precedence such as +, <<, and & in one expression forces readers to memorize the evaluation order to know the meaning without parentheses. Impact: a reader or maintainer who assumes the wrong precedence misreads the expression and introduces defects, especially where bitwise and shift operators are confused with arithmetic precedence. Fix: parenthesize compound expressions whose precedence is not obvious to make the evaluation order explicit in the code.
M5-0-4Required · Automated✓ compilable
암시적 정수 변환이 부호(signedness)를 바꾸지 않게 한다An implicit integral conversion shall not change the signedness of the underlying type
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
unsigned u = 1u;
int s = -1;
if (s < u) std::cout << "s < u\n"; // s 가 거대한 unsigned 로 변환 → 비교 뒤집힘
else std::cout << "s >= u\n"; // 실제로 이쪽이 출력됨(직관과 반대)
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int s = -1;
int u = 1; // 부호를 통일(또는 명시적 캐스트로 의도 표현)
if (s < u) std::cout << "s < u\n"; // -1 < 1 — 직관대로
else std::cout << "s >= u\n";
}⚠️ 근거: 부호 있는 값과 없는 값을 한 식에서 비교·연산하면, 일반적 산술 변환 규칙에 따라 부호 있는 값이 부호 없는 타입으로 변환되어 음수가 거대한 양수가 된다. 영향: -1 < 1u 같은 비교가 거짓이 되는 등 결과가 직관과 정반대로 뒤집혀, 길이·인덱스 비교나 루프 종료 조건에서 경계 오류·무한 루프를 일으킨다. 대응: 비교·연산 대상의 부호를 통일하거나, 의도한 변환을 static_cast 로 명시하고 컴파일러 부호 변환 경고(-Wsign-conversion)를 켠다.Rationale: comparing or operating on a signed and an unsigned value in one expression converts the signed value to the unsigned type under the usual arithmetic conversions, turning a negative number into a huge positive one. Impact: comparisons like -1 < 1u become false, flipping the result opposite to intuition and causing boundary errors or infinite loops in length/index comparisons or loop termination conditions. Fix: unify the signedness of the operands, or make the intended conversion explicit with static_cast and enable the compiler sign-conversion warning (-Wsign-conversion).
M5-0-15Required · Automated✓ compilable
포인터 산술은 배열 첨자 형태로만 수행한다Array indexing shall be the only form of pointer arithmetic
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int a[5] = {0, 1, 2, 3, 4};
int* p = a;
*(p + 3) = 99; // 노골적 포인터 산술 — 경계 오류를 가리기 쉬움
std::cout << a[3] << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int a[5] = {0, 1, 2, 3, 4};
int* p = a;
p[3] = 99; // 배열 첨자 표기 — 인덱스 의도가 분명
std::cout << a[3] << '\n';
}⚠️ 근거: p[i] 와 *(p+i) 는 의미가 같지만, 명시적 포인터 덧셈은 인덱스가 무엇이고 그것이 배열 범위 안인지에 대한 의도를 흐린다. 영향: 노골적 포인터 산술은 경계를 벗어난 오프셋을 평범한 덧셈처럼 보이게 해 버퍼 오버런을 숨기고, 정적 분석기가 인덱스 범위를 추론하기 어렵게 만든다. 대응: 포인터 산술을 배열 첨자 표기 p[i] 로만 표현해 인덱스 의도를 드러내고, 가능하면 std::array·범위 기반 접근으로 경계 검사를 돕는다.Rationale: p[i] and *(p+i) mean the same, but explicit pointer addition obscures the intent of what the index is and whether it is within the array bounds. Impact: explicit pointer arithmetic makes an out-of-bounds offset look like ordinary addition, hiding buffer overruns and making it harder for static analyzers to infer the index range. Fix: express pointer arithmetic only as array indexing p[i] to reveal index intent, and prefer std::array or range-based access to aid bounds checking where possible.
M5-2-8Required · Automated✓ compilable
객체 포인터를 정수나 void* 로 무분별하게 변환하지 않는다An object pointer shall not be converted to an integer or unrelated pointer type
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdint>
struct Widget { int id = 7; };
int main() {
Widget w;
auto n = reinterpret_cast<std::uintptr_t>(&w); // 포인터를 정수로 — 타입 추적성 상실
Widget* back = reinterpret_cast<Widget*>(n); // 복원 시 타입 안전성 없음
std::cout << back->id << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
struct Widget { int id = 7; };
static void use(Widget* w) { std::cout << w->id << '\n'; }
int main() {
Widget w;
use(&w); // 포인터를 원래 타입 그대로 전달
}⚠️ 근거: 객체 포인터를 정수(uintptr_t)나 무관한 포인터 타입으로 바꿔 보관·복원하면, 컴파일러의 타입 검사를 우회하고 원래 가리키던 타입 정보를 잃는다. 영향: 정수로 왕복한 포인터는 잘못된 타입으로 복원되거나, 객체 수명·정렬과 무관하게 다뤄져 미정의 동작·추적 불가능한 손상을 부른다. 대응: 포인터는 원래의 정적 타입으로 유지·전달하고, 다형성이 필요하면 공통 기반 타입 포인터나 std::variant·태그된 핸들 같은 타입 안전한 추상을 사용한다.Rationale: converting an object pointer to an integer (uintptr_t) or an unrelated pointer type to store and restore it bypasses the compiler type checks and loses the original pointed-to type information. Impact: a pointer round-tripped through an integer may be restored as the wrong type or handled regardless of object lifetime and alignment, causing undefined behaviour and untraceable corruption. Fix: keep and pass pointers in their original static type, and when polymorphism is needed use a common base pointer or a type-safe abstraction such as std::variant or a tagged handle.
M5-14-1Required · Automated✓ compilable
&&/|| 의 우변에 부작용을 두지 않는다The right hand operand of a && or || operator shall not contain side effects
❌ 위반 예시Non-compliant example
#include <iostream>
static int g_calls = 0;
static int fetch() { ++g_calls; return 5; }
int main() {
bool ok = false;
int n = 0;
if (ok && (n = fetch()) > 0) std::cout << "branch\n"; // ok 가 거짓 → 우변 미실행
std::cout << "n=" << n << " calls=" << g_calls << '\n'; // n=0 calls=0 — 부작용 누락
}✅ 준수 예시Compliant example
#include <iostream>
static int g_calls = 0;
static int fetch() { ++g_calls; return 5; }
int main() {
bool ok = false;
int n = fetch(); // 부작용을 조건 밖에서 무조건 수행
if (ok && n > 0) std::cout << "branch\n";
std::cout << "n=" << n << " calls=" << g_calls << '\n'; // n=5 calls=1
}⚠️ 근거: && 와 || 는 단락 평가(short-circuit)를 하므로, 좌변 결과에 따라 우변이 아예 실행되지 않을 수 있다. 영향: 우변에 대입·증가·함수 호출 같은 부작용을 두면 그것이 조건부로만 일어나, 예제처럼 n=fetch() 가 건너뛰어져 변수·카운터가 기대와 달라지는 미묘한 버그가 된다. 대응: 부작용은 논리 연산 밖의 독립 문장에서 무조건 수행하고, && / || 의 피연산자는 부작용 없는 순수 조건식으로 유지한다.Rationale: && and || short-circuit, so the right operand may not execute at all depending on the left operand result. Impact: putting side effects like assignment, increment, or a function call in the right operand makes them happen only conditionally, so as in the example n=fetch() is skipped and variables or counters differ from expectation — a subtle bug. Fix: perform side effects unconditionally in a separate statement outside the logical operator and keep the operands of && / || pure, side-effect-free conditions.
M5-18-1Required · Automated✓ compilable
쉼표 연산자를 사용하지 않는다The comma operator shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
static int a() { std::cout << "a "; return 1; }
static int b() { std::cout << "b "; return 2; }
int main() {
int x = (a(), b()); // 쉼표 연산자 — a() 부작용이 한 식에 숨고 결과는 b()
std::cout << "x=" << x << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
static int a() { std::cout << "a "; return 1; }
static int b() { std::cout << "b "; return 2; }
int main() {
a(); // 부작용을 독립 문장으로 드러냄
int x = b();
std::cout << "x=" << x << '\n';
}⚠️ 근거: 쉼표 연산자 (e1, e2) 는 e1 을 평가해 부작용만 취하고 버린 뒤 e2 의 값을 결과로 주는데, 이 구조는 부작용과 결과가 한 식에 뒤섞여 잘 드러나지 않는다. 영향: 독자가 첫 피연산자의 부작용을 놓치거나, 쉼표를 함수 인자 구분자와 혼동해 의미를 오독하기 쉬워 분석·리뷰가 어려워진다. 대응: 쉼표 연산자를 쓰지 말고 각 부작용·계산을 별도 문장으로 분리해 평가 순서와 결과를 명확히 한다.Rationale: the comma operator (e1, e2) evaluates e1 only for its side effect, discards it, and yields the value of e2, a structure that mixes side effects and result into one expression where they are hard to see. Impact: readers miss the side effect of the first operand or confuse the comma with an argument separator, easily misreading the meaning and making analysis and review harder. Fix: avoid the comma operator and split each side effect and computation into separate statements to make the evaluation order and result clear.
M5-0-10Required · Automated✓ compilable📄 공식 예제Official example
If the bitwise operators ~and << are applied to an operand with an underlying type of unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand.If the bitwise operators ~and << are applied to an operand with an underlying type of unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-10: If the bitwise operators ~and << are applied to an operand with an underlying type of unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-11Required · Automated✓ compilable📄 공식 예제Official example
The plain char type shall only be used for the storage and use of character values.The plain char type shall only be used for the storage and use of character values.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-11: The plain char type shall only be used for the storage and use of character values. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-12Required · Automated✓ compilable📄 공식 예제Official example
Signed char and unsigned char type shall only be used for the storage and use of numeric values.Signed char and unsigned char type shall only be used for the storage and use of numeric values.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-12: Signed char and unsigned char type shall only be used for the storage and use of numeric values. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-14Required · Automated✓ compilable📄 공식 예제Official example
The first operand of a conditional-operator shall have type bool.The first operand of a conditional-operator shall have type bool.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-14: The first operand of a conditional-operator shall have type bool. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-16Required · Automated✓ compilable📄 공식 예제Official example
A pointer operand and any pointer resulting from pointer arithmetic using that operand shall both address elements of the same array.A pointer operand and any pointer resulting from pointer arithmetic using that operand shall both address elements of the same array.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-16: A pointer operand and any pointer resulting from pointer arithmetic using that operand shall both address elements of the same array. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: The next element beyond the end of an array indicates the end of the array .See MISRA C++ 2008 [7]
Note: The next element beyond the end of an array indicates the end of the array .
M5-0-17Required · Automated✓ compilable📄 공식 예제Official example
Subtraction between pointers shall only be applied to pointers that address elements of the same array.Subtraction between pointers shall only be applied to pointers that address elements of the same array.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-17: Subtraction between pointers shall only be applied to pointers that address elements of the same array. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-18Required · Automated✓ compilable📄 공식 예제Official example
>, >=, <, <= shall not be applied to objects of pointer type, except where they point to the same array.>, >=, <, <= shall not be applied to objects of pointer type, except where they point to the same array.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-18: >, >=, <, <= shall not be applied to objects of pointer type, except where they point to the same array. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-20Required · Automated✓ compilable📄 공식 예제Official example
Non-constant operands to a binary bitwise operator shall have the same underlying type.Non-constant operands to a binary bitwise operator shall have the same underlying type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-20: Non-constant operands to a binary bitwise operator shall have the same underlying type. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-21Required · Automated✓ compilable📄 공식 예제Official example
Bitwise operators shall only be applied to operands of unsigned underlying type.Bitwise operators shall only be applied to operands of unsigned underlying type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-21: Bitwise operators shall only be applied to operands of unsigned underlying type. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.5.1 Primary expressionSee MISRA C++ 2008 [7]
6.5.1 Primary expression
M5-0-3Required · Automated✓ compilable📄 공식 예제Official example
A cvalue expression shall not be implicitly converted to a different underlying type.A cvalue expression shall not be implicitly converted to a different underlying type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-3: A cvalue expression shall not be implicitly converted to a different underlying type. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-5Required · Automated✓ compilable📄 공식 예제Official example
There shall be no implicit floating-integral conversions.There shall be no implicit floating-integral conversions.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-5: There shall be no implicit floating-integral conversions. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-6Required · Automated✓ compilable📄 공식 예제Official example
An implicit integral or floating-point conversion shall not reduce the size of the underlying type.An implicit integral or floating-point conversion shall not reduce the size of the underlying type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-6: An implicit integral or floating-point conversion shall not reduce the size of the underlying type. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-7Required · Automated✓ compilable📄 공식 예제Official example
There shall be no explicit floating-integral conversions of a cvalue expression.There shall be no explicit floating-integral conversions of a cvalue expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-7: There shall be no explicit floating-integral conversions of a cvalue expression. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Standard library functions, i.e. std::floor and std::ceil, return a floating-point data
type:
1 #include <cmath>
2 #include <cstdint>
3
4 void Fn() noexcept
5 {
6 float f = -4.5;
7 std::int8_t x1 = static_cast<std::int8_t>(f); // Compliant, x1 = -4
8 std::int8_t x2 =
9 static_cast<std::int8_t>(std::floor(f)); // Compliant, x2 = -5
10 std::int8_t x3 =
11 static_cast<std::int8_t>(std::ceil(f)); // Compliant, x3 = -4
12 }See MISRA C++ 2008 [7]
Note: Standard library functions, i.e. std::floor and std::ceil, return a floating-point data
type:
1 #include <cmath>
2 #include <cstdint>
3
4 void Fn() noexcept
5 {
6 float f = -4.5;
7 std::int8_t x1 = static_cast<std::int8_t>(f); // Compliant, x1 = -4
8 std::int8_t x2 =
9 static_cast<std::int8_t>(std::floor(f)); // Compliant, x2 = -5
10 std::int8_t x3 =
11 static_cast<std::int8_t>(std::ceil(f)); // Compliant, x3 = -4
12 }
M5-0-8Required · Automated✓ compilable📄 공식 예제Official example
An explicit integral or floating-point conversion shall not increase the size of the underlying type of a cvalue expression.An explicit integral or floating-point conversion shall not increase the size of the underlying type of a cvalue expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-8: An explicit integral or floating-point conversion shall not increase the size of the underlying type of a cvalue expression. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-0-9Required · Automated✓ compilable📄 공식 예제Official example
An explicit integral conversion shall not change the signedness of the underlying type of a cvalue expression.An explicit integral conversion shall not change the signedness of the underlying type of a cvalue expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-0-9: An explicit integral conversion shall not change the signedness of the underlying type of a cvalue expression. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-17-1Required · Non-automated✓ compilable📄 공식 예제Official example
The semantic equivalence between a binary operator and its assignment operator form shall be preserved.The semantic equivalence between a binary operator and its assignment operator form shall be preserved.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-17-1: The semantic equivalence between a binary operator and its assignment operator form shall be preserved. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.5.19 Comma operatorSee MISRA C++ 2008 [7]
6.5.19 Comma operator
M5-19-1Required · Automated✓ compilable📄 공식 예제Official example
Evaluation of constant unsigned integer expressions shall not lead to wrap-around.Evaluation of constant unsigned integer expressions shall not lead to wrap-around.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-19-1: Evaluation of constant unsigned integer expressions shall not lead to wrap-around. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Obligation level changed
Note: This rule applies to bit-fields, too.
6.6 Statements
6.6.2 Expression statementSee MISRA C++ 2008 [7]
Note: Obligation level changed
Note: This rule applies to bit-fields, too.
6.6 Statements
6.6.2 Expression statement
M5-2-10Required · Automated✓ compilable📄 공식 예제Official example
The increment ( ++) and decrement ( −−) operators shall not be mixed with other operators in an expression.The increment ( ++) and decrement ( −−) operators shall not be mixed with other operators in an expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-2-10: The increment ( ++) and decrement ( −−) operators shall not be mixed with other operators in an expression. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Obligation level changed.See MISRA C++ 2008 [7]
Note: Obligation level changed.
M5-2-11Required · Automated✓ compilable📄 공식 예제Official example
The comma operator, && operator and the || operator shall not be overloaded.The comma operator, && operator and the || operator shall not be overloaded.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-2-11: The comma operator, && operator and the || operator shall not be overloaded. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-2-12Required · Automated✓ compilable📄 공식 예제Official example
An identifier with array type passed as a function argument shall not decay to a pointer.An identifier with array type passed as a function argument shall not decay to a pointer.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-2-12: An identifier with array type passed as a function argument shall not decay to a pointer. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
See also:
• C++ Core Guidelines [11]: C.152: Never assign a pointer to an array of derived
class objects to a pointer to its base.
• C++ Core Guidelines [11]: R.2: In interfaces, use raw pointers to denote
individual objects (only).
• C++ Core Guidelines [11]: I.13: Do not pass an array as a single pointer.
6.5.3 Unary expressionsSee MISRA C++ 2008 [7]
See also:
• C++ Core Guidelines [11]: C.152: Never assign a pointer to an array of derived
class objects to a pointer to its base.
• C++ Core Guidelines [11]: R.2: In interfaces, use raw pointers to denote
individual objects (only).
• C++ Core Guidelines [11]: I.13: Do not pass an array as a single pointer.
6.5.3 Unary expressions
M5-2-2Required · Automated✓ compilable📄 공식 예제Official example
A pointer to a virtual base class shall only be cast to a pointer to a derived class by means of dynamic_cast.A pointer to a virtual base class shall only be cast to a pointer to a derived class by means of dynamic_cast.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-2-2: A pointer to a virtual base class shall only be cast to a pointer to a derived class by means of dynamic_cast. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
See also:
• JSF December 2005 [8]: AV Rule 178: Down casting (casting from base to
derived class) shall only be allowed through one of the following mechanism:
Virtual functions that act like dynamic casts (most likely useful in relatively simple
cases); Use of the visitor (or similar) pattern (most likely useful in complicated
cases).See MISRA C++ 2008 [7]
See also:
• JSF December 2005 [8]: AV Rule 178: Down casting (casting from base to
derived class) shall only be allowed through one of the following mechanism:
Virtual functions that act like dynamic casts (most likely useful in relatively simple
cases); Use of the visitor (or similar) pattern (most likely useful in complicated
cases).
M5-2-3Advisory · Automated✓ compilable📄 공식 예제Official example
Casts from a base class to a derived class should not be performed on polymorphic types.Casts from a base class to a derived class should not be performed on polymorphic types.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-2-3: Casts from a base class to a derived class should not be performed on polymorphic types. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: T ype is polymorphic if it declares or inherits at least one virtual function.See MISRA C++ 2008 [7]
Note: T ype is polymorphic if it declares or inherits at least one virtual function.
M5-2-6Required · Automated✓ compilable📄 공식 예제Official example
A cast shall not convert a pointer to a function to any other pointer type, including a pointer to function type.A cast shall not convert a pointer to a function to any other pointer type, including a pointer to function type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-2-6: A cast shall not convert a pointer to a function to any other pointer type, including a pointer to function type. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-2-9Required · Automated✓ compilable📄 공식 예제Official example
A cast shall not convert a pointer type to an integral type. --- PAGE 102 ---A cast shall not convert a pointer type to an integral type. --- PAGE 102 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-2-9: A cast shall not convert a pointer type to an integral type. --- PAGE 102 --- // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Obligation level changed.See MISRA C++ 2008 [7]
Note: Obligation level changed.
M5-3-1Required · Automated✓ compilable📄 공식 예제Official example
Each operand of the ! operator, the logical && or the logical || operators shall have type bool.Each operand of the ! operator, the logical && or the logical || operators shall have type bool.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-3-1: Each operand of the ! operator, the logical && or the logical || operators shall have type bool. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-3-2Required · Automated✓ compilable📄 공식 예제Official example
The unary minus operator shall not be applied to an expression whose underlying type is unsigned.The unary minus operator shall not be applied to an expression whose underlying type is unsigned.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-3-2: The unary minus operator shall not be applied to an expression whose underlying type is unsigned. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-3-3Required · Automated✓ compilable📄 공식 예제Official example
The unary & operator shall not be overloaded.The unary & operator shall not be overloaded.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-3-3: The unary & operator shall not be overloaded. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-3-4Required · Automated✓ compilable📄 공식 예제Official example
Evaluation of the operand to the sizeof operator shall not contain side effects.Evaluation of the operand to the sizeof operator shall not contain side effects.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-3-4: Evaluation of the operand to the sizeof operator shall not contain side effects. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M5-8-1Required · Partially automated✓ compilable📄 공식 예제Official example
The right hand operand of a shift operator shall lie between zero and one less than the width in bits of the underlying type of the left hand operand.The right hand operand of a shift operator shall lie between zero and one less than the width in bits of the underlying type of the left hand operand.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M5-8-1: The right hand operand of a shift operator shall lie between zero and one less than the width in bits of the underlying type of the left hand operand. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.5.10 Equality operatorsSee MISRA C++ 2008 [7]
6.5.10 Equality operators
A9A9 (AUTOSAR)A9 (AUTOSAR-original)
A9-3-1Required · Automated✓ compilable
멤버 함수가 내부 데이터에 대한 비-const 핸들을 반환하지 않게 한다Member functions shall not return non-const handles to class data members
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
class Buf {
std::vector<int> data_{1, 2, 3};
public:
std::vector<int>& data() { return data_; } // 내부 벡터의 수정 가능 참조 노출
};
int main() {
Buf b;
b.data().clear(); // 외부에서 내부 상태를 마음대로 변경 — 캡슐화 붕괴
std::cout << b.data().size() << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
class Buf {
std::vector<int> data_{1, 2, 3};
public:
const std::vector<int>& data() const { return data_; } // 읽기 전용 접근만
void clear() { data_.clear(); } // 동작은 명시적 메서드로
};
int main() {
Buf b;
std::cout << b.data().size() << '\n'; // 3 — 외부는 읽기만 가능
}⚠️ 근거: 멤버 함수가 내부 데이터의 비-const 참조·포인터를 반환하면, 호출자가 클래스를 거치지 않고 그 데이터를 직접 수정할 수 있어 캡슐화가 깨진다. 영향: 외부 코드가 불변식을 검증하는 메서드를 우회해 내부 상태를 바꾸면, 클래스가 유지하려던 불변식(정렬·합계 일관성 등)이 조용히 위반되어 결함을 추적하기 어려워진다. 대응: 읽기 접근은 const 핸들만 반환하고, 변경은 불변식을 보장하는 전용 메서드를 통해서만 하게 한다.Rationale: when a member function returns a non-const reference or pointer to internal data, callers can modify that data directly without going through the class, breaking encapsulation. Impact: external code that bypasses the validating methods to change internal state silently violates the invariants the class tries to maintain (ordering, sum consistency), making defects hard to trace. Fix: return only const handles for read access and route all changes through dedicated methods that preserve the invariants.
A9-5-1Required · Automated✓ compilable
union 대신 std::variant 를 사용한다Unions shall not be used; use std::variant instead
❌ 위반 예시Non-compliant example
#include <iostream>
union Value { int i; double d; }; // 어느 멤버가 활성인지 추적 불가
int main() {
Value v; v.i = 42; // i 를 활성화
std::cout << v.d << '\n'; // 비활성 멤버 d 읽기 — 미정의 동작(타입 퍼닝)
}✅ 준수 예시Compliant example
#include <iostream>
#include <variant>
using Value = std::variant<int, double>; // 현재 타입을 스스로 추적
int main() {
Value v = 42; // int 보유
if (std::holds_alternative<int>(v))
std::cout << std::get<int>(v) << '\n'; // 잘못된 타입 접근은 예외로 차단
}⚠️ 근거: union 은 모든 멤버가 같은 메모리를 공유하지만 현재 어떤 멤버가 유효한지(활성 멤버)를 스스로 기록하지 않는다. 영향: 한 멤버에 쓰고 다른 멤버로 읽으면(타입 퍼닝) 미정의 동작이며, 활성 멤버를 잘못 추적하면 쓰레기 값·크래시가 나는데 컴파일러는 이를 막아주지 못한다. 대응: 활성 타입을 스스로 추적하고 잘못된 접근을 예외로 막는 std::variant 를 사용한다.Rationale: a union shares one memory for all members but does not itself record which member is currently valid (the active member). Impact: writing one member and reading another (type punning) is undefined behaviour, and mistracking the active member yields garbage or crashes, which the compiler cannot prevent. Fix: use std::variant, which tracks the active type itself and blocks wrong accesses with an exception.
A9-6-1Required · Partially automated✓ compilable📄 공식 예제Official example
Data types used for interfacing with hardware or conforming to communication protocols shall be trivial, standard-layout and only contain members of types with defined sizes.Data types used for interfacing with hardware or conforming to communication protocols shall be trivial, standard-layout and only contain members of types with defined sizes.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A9-6-1.cpp 319312 2018-05-15 08:29:17Z christof.meerwald $
#include <cstdint>
enum class E1 : std::uint8_t
{
E11,
E12,
E13
};
enum class E2 : std::int16_t
{
E21,
E22,
E23
};
enum class E3
{
E31,
E32,
E33
};
enum E4
{
E41,
E42,
E43
};
class C
{
public:
std::int32_t a : 2; // Compliant
std::uint8_t b : 2U; // Compliant
bool c : 1; // Non-compliant - the size of bool is implementation defined
char d : 2; // Non-compliant
wchar_t e : 2; // Non-compliant - the size of wchar_t is implementation
defined
E1 f1 : 2; // Compliant
E2 f2 : 2; // Compliant
E3 f3 : 2; // Non-compliant - E3 enum class does not explicitly define
// underlying type
E4 f4 : 2; // Non-compliant - E4 enum does not explicitly define underlying
// type
};
struct D
{
std::int8_t a; // Compliant
bool b; // Non-compliant - the size of bool is
// implementation defined
std::uint16_t c1 : 8; // Compliant
std::uint16_t c2 : 8; // Compliant
};
void Fn() noexcept
{
C c;
c.f1 = E1::E11;
}⚠️ When the layout of data types is important, only those types that have a defined
size shall be used (see A3-9-1, this excludes bool, wchar_t, pointers, and pointers
to members). Enumeration types may be used if they have been explicitly declared
with an underlying type that has a defined size.
Note: As the use of bit-fields is only allowed for interfacing with hardware or conforming
to communication protocols, this restriction on types also applies to bit-fields, see A9-
6-2.
Note: The signed exact-width integer types like std::int16_t are guaranteed to have
a two’s complement representation.
See also:
• MISRA C++ 2008 [7]: A9-6-2: Bit-fields shall be either bool type or an explicitly
unsigned or signed integral type
• JSF December 2005 [8]: AV Rule 154: Bit-fields shall have explicitly unsigned
integral or enumeration types only
• HIC++ v4.0 [9]: 9.2.1: Declare bit-fields with an explicitly unsigned integral or
enumeration typeWhen the layout of data types is important, only those types that have a defined
size shall be used (see A3-9-1, this excludes bool, wchar_t, pointers, and pointers
to members). Enumeration types may be used if they have been explicitly declared
with an underlying type that has a defined size.
Note: As the use of bit-fields is only allowed for interfacing with hardware or conforming
to communication protocols, this restriction on types also applies to bit-fields, see A9-
6-2.
Note: The signed exact-width integer types like std::int16_t are guaranteed to have
a two’s complement representation.
See also:
• MISRA C++ 2008 [7]: A9-6-2: Bit-fields shall be either bool type or an explicitly
unsigned or signed integral type
• JSF December 2005 [8]: AV Rule 154: Bit-fields shall have explicitly unsigned
integral or enumeration types only
• HIC++ v4.0 [9]: 9.2.1: Declare bit-fields with an explicitly unsigned integral or
enumeration type
A9-6-2Required · Non-automated✓ compilable📄 공식 예제Official example
Bit-fields shall be used only when interfacing to hardware or conforming to communication protocols. --- PAGE 186 ---Bit-fields shall be used only when interfacing to hardware or conforming to communication protocols. --- PAGE 186 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A9-6-2: Bit-fields shall be used only when interfacing to hardware or conforming to communication protocols. --- PAGE 186 --- // No code example provided in the official guideline PDF.
⚠️ Usage of bit-fields increases code complexity and certain aspects of bit-field
manipulation can be error prone and implementation-defined. Hence a bit-field usage
is reserved only when interfacing to hardware or conformance to communication
protocols
Note: A9-6-1 restricts the types allowed to be used in these contexts.
See also:
• JSF December 2005 [8]: AV Rule 155: Bit-fields will not be used to pack data into
a word for the sole purpose of saving space.Usage of bit-fields increases code complexity and certain aspects of bit-field
manipulation can be error prone and implementation-defined. Hence a bit-field usage
is reserved only when interfacing to hardware or conformance to communication
protocols
Note: A9-6-1 restricts the types allowed to be used in these contexts.
See also:
• JSF December 2005 [8]: AV Rule 155: Bit-fields will not be used to pack data into
a word for the sole purpose of saving space.
A10A10 (AUTOSAR)A10 (AUTOSAR-original)
A10-2-1Required · Automated✓ compilable
파생 클래스에서 비가상 멤버 함수를 재정의(hide)하지 않는다Non-virtual member functions shall not be redefined in derived classes
❌ 위반 예시Non-compliant example
#include <iostream>
struct Base { void f() { std::cout << "Base::f\n"; } }; // 비가상
struct Derived : Base { void f() { std::cout << "Derived::f\n"; } }; // 이름 숨김
int main() {
Derived d;
Base& b = d;
b.f(); // 정적 타입이 Base → Base::f (다형성 아님, 직관과 다름)
}✅ 준수 예시Compliant example
#include <iostream>
struct Base { virtual void f() { std::cout << "Base::f\n"; } };
struct Derived : Base { void f() override { std::cout << "Derived::f\n"; } };
int main() {
Derived d;
Base& b = d;
b.f(); // 가상 디스패치 → Derived::f (의도대로)
}⚠️ 근거: 기반 클래스의 비가상 함수를 파생 클래스에서 같은 이름으로 다시 정의하면, 다형적 재정의(override)가 아니라 단순한 이름 숨김(name hiding)이 되어 호출되는 함수가 객체의 동적 타입이 아닌 정적 타입에 따라 결정된다. 영향: 기반 참조·포인터로 호출하면 파생 버전이 아닌 기반 버전이 불려, 다형성을 기대한 코드가 조용히 잘못된 동작을 한다. 대응: 다형성이 필요하면 기반 함수를 virtual 로 선언하고 파생에서 override 로 재정의하며, 다형성이 불필요하면 이름을 숨기지 않도록 다른 이름을 쓴다.Rationale: redefining a base non-virtual function with the same name in a derived class is not polymorphic overriding but mere name hiding, so the function called is chosen by the static type of the object rather than its dynamic type. Impact: a call through a base reference or pointer invokes the base version instead of the derived one, so code expecting polymorphism silently misbehaves. Fix: when polymorphism is needed declare the base function virtual and override it in the derived class, and when it is not, avoid hiding by using a different name.
A10-3-1Required · Automated✓ compilable
가상 함수 선언에 virtual/override/final 중 정확히 하나만 사용한다Virtual function declaration shall contain exactly one of the three specifiers
❌ 위반 예시Non-compliant example
#include <iostream>
struct B { virtual void f() { std::cout << "B\n"; } };
struct D : B {
virtual void f() override { std::cout << "D\n"; } // virtual + override 중복
};
int main() { D d; d.f(); }✅ 준수 예시Compliant example
#include <iostream>
struct B { virtual void f() { std::cout << "B\n"; } };
struct D : B {
void f() override { std::cout << "D\n"; } // override 만 — 재정의 의도 명확
};
int main() { D d; d.f(); }⚠️ 근거: 재정의 함수에 virtual 과 override 를 함께 쓰면 의미가 중복되고(virtual 은 이미 기반에서 결정됨), 어떤 의도(새 가상 함수인지 재정의인지)인지 모호해진다. 영향: 일관성이 없는 표기는 독자에게 혼란을 주고, 새 가상 함수와 재정의를 구분하기 어렵게 해 유지보수 실수를 부른다. 대응: 새로 도입하는 가상 함수에는 virtual 만, 재정의에는 override 만, 더 이상 재정의 불가로 봉인할 때는 final 만 사용한다.Rationale: combining virtual and override on a redefining function is redundant (virtual is already determined by the base) and obscures whether the intent is a new virtual function or an override. Impact: inconsistent notation confuses readers and makes it hard to distinguish new virtual functions from overrides, inviting maintenance mistakes. Fix: use virtual alone on a newly introduced virtual function, override alone on a redefinition, and final alone when sealing against further overriding.
A10-3-2Required · Automated✓ compilable
재정의하는 모든 가상 함수에 override 를 표시한다Each overriding virtual function shall be declared with the override specifier
❌ 위반 예시Non-compliant example
#include <iostream>
struct B { virtual void f(int) { std::cout << "B::f(int)\n"; } };
struct D : B {
void f(long) { std::cout << "D::f(long)\n"; } // 시그니처 다름 → 재정의 아님(새 함수)
};
int main() {
D d; B& b = d;
b.f(1); // B::f(int) 호출 — 재정의로 믿었다면 조용한 버그
}✅ 준수 예시Compliant example
#include <iostream>
struct B { virtual void f(int) { std::cout << "B::f(int)\n"; } };
struct D : B {
void f(int) override { std::cout << "D::f(int)\n"; } // override → 시그니처 검증
};
int main() {
D d; B& b = d;
b.f(1); // D::f(int) 호출 — 의도대로 재정의
}⚠️ 근거: override 지정자는 그 함수가 기반 클래스의 가상 함수를 실제로 재정의하는지 컴파일러가 검증하게 한다. 영향: override 를 빠뜨리고 시그니처가 미세하게 다르면(f(int) 대 f(long)) 재정의가 아니라 별개의 새 함수가 만들어지는데 컴파일러가 경고하지 않아, 기반 포인터 호출이 엉뚱한 함수로 가는 조용한 버그가 된다. 대응: 재정의하는 모든 가상 함수에 override 를 붙여 시그니처 불일치를 컴파일 오류로 잡는다.Rationale: the override specifier makes the compiler verify that a function actually overrides a base-class virtual function. Impact: omitting override with a slightly different signature (f(int) vs f(long)) creates a separate new function instead of an override, with no warning, so a base-pointer call goes to the wrong function — a silent bug. Fix: add override to every overriding virtual function so a signature mismatch becomes a compile error.
A10-0-1Required · Non-automated✓ compilable📄 공식 예제Official example
Public inheritance shall be used to implement “is-a” relationship.Public inheritance shall be used to implement “is-a” relationship.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A10-0-1: Public inheritance shall be used to implement "is-a" relationship. // No code example provided in the official guideline PDF.
⚠️ Public and non-public inheritance have a very different application and it shall be used
accordingly .
See: Is-a-relationship, Has-a-relationship
See also:
• JSF December 2005 [8]: AV Rule 91: Public inheritance will be used to implement
“is-a” relationships.Public and non-public inheritance have a very different application and it shall be used
accordingly .
See: Is-a-relationship, Has-a-relationship
See also:
• JSF December 2005 [8]: AV Rule 91: Public inheritance will be used to implement
“is-a” relationships.
A10-0-2Required · Non-automated✓ compilable📄 공식 예제Official example
Membership or non-public inheritance shall be used to implement “has-a” relationship.Membership or non-public inheritance shall be used to implement “has-a” relationship.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A10-0-2: Membership or non-public inheritance shall be used to implement "has-a" relationship. // No code example provided in the official guideline PDF.
⚠️ Public and non-public inheritance have a very different application and it shall be used
accordingly .
See: Is-a-relationship, Has-a-relationship
See also:
• JSF December 2005 [8]: AV Rule 93: “has-a” or “is-implemented-in-terms-of”
relationships will be modeled through membership or non-public inheritance.
6.10.1 Multiple base ClassesPublic and non-public inheritance have a very different application and it shall be used
accordingly .
See: Is-a-relationship, Has-a-relationship
See also:
• JSF December 2005 [8]: AV Rule 93: “has-a” or “is-implemented-in-terms-of”
relationships will be modeled through membership or non-public inheritance.
6.10.1 Multiple base Classes
A10-1-1Required · Automated✓ compilable📄 공식 예제Official example
Class shall not be derived from more than one base class which is not an interface class.Class shall not be derived from more than one base class which is not an interface class.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A10-1-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
class A
{
public:
void F1() noexcept(false) {}
private:
std::int32_t x{0};
std::int32_t y{0};
};
class B
{
public:
void F2() noexcept(false) {}
private:
std::int32_t x{0};
};
class C : public A,
public B // Non-compliant - A and B are both not interface classes
{
};
class D
{
public:
virtual ~D() {}
virtual void F3() noexcept = 0;
virtual void F4() noexcept = 0;
};
class E
{
public:
static constexpr std::int32_t value{10};
virtual ~E() {}
virtual void F5() noexcept = 0;
};
class F : public A,
public B,
public D,
public E // Non-compliant - A and B are both not interface classes
{
};
class G : public A,
public D,
public E // Compliant - D and E are interface classes
{
};⚠️ Multiple inheritance exposes derived class to multiple implementations. This makes
the code more difficult to maintain.
See: Diamond-Problem, Interface-Class
See also:
• JSF December 2005 [8]: AV Rule 88 Multiple inheritance shall only be allowed in
the following restricted form: n interfaces plus m private implementations, plus at
most one protected implementation.
• HIC++ v4.0 [9]: 10.3.1 Ensure that a derived class has at most one base class
which is not an interface class.
• C++ Core Guidelines [11]: C.135: Use multiple inheritance to represent multiple
distinct interfaces.Multiple inheritance exposes derived class to multiple implementations. This makes
the code more difficult to maintain.
See: Diamond-Problem, Interface-Class
See also:
• JSF December 2005 [8]: AV Rule 88 Multiple inheritance shall only be allowed in
the following restricted form: n interfaces plus m private implementations, plus at
most one protected implementation.
• HIC++ v4.0 [9]: 10.3.1 Ensure that a derived class has at most one base class
which is not an interface class.
• C++ Core Guidelines [11]: C.135: Use multiple inheritance to represent multiple
distinct interfaces.
A10-3-3Required · Automated✓ compilable📄 공식 예제Official example
Virtual functions shall not be introduced in a final class.Virtual functions shall not be introduced in a final class.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A10-3-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
class A
{
public:
virtual ~A() = default;
virtual void F() noexcept = 0;
virtual void G() noexcept {}
};
class B final : public A
{
public:
void F() noexcept final // Compliant
{
}
void G() noexcept override // Non-compliant
{
}
virtual void H() noexcept = 0; // Non-compliant
virtual void Z() noexcept // Non-compliant
{
}
};⚠️ Declaring a class as final explicitly specifies that the class cannot be inherited.
Declaring a virtual function inside a class specifies that the function can be overridden
in the inherited class, which is inconsistent.
See also:
• HIC++ v4.0 [9]: 9.1.5 Do not introduce virtual functions in a final class.Declaring a class as final explicitly specifies that the class cannot be inherited.
Declaring a virtual function inside a class specifies that the function can be overridden
in the inherited class, which is inconsistent.
See also:
• HIC++ v4.0 [9]: 9.1.5 Do not introduce virtual functions in a final class.
A10-3-5Required · Automated✓ compilable📄 공식 예제Official example
A user-defined assignment operator shall not be virtual.A user-defined assignment operator shall not be virtual.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A10-3-4.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
class A
{
public:
virtual A& operator=(A const& oth) = 0; // Non-compliant
virtual A& operator+=(A const& rhs) = 0; // Non-compliant
};
class B : public A
{
public:
B& operator=(A const& oth) override // It needs to take an argument of type
// A& in order to override
{
return *this;
}
B& operator+=(A const& oth) override // It needs to take an argument of
// type A& in order to override
{
return *this;
}
B& operator-=(B const& oth) // Compliant
{
return *this;
}
};
class C : public A
{
public:
C& operator=(A const& oth) override // It needs to take an argument of type
// A& in order to override
{
return *this;
}
C& operator+=(A const& oth) override // It needs to take an argument of
// type A& in order to override
{
return *this;
}
C& operator-=(C const& oth) // Compliant
{
return *this;
}
};
// class D : public A
//{
// public:
// D& operator=(D const& oth) override // Compile time error - this method
// does not override because of different
// signature
// {
// return *this;
// }
// D& operator+=(D const& oth) override // Compile time error - this method
// does not override because of different
// signature
// {
// return *this;
// }
//};
void Fn() noexcept
{
B b;
C c;
b = c; // Calls B::operator= and accepts an argument of type C
b += c; // Calls B::operator+= and accepts an argument of type C
c = b; // Calls C::operator= and accepts an argument of type B
c += b; // Calls C::operator+= and accepts an argument of type B
// b -= c; // Compilation error, because of types mismatch. Expected
// behavior
// c -= b; // Compilation error, because of types mismatch. Expected
// behavior
B b2;
C c2;
b -= b2;
c -= c2;
}⚠️ If an overloaded operator is declared virtual in a base class A, then in its subclasses
B and C identical arguments list needs to be provided for the overriders. This allows
to call an assignment operator of class B that takes an argument of type C which may
lead to undefined behavior.
Note that this rule applies to all assignment operators, as well to copy and move
assignment operators.
See also:
• noneIf an overloaded operator is declared virtual in a base class A, then in its subclasses
B and C identical arguments list needs to be provided for the overriders. This allows
to call an assignment operator of class B that takes an argument of type C which may
lead to undefined behavior.
Note that this rule applies to all assignment operators, as well to copy and move
assignment operators.
See also:
• none
A10-4-1Advisory · Non-automated✓ compilable📄 공식 예제Official example
Hierarchies should be based on interface classes.Hierarchies should be based on interface classes.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A10-4-1: Hierarchies should be based on interface classes. // No code example provided in the official guideline PDF.
⚠️ Software design that provides common and standardized interfaces without committing
to a particular implementation:
• eliminates of potential redundancy .
• increases software reusability .
• hides implementation details.
• can be easily extended.
• facilitates different objects iteration.
Well-defined interfaces are less prone to require further reworking and maintenance.
See: Interface-Class
See also:
• JSF December 2005 [8]: AV Rule 87: Hierarchies should be based on abstract
classes.
• C++ Core Guidelines [11]: I.25: Prefer abstract classes as interfaces to class
hierarchies.
• C++ Core Guidelines [11]: C.122: Use abstract classes as interfaces when
complete separation of interface and implementation is needed.
6.11 Member access control
6.11.0 GeneralSoftware design that provides common and standardized interfaces without committing
to a particular implementation:
• eliminates of potential redundancy .
• increases software reusability .
• hides implementation details.
• can be easily extended.
• facilitates different objects iteration.
Well-defined interfaces are less prone to require further reworking and maintenance.
See: Interface-Class
See also:
• JSF December 2005 [8]: AV Rule 87: Hierarchies should be based on abstract
classes.
• C++ Core Guidelines [11]: I.25: Prefer abstract classes as interfaces to class
hierarchies.
• C++ Core Guidelines [11]: C.122: Use abstract classes as interfaces when
complete separation of interface and implementation is needed.
6.11 Member access control
6.11.0 General
A11A11 (AUTOSAR)A11 (AUTOSAR-original)
A11-3-1Required · Automated✓ compilable
friend 선언을 사용하지 않는다Friend declarations shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
class Account {
friend class Auditor; // Auditor 에 내부를 통째로 개방 — 캡슐화 우회
double balance_ = 100.0;
};
class Auditor {
public:
double peek(const Account& a) { return a.balance_; } // private 직접 접근
};
int main() { Account a; Auditor au; std::cout << au.peek(a) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
class Account {
double balance_ = 100.0;
public:
double balance() const { return balance_; } // 명시적 공개 인터페이스
};
class Auditor {
public:
double peek(const Account& a) { return a.balance(); } // 공개 API 만 사용
};
int main() { Account a; Auditor au; std::cout << au.peek(a) << '\n'; }⚠️ 근거: friend 선언은 다른 클래스·함수에 private/protected 멤버 전체를 개방해 접근 제어를 우회한다. 영향: friend 관계는 두 클래스를 강하게 결합시켜, 한쪽의 내부 표현을 바꾸면 friend 도 함께 깨지고, 캡슐화로 보호하려던 불변식을 외부가 직접 위반할 수 있게 만든다. 대응: 필요한 협력은 의도를 드러내는 명시적 공개 인터페이스(접근자·동작 메서드)로 제공하고 friend 의존을 제거한다.Rationale: a friend declaration opens all private/protected members to another class or function, bypassing access control. Impact: a friend relationship tightly couples two classes, so changing the internal representation of one breaks the friend too, and it lets outside code directly violate invariants that encapsulation was meant to protect. Fix: provide needed collaboration through an intent-revealing public interface (accessors, action methods) and remove the friend dependency.
A11-0-1Advisory · Automated✓ compilable📄 공식 예제Official example
A non-POD type should be defined as class.A non-POD type should be defined as class.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <algorithm> // $Id: A11-0-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #include <cstdint> #include <limits> class A // Compliant - A provides user-defined constructors, invariant and // interface { std::int32_t x; // Data member is private by default public: static constexpr std::int32_t maxValue = std::numeric_limits<std::int32_t>::max(); A() : x(maxValue) {} explicit A(std::int32_t number) : x(number) {} A(A const&) = default; A(A&&) = default; A& operator=(A const&) = default; A& operator=(A&&) = default; std::int32_t GetX() const noexcept { return x; } void SetX(std::int32_t number) noexcept { x = number; } }; struct B // Non-compliant - non-POD type defined as struct { public: static constexpr std::int32_t maxValue = std::numeric_limits<std::int32_t>::max(); B() : x(maxValue) {} explicit B(std::int32_t number) : x(number) {} B(B const&) = default; B(B&&) = default; B& operator=(B const&) = default; B& operator=(B&&) = default; std::int32_t GetX() const noexcept { return x; } void SetX(std::int32_t number) noexcept { x = number; } private: std::int32_t x; // Need to provide private access specifier for x member }; struct C // Compliant - POD type defined as struct { std::int32_t x; std::int32_t y; }; class D // Compliant - POD type defined as class, but not compliant with // M11-0-1 { public: std::int32_t x; std::int32_t y; };
⚠️ Types that are not POD types are supposed to be defined as class objects, as a class
specifier forces the type to provide private access control for all its members by default.
This is consistent with developer expectations, because it is expected that a class has
its invariant, interface and could provide custom-defined constructors.
See also:
• C++ Core Guidelines [11]: C.2: Use class if the class has an invariant; use struct
if the data members can vary independently .
• stackoverflow.com [17]: When should you use a class vs a struct in C++?Types that are not POD types are supposed to be defined as class objects, as a class
specifier forces the type to provide private access control for all its members by default.
This is consistent with developer expectations, because it is expected that a class has
its invariant, interface and could provide custom-defined constructors.
See also:
• C++ Core Guidelines [11]: C.2: Use class if the class has an invariant; use struct
if the data members can vary independently .
• stackoverflow.com [17]: When should you use a class vs a struct in C++?
A11-0-2Required · Automated✓ compilable📄 공식 예제Official example
A type defined as struct shall: (1) provide only public data members, (2) not provide any special member functions or methods, (3) not be a base of another struct or class, (4) not inherit from another struct or class.A type defined as struct shall: (1) provide only public data members, (2) not provide any special member functions or methods, (3) not be a base of another struct or class, (4) not inherit from another struct or class.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A11-0-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #include <cstdint> struct A // Compliant { std::int32_t x; double y; }; struct B // Compliant { std::uint8_t x; A a; }; struct C // Compliant { float x = 0.0f; std::int32_t y = 0; std::uint8_t z = 0U; }; struct D // Non-compliant { public: std::int32_t x; protected: std::int32_t y; private: std::int32_t z; }; struct E // Non-compliant { public: std::int32_t x; void Fn() noexcept {} private: void F1() noexcept(false) {} }; struct F : public D // Non-compliant { };
⚠️ This is consistent with developer expectations that a class provides its invariant,
interface and encapsulation guarantee, while a struct is only an aggregate without any
class-like features.
An example of a struct type is POD type.
See: POD-type.
See also:
• stackoverflow.com [17]: When should you use a class vs a struct in C++?
6.11.3 FriendsThis is consistent with developer expectations that a class provides its invariant,
interface and encapsulation guarantee, while a struct is only an aggregate without any
class-like features.
An example of a struct type is POD type.
See: POD-type.
See also:
• stackoverflow.com [17]: When should you use a class vs a struct in C++?
6.11.3 Friends
A12A12 (AUTOSAR)A12 (AUTOSAR-original)
A12-0-1Required · Automated✓ compilable
특수 멤버 중 하나를 정의하면 모두 정의하거나 모두 생략한다(Rule of Five/Zero)If a class declares any of the special member functions, it shall declare all of them
❌ 위반 예시Non-compliant example
#include <iostream>
class R {
int* p_;
public:
explicit R(int v) : p_(new int(v)) {}
~R() { delete p_; } // 소멸자만 정의 → 복사 생성/대입은 얕은 복사 → 이중 해제
int get() const { return *p_; }
};
int main() {
R a(5);
R b = a; // 컴파일러 생성 복사 — p_ 포인터만 복사, a/b 가 같은 메모리 소유
std::cout << b.get() << '\n';
} // a, b 소멸 시 같은 p_ 를 두 번 delete — 힙 손상✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
class R {
std::unique_ptr<int> p_; // Rule of Zero — 소유권을 스마트포인터에 위임
public:
explicit R(int v) : p_(std::make_unique<int>(v)) {}
int get() const { return *p_; }
};
int main() {
R a(5);
// R b = a; // unique_ptr 이 복사 불가 → 얕은 복사 자체가 컴파일 차단
std::cout << a.get() << '\n';
}⚠️ 근거: 소멸자·복사 생성자·복사 대입·이동 생성자·이동 대입은 자원 관리에서 한 묶음으로 동작하며, 하나만 사용자 정의하면 나머지는 컴파일러가 생성한 얕은(멤버별) 버전을 쓴다. 영향: 소멸자만 정의해 raw 포인터를 해제하면, 얕은 복사로 두 객체가 같은 포인터를 소유해 소멸 시 이중 해제로 힙이 손상된다. 대응: 다섯 특수 멤버를 모두 일관되게 정의하거나(Rule of Five), 더 나아가 자원을 스마트 포인터·컨테이너에 위임해 특수 멤버를 아예 선언하지 않는다(Rule of Zero).Rationale: the destructor, copy constructor, copy assignment, move constructor, and move assignment work together for resource management, and defining only one leaves the rest as compiler-generated shallow (member-wise) versions. Impact: defining only a destructor that frees a raw pointer means a shallow copy lets two objects own the same pointer, double-freeing and corrupting the heap on destruction. Fix: define all five special members consistently (Rule of Five), or better, delegate resources to smart pointers/containers and declare none of them (Rule of Zero).
A12-1-1Required · Automated✓ compilable
생성자는 모든 기반 클래스와 비정적 멤버를 명시적으로 초기화한다Constructors shall explicitly initialize all virtual base classes, all direct non-virtual base classes and all non-static data members
❌ 위반 예시Non-compliant example
#include <iostream>
class P {
int x_;
int y_;
public:
P() { x_ = 0; } // y_ 를 초기화하지 않음 → 불확정 값
void print() const { std::cout << x_ << ' ' << y_ << '\n'; }
};
int main() { P p; p.print(); } // y_ 는 쓰레기 값✅ 준수 예시Compliant example
#include <iostream>
class P {
int x_;
int y_;
public:
P() : x_{0}, y_{0} {} // 모든 멤버를 초기화 목록에서 명시 초기화
void print() const { std::cout << x_ << ' ' << y_ << '\n'; }
};
int main() { P p; p.print(); } // 0 0⚠️ 근거: 생성자가 어떤 비정적 멤버를 초기화 목록에서도 본문에서도 초기화하지 않으면, 기본 타입 멤버는 불확정 값으로 남는다. 영향: 미초기화 멤버를 읽으면 미정의 동작이 되어, 디버그에서는 우연히 0 이 나오다 릴리스에서 다른 값이 나오는 재현 어려운 버그가 된다. 대응: 모든 기반 클래스와 멤버를 생성자 초기화 목록에서 명시적으로 초기화하고(가능하면 기본 멤버 초기자도 활용), 컴파일러 경고(-Weffc++ 등)를 켠다.Rationale: if a constructor initializes some non-static member neither in the initializer list nor in the body, a fundamental-type member is left with an indeterminate value. Impact: reading an uninitialized member is undefined behaviour, producing a hard-to-reproduce bug that incidentally reads 0 in debug but differs in release. Fix: explicitly initialize all base classes and members in the constructor initializer list (also using default member initializers where possible) and enable compiler warnings.
A12-1-4Required · Automated✓ compilable
단일 인자 생성자는 explicit 로 선언한다All constructors that are callable with a single argument shall be declared explicit
❌ 위반 예시Non-compliant example
#include <iostream>
struct Meters { double v; Meters(double x) : v(x) {} }; // 암시적 변환 허용
static void travel(Meters m) { std::cout << m.v << "m\n"; }
int main() {
travel(3.0); // double 3.0 이 조용히 Meters 로 변환 — 단위 혼동 위험
}✅ 준수 예시Compliant example
#include <iostream>
struct Meters { double v; explicit Meters(double x) : v(x) {} }; // 명시적 생성만
static void travel(Meters m) { std::cout << m.v << "m\n"; }
int main() {
travel(Meters{3.0}); // 의도를 분명히 — 단위를 명시적으로 감쌈
}⚠️ 근거: 단일 인자로 호출 가능한 생성자가 explicit 가 아니면, 컴파일러가 그 인자 타입을 클래스 타입으로 암시적으로 변환하는 경로를 열어준다. 영향: 함수 인자·반환·대입 등 예상치 못한 곳에서 double 이 Meters 로 조용히 바뀌어, 단위·의미가 다른 값이 섞이거나 오버로드 해석이 의도와 달라진다. 대응: 단일 인자 생성자를 explicit 로 선언해 변환을 명시적 생성으로만 제한한다(의도적 암시 변환은 드물게 문서화해 둔다).Rationale: a constructor callable with a single argument that is not explicit opens a path for the compiler to implicitly convert that argument type into the class type. Impact: in unexpected places like function arguments, returns, or assignment, a double silently becomes a Meters, mixing values of different units or meanings and skewing overload resolution. Fix: declare single-argument constructors explicit to restrict conversion to explicit construction only (documenting the rare intentional implicit conversion).
A12-8-1Required · Automated✓ compilable
이동/복사 연산은 이동/복사 외의 부작용을 갖지 않는다Move and copy constructors shall move and respectively copy base classes and data members without any side effects
❌ 위반 예시Non-compliant example
#include <iostream>
static int g_copies = 0;
struct S {
int v;
S(int v) : v(v) {}
S(const S& o) : v(o.v) { ++g_copies; } // 복사에 전역 카운터 부작용
};
static S make() { return S(7); }
int main() {
S a = make(); // 복사 생략(RVO)으로 복사 생성자 호출이 0 회일 수 있음
std::cout << "copies=" << g_copies << '\n'; // 0? 1? 최적화에 따라 달라짐
}✅ 준수 예시Compliant example
#include <iostream>
struct S {
int v;
S(int v) : v(v) {}
S(const S& o) : v(o.v) {} // 복사 의미만 — 관찰 가능한 부작용 없음
};
static S make() { return S(7); }
int main() {
S a = make();
std::cout << a.v << '\n'; // 7 — 복사 횟수와 무관하게 결과 일정
}⚠️ 근거: 컴파일러는 복사 생략(copy elision/RVO)으로 복사·이동 생성자 호출을 합법적으로 제거할 수 있어, 그 호출 횟수는 관찰 가능한 보장이 아니다. 영향: 복사·이동 연산에 로깅·카운팅·자원 등록 같은 부작용을 넣으면, 최적화 수준이나 컴파일러에 따라 그 부작용 발생 횟수가 달라져 동작이 비결정적이 된다. 대응: 복사·이동 생성자는 멤버를 복사/이동하는 의미만 구현하고, 관찰 가능한 부작용은 별도의 명시적 연산으로 분리한다.Rationale: the compiler may legally eliminate copy/move constructor calls via copy elision (RVO), so the number of such calls is not an observable guarantee. Impact: putting side effects like logging, counting, or resource registration in copy/move operations makes the count of those side effects vary by optimization level or compiler, rendering behaviour nondeterministic. Fix: implement only the copy/move semantics of members in copy/move constructors and separate any observable side effect into an explicit operation.
A12-8-3Required · Automated✓ compilable
이동된(moved-from) 객체의 값을 읽지 않는다Moved-from object shall not be read-accessed
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
#include <utility>
int main() {
std::string a = "payload";
std::string b = std::move(a); // a 는 유효하나 값은 미지정
std::cout << "a.size()=" << a.size() << '\n'; // 미지정 상태 읽기 — 비결정적
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
#include <utility>
int main() {
std::string a = "payload";
std::string b = std::move(a);
a = "reset"; // 재사용 전 명확한 값으로 재설정
std::cout << "a.size()=" << a.size() << '\n'; // 5
}⚠️ 근거: 표준 라이브러리 타입은 이동 후 "유효하지만 미지정(valid but unspecified)" 상태가 되어, 소멸·재대입은 안전하지만 그 구체적 값(길이·내용)은 보장되지 않는다. 영향: 이동된 객체의 값을 읽어 계산·분기하면 구현·최적화에 따라 결과가 달라지는 비결정적 버그가 되고, 이동을 빠뜨린 진짜 논리 오류를 가린다. 대응: 이동된 객체는 다시 대입하거나 clear() 등으로 명확한 상태로 만든 뒤에만 재사용한다.Rationale: standard-library types are left valid but unspecified after a move — destruction and reassignment are safe, but the concrete value (size, contents) is not guaranteed. Impact: reading a moved-from value to compute or branch yields nondeterministic bugs that vary by implementation/optimization and mask a real logic error of a missed move. Fix: reuse a moved-from object only after putting it in a known state, such as reassigning or calling clear().
A12-8-5Required · Automated✓ compilable
복사/이동 대입은 자기 대입(self-assignment)을 처리한다A copy assignment and a move assignment operators shall handle self-assignment
❌ 위반 예시Non-compliant example
#include <iostream>
struct S {
int* p_;
explicit S(int v) : p_(new int(v)) {}
~S() { delete p_; }
S& operator=(const S& o) {
delete p_; // o 가 this 면 자기 데이터를 먼저 해제
p_ = new int(*o.p_); // 해제된 메모리에서 복사 — use-after-free
return *this;
}
};
int main() { S a(5); a = a; std::cout << *a.p_ << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
#include <utility>
struct S {
int* p_;
explicit S(int v) : p_(new int(v)) {}
S(const S& o) : p_(new int(*o.p_)) {}
~S() { delete p_; }
S& operator=(S o) { // copy-and-swap — 자기 대입 자동 안전
std::swap(p_, o.p_);
return *this;
}
};
int main() { S a(5); a = a; std::cout << *a.p_ << '\n'; }⚠️ 근거: 복사·이동 대입에서 기존 자원을 먼저 해제한 뒤 원본을 복사하는 순서로 작성하면, 원본과 대상이 같은 객체(자기 대입)일 때 복사할 원본이 이미 해제된 상태가 된다. 영향: use-after-free 로 쓰레기 값을 읽거나 크래시가 나고, 이중 해제로 힙이 손상될 수 있다. 대응: copy-and-swap 관용구(또는 명시적 자기 검사 if (this == &o) return *this;)로 자기 대입에서도 항상 안전하게 만든다.Rationale: a copy/move assignment that frees the existing resource before copying the source breaks when source and target are the same object (self-assignment), because the source is already freed when copied. Impact: a use-after-free reads garbage or crashes, and a double free can corrupt the heap. Fix: use the copy-and-swap idiom (or an explicit self-check if (this == &o) return *this;) so self-assignment is always safe.
A12-0-2Required · Partially automated✓ compilable📄 공식 예제Official example
Bitwise operations and operations that assume data representation in memory shall not be performed on objects.Bitwise operations and operations that assume data representation in memory shall not be performed on objects.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-0-2.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
//
#include <cstdint>
#include <cstring>
class A
{
public:
A() = default;
A(uint8_t c, uint32_t i, int8_t d, int32_t h) : c(c), i(i), d(d), h(h) {}
bool operator==(const A& rhs) const noexcept
{
return c==rhs.c && i==rhs.i && d==rhs.d && h==rhs.h;
}
private:
uint8_t c;
uint32_t i;
int8_t d;
int32_t h;
};
int main(void)
{
A noninit;
//setting field c
std::memset(&noninit, 3, 1); //non-compliant
//setting field i
std::memset(((uint8_t*)&noninit)+sizeof(uint8_t)+3, 5, 1); //non-compliant
A init(3, 5, 7, 9); //compliant
if (noninit == init) //compliant
{
}
if (0 == std::memcmp(&noninit, &init, sizeof(init)))
{ //non-compliant, includes padding bytes
}
return 0;
}⚠️ Object representations may consist of more than only the declared fields (unless the
objects are standard-layout or trivially copyable). Performing bitwise operations on
objects may access bits that are not part of the value representation, which may lead
to undefined behavior. Operations on objects (e.g. initialization, copying, comparing,
setting, accessing) shall be done by dedicated constructors, overloaded operators,
accessors or mutators.
See also:
• JSF December 2005 [8]: AV Rule 156: All the members of a structure (or class)
shall be named and shall only be accessed via their names.
• JSF December 2005 [8]: AV Rule 210: Algorithms shall not make assumptions
concerning how data is represented in memory (e.g. big endian vs. little endian,
base class subobject ordering in derived classes, nonstatic data member ordering
across access specifiers, etc.)
• JSF December 2005 [8]: AV Rule 210.1: Algorithms shall not make assumptions
concerning the order of allocation of nonstatic data members separated by an
access specifier.
• JSF December 2005 [8]: AV Rule 211: Algorithms shall not assume that shorts,
ints, longs, floats, doubles or long doubles begin at particular addresses.
• SEI CERT C++ Coding Standard [10]: EXP42-C: Do not compare padding data
• SEI CERT C++ Coding Standard [10]: EXP62-C: Do not access the bits of an
object representation that are not part of the object’s value representation
• SEI CERT C++ Coding Standard [10]: OOP57-CPP: Prefer special member
functions and overloaded operators to C Standard Library functions
6.12.1 ConstructorsObject representations may consist of more than only the declared fields (unless the
objects are standard-layout or trivially copyable). Performing bitwise operations on
objects may access bits that are not part of the value representation, which may lead
to undefined behavior. Operations on objects (e.g. initialization, copying, comparing,
setting, accessing) shall be done by dedicated constructors, overloaded operators,
accessors or mutators.
See also:
• JSF December 2005 [8]: AV Rule 156: All the members of a structure (or class)
shall be named and shall only be accessed via their names.
• JSF December 2005 [8]: AV Rule 210: Algorithms shall not make assumptions
concerning how data is represented in memory (e.g. big endian vs. little endian,
base class subobject ordering in derived classes, nonstatic data member ordering
across access specifiers, etc.)
• JSF December 2005 [8]: AV Rule 210.1: Algorithms shall not make assumptions
concerning the order of allocation of nonstatic data members separated by an
access specifier.
• JSF December 2005 [8]: AV Rule 211: Algorithms shall not assume that shorts,
ints, longs, floats, doubles or long doubles begin at particular addresses.
• SEI CERT C++ Coding Standard [10]: EXP42-C: Do not compare padding data
• SEI CERT C++ Coding Standard [10]: EXP62-C: Do not access the bits of an
object representation that are not part of the object’s value representation
• SEI CERT C++ Coding Standard [10]: OOP57-CPP: Prefer special member
functions and overloaded operators to C Standard Library functions
6.12.1 Constructors
A12-1-2Required · Automated✓ compilable📄 공식 예제Official example
Both NSDMI and a non-static member initializer in a constructor shall not be used in the same type.Both NSDMI and a non-static member initializer in a constructor shall not be used in the same type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <stdexcept>
// $Id: A12-1-2.cpp 271696 2017-03-23 09:23:09Z piotr.tanski $
#include <cstdint>
#include <utility>
class A
{
public:
A() : i1{0}, i2{0} // Compliant - i1 and i2 are initialized by the
// constructor only. Not compliant with A12-1-3
{
}
// Implementation
private:
std::int32_t i1;
std::int32_t i2;
};
class B
{
public:
// Implementation
private:
std::int32_t i1{0};
std::int32_t i2{
0}; // Compliant - both i1 and i2 are initialized by NSDMI only
};
class C
{
public:
C() : i2{0} // Non-compliant - i1 is initialized by NSDMI, i2 is in
// member in member initializer list
{
}
C(C const& oth) : i1{oth.i1}, i2{oth.i2} // Compliant by exception
{
}
C(C&& oth)
: i1{std::move(oth.i1)},
i2{std::move(oth.i2)} // Compliant by exception
{
}
// Implementation
private:
std::int32_t i1{0};
std::int32_t i2;
};⚠️ Since 2011 C++ Language Standard it is allowed to initialize a non-static member
along with the declaration of the member in the class body using NSDMI (“non-static
data member initializer”). T o avoid possible confusion which values are actually used,
if any member is initialized by NSDMI or with a constructor, then all others should be
initialized the same way .
Exception:
The move and copy constructors are exempt from this rule, because these constructors
copy the existing values from other objects.
See also:
• HIC++ v4.0 [9]:12.4.3 Do not specify both an NSDMI and a member initializer in
a constructor for the same non static memberSince 2011 C++ Language Standard it is allowed to initialize a non-static member
along with the declaration of the member in the class body using NSDMI (“non-static
data member initializer”). T o avoid possible confusion which values are actually used,
if any member is initialized by NSDMI or with a constructor, then all others should be
initialized the same way .
Exception:
The move and copy constructors are exempt from this rule, because these constructors
copy the existing values from other objects.
See also:
• HIC++ v4.0 [9]:12.4.3 Do not specify both an NSDMI and a member initializer in
a constructor for the same non static member
A12-1-3Required · Automated✓ compilable📄 공식 예제Official example
If all user-defined constructors of a class initialize data members with constant values that are the same across all constructors, then data members shall be initialized using NSDMI instead.If all user-defined constructors of a class initialize data members with constant values that are the same across all constructors, then data members shall be initialized using NSDMI instead.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-1-3.cpp 291949 2017-10-19 21:26:22Z michal.szczepankiewicz $
#include <cstdint>
#include <string>
class A
{
public:
A() : x(0), y(0.0F), str() // Non-compliant
{
}
// ...
private:
std::int32_t x;
float y;
std::string str;
};
class B
{
public:
// ...
private:
std::int32_t x = 0; // Compliant
float y = 0.0F; // Compliant
std::string str = ""; // Compliant
};
class C
{
public:
C() : C(0, 0.0F, decltype(str)()) // Compliant
{
}
C(std::int32_t i, float f, std::string s) : x(i), y(f), str(s) // Compliant
{
}
// ...
private:
std::int32_t x =
0; // Non-compliant - there's a constructor that initializes C
// class with user input
float y = 0.0F; // Non-compliant - there's a constructor that initializes C
// class with user input
std::string str = ""; // Non-compliant - there's a constructor that
// initializes C class with user input
};⚠️ Using NSDMI lets the compiler to generate the function that can be more efficient
than a user-defined constructor that initializes data member variables with pre-defined
constant values.
See also:
• C++ Core Guidelines [11]: C.45: Don’t define a default constructor that only
initializes data members; use in-class member initializers instead.Using NSDMI lets the compiler to generate the function that can be more efficient
than a user-defined constructor that initializes data member variables with pre-defined
constant values.
See also:
• C++ Core Guidelines [11]: C.45: Don’t define a default constructor that only
initializes data members; use in-class member initializers instead.
A12-1-5Required · Partially automated✓ compilable📄 공식 예제Official example
Common class initialization for non-constant members shall be done by a delegating constructor.Common class initialization for non-constant members shall be done by a delegating constructor.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-1-5.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
class A
{
public:
// Compliant
A(std::int32_t x, std::int32_t y) : x(x + 8), y(y) {}
explicit A(std::int32_t x) : A(x, 0) {}
private:
std::int32_t x;
std::int32_t y;
};
class B
{
public:
// Non-compliant
B(std::int32_t x, std::int32_t y) : x(x + 8), y(y) {}
explicit B(std::int32_t x) : x(x + 8), y(0) {}
private:
std::int32_t x;
std::int32_t y;
};⚠️ Common initialization of non-constant members in a delegating constructor prevents
from code repetition, accidental differences and maintenance problems.
See also:
• HIC++ v4.0 [9]: 12.4.5: Use delegating constructors to reduce code duplication.
• C++ Core Guidelines [11]: C.51: Use delegating constructors to represent
common actions for all constructors of a class.Common initialization of non-constant members in a delegating constructor prevents
from code repetition, accidental differences and maintenance problems.
See also:
• HIC++ v4.0 [9]: 12.4.5: Use delegating constructors to reduce code duplication.
• C++ Core Guidelines [11]: C.51: Use delegating constructors to represent
common actions for all constructors of a class.
A12-1-6Required · Automated✓ compilable📄 공식 예제Official example
Derived classes that do not need further explicit initialization and require all the constructors from the base class shall use inheriting constructors.Derived classes that do not need further explicit initialization and require all the constructors from the base class shall use inheriting constructors.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-1-6.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
class A
{
public:
A(std::int32_t x, std::int32_t y) : x(x + 8), y(y) {}
explicit A(std::int32_t x) : A(x, 0) {}
private:
std::int32_t x;
std::int32_t y;
};
// Non-compliant
class B : public A
{
public:
B(std::int32_t x, std::int32_t y) : A(x, y) {}
explicit B(std::int32_t x) : A(x) {}
};
// Compliant
class C : public A
{
public:
using A::A;
};⚠️ Reimplementing constructors that do not need further initialization is error-prone and
may lead to using wrong base class constructor accidentally .
See also:
• C++ Core Guidelines [11]: C.52: Use inheriting constructors to import
constructors into a derived class that does not need further explicit initialization.
6.12.4 DestructorsReimplementing constructors that do not need further initialization is error-prone and
may lead to using wrong base class constructor accidentally .
See also:
• C++ Core Guidelines [11]: C.52: Use inheriting constructors to import
constructors into a derived class that does not need further explicit initialization.
6.12.4 Destructors
A12-4-1Required · Automated✓ compilable📄 공식 예제Official example
Destructor of a base class shall be public virtual, public override or protected non-virtual.Destructor of a base class shall be public virtual, public override or protected non-virtual.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-4-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
class A
{
public:
~A() // Non-compliant
{
}
};
class B : public A
{
};
class C
{
public:
virtual ~C() // Compliant
{
}
};
class D : public C
{
};
class E
{
protected:
~E(); // Compliant
};
class F : public E
{
};
void F1(A * obj1, C * obj2)
{
// ...
delete obj1; // Only destructor of class A will be invoked
delete obj2; // Both destructors of D and C will be invoked
}
void F2()
{
A* a = new B;
C* c = new D;
F1(a, c);
}⚠️ If an object is supposed to be destroyed through a pointer or reference to its base
class, the destructor in the base class needs to be virtual. Otherwise, destructors for
derived types will not be invoked.
Note that if it is prohibited to destroy an object through a pointer or reference to its base
class, the destructor in the base class is supposed to be protected.
See also:
• JSF December 2005 [8]: AV Rule 78 All base classes with a virtual function shall
define a virtual destructor.
• HIC++ v4.0 [9]: 12.2.1 Declare virtual, private or protected the destructor of a
type used as a base class.
• SEI CERT C++ Coding Standard [10]: OOP52-CPP: Do not delete a polymorphic
object without a virtual destructor.
• C++ Core Guidelines [11]: C.35: A base class destructor should be either public
and virtual, or protected and nonvirtual.
• C++ Core Guidelines [11]: Discussion: Make base class destructors public and
virtual, or protected and nonvirtual.If an object is supposed to be destroyed through a pointer or reference to its base
class, the destructor in the base class needs to be virtual. Otherwise, destructors for
derived types will not be invoked.
Note that if it is prohibited to destroy an object through a pointer or reference to its base
class, the destructor in the base class is supposed to be protected.
See also:
• JSF December 2005 [8]: AV Rule 78 All base classes with a virtual function shall
define a virtual destructor.
• HIC++ v4.0 [9]: 12.2.1 Declare virtual, private or protected the destructor of a
type used as a base class.
• SEI CERT C++ Coding Standard [10]: OOP52-CPP: Do not delete a polymorphic
object without a virtual destructor.
• C++ Core Guidelines [11]: C.35: A base class destructor should be either public
and virtual, or protected and nonvirtual.
• C++ Core Guidelines [11]: Discussion: Make base class destructors public and
virtual, or protected and nonvirtual.
A12-4-2Advisory · Automated✓ compilable📄 공식 예제Official example
If a public destructor of a class is non-virtual, then the class should be declared final.If a public destructor of a class is non-virtual, then the class should be declared final.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-4-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ class A // Non-compliant - class A should not be used as a base class because // its destructor is not virtual, but it is // not declared final { public: A() = default; A(A const&) = default; A(A&&) = default; A& operator=(A const&) = default; A& operator=(A&&) = default; ~A() = default; // Public non-virtual destructor }; class B final // Compliant - class B can not be used as a base class, because // it is declared final, and it should not be derived // because its destructor is not virtual { public: B() = default; B(B const&) = default; B(B&&) = default; B& operator=(B const&) = default; B& operator=(B&&) = default; ~B() = default; // Public non-virtual destructor }; class C // Compliant - class C is not final, and its destructor is virtual. It // can be used as a base class { public: C() = default; C(C const&) = default; C(C&&) = default; C& operator=(C const&) = default; C& operator=(C&&) = default; virtual ~C() = default; // Public virtual destructor }; class AA : public A { }; // class BA : public B // Compilation error - can not derive from final base // class B //{ //}; class CA : public C { }; void Fn() noexcept { AA obj1; CA obj2; A& ref1 = obj1; C& ref2 = obj2; ref1.~A(); // Calls A::~A() only ref2.~C(); // Calls both CA::~CA() and C::~C() }
⚠️ If a public destructor of a class is non-virtual (i.e. no virtual, override or final keyword),
then the class is not supposed to be used as a base class in inheritance hierarchy .
Note that a destructor needs to be virtual in a base class in order to correctly destroy
an instance of a derived class through a pointer to the base class.
See also:
• SEI CERT C++ Coding Standard [10]: OOP52-CPP: Do not delete a polymorphic
object without a virtual destructor.
6.12.6 InitializationIf a public destructor of a class is non-virtual (i.e. no virtual, override or final keyword),
then the class is not supposed to be used as a base class in inheritance hierarchy .
Note that a destructor needs to be virtual in a base class in order to correctly destroy
an instance of a derived class through a pointer to the base class.
See also:
• SEI CERT C++ Coding Standard [10]: OOP52-CPP: Do not delete a polymorphic
object without a virtual destructor.
6.12.6 Initialization
A12-6-1Required · Automated✓ compilable📄 공식 예제Official example
All class data members that are initialized by the constructor shall be initialized using member initializers.All class data members that are initialized by the constructor shall be initialized using member initializers.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-6-1.cpp 271696 2017-03-23 09:23:09Z piotr.tanski $
#include <cstdint>
#include <string>
class A
{
public:
A(std::int32_t n, std::string s) : number{n}, str{s} // Compliant
{
}
// Implementation
private:
std::int32_t number;
std::string str;
};
class B
{
public:
B(std::int32_t n, std::string s) // Non-compliant - no member initializers
{
number = n;
str = s;
}
// Implementation
private:
std::int32_t number;
std::string str;
};
class C
{
public:
C(std::int32_t n, std::string s) : number{n}, str{s} // Compliant
{
n += 1; // This does not violate the rule
str.erase(str.begin(),
str.begin() + 1); // This does not violate the rule
}
// Implementation
private:
std::int32_t number;
std::string str;
};⚠️ Using the constructor’s member initializers is more efficient than assigning a copy
of passed values to data members in the constructor’s body . Also, it supports the
programmer to prevent “data usage before initialization” errors.
Note that if a data member is already initialized using member initializer, then changing
its value in the constructor’s body does not violate this rule.
See also:
• C++ Core Guidelines [11]: C.49: Prefer initialization to assignment in
constructors.
6.12.7 Construction and destructionsUsing the constructor’s member initializers is more efficient than assigning a copy
of passed values to data members in the constructor’s body . Also, it supports the
programmer to prevent “data usage before initialization” errors.
Note that if a data member is already initialized using member initializer, then changing
its value in the constructor’s body does not violate this rule.
See also:
• C++ Core Guidelines [11]: C.49: Prefer initialization to assignment in
constructors.
6.12.7 Construction and destructions
A12-7-1Required · Automated✓ compilable📄 공식 예제Official example
If the behavior of a user-defined special member function is identical to implicitly defined special member function, then it shall be defined “=default” or be left undefined.If the behavior of a user-defined special member function is identical to implicitly defined special member function, then it shall be defined “=default” or be left undefined.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-7-1.cpp 271715 2017-03-23 10:13:51Z piotr.tanski $
#include <cstdint>
#include <utility>
class A
{
public:
A() : x(0), y(0) {} // Compliant
A(std::int32_t first, std::int32_t second) : x(first), y(second) {} // Compliant
// -
// anyway, such
// a constructor
// cannot be
// defaulted.
A(const A& oth)
: x(oth.x),
y(oth.y) // Non-compliant - equivalent to the implicitly
// defined copy constructor
{
}
A(A&& oth)
: x(std::move(oth.x)),
y(std::move(
oth.y)) // Non-compliant - equivalent to the implicitly
// defined move constructor
{
}
~A() // Non-compliant - equivalent to the implicitly defined destructor
{
}
private:
std::int32_t x;
std::int32_t y;
};
class B
{
public:
B() {} // Non-compliant - x and y are not initialized
// should be replaced with: B() : x{0}, y{0} {}
B(std::int32_t first, std::int32_t second) : x(first), y(second) {} // Compliant
B(const B&) =
default; // Compliant - equivalent to the copy constructor of class A
B(B&&) =
default; // Compliant - equivalent to the move constructor of class A
~B() = default; // Compliant - equivalent to the destructor of class A
private:
std::int32_t x;
std::int32_t y;
};
class C
{
public:
C() = default; // Compliant
C(const C&) = default; // Compliant
C(C&&) = default; // Compliant
};
class D
{
public:
D() : ptr(nullptr) {} // Compliant - this is not equivalent to what the
// implicitly defined default constructor would do
D(C* p) : ptr(p) {} // Compliant
D(const D&) = default; // Shallow copy will be performed, user-defined copy
// constructor is needed to perform deep copy on ptr variable
D(D&&) = default; // ptr variable will be moved, so ptr will still point to
// the same object
~D() = default; // ptr will not be deleted, the user-defined destructor is
// needed to delete allocated memory
private:
C* ptr;
};
class E // Compliant - special member functions definitions are not needed as
// class E uses only implicit definitions
{
};⚠️ If a user-defined version of a special member function is the same as would be provided
by the compiler, it will be less error prone and more maintainable to replace it with
“=default” definition or leave it undefined to let the compiler define it implicitly .
Note that this rule applies to all special member functions of a class.
See: Implicitly-Defined-Default-Constructor, Implicitly-Defined-
Copy-Constructor, Implicitly-Defined-Move-Constructor,
Implicitly-Defined-Copy-Assignment-Operator, Implicitly-Defined-
Move-Assignment-Operator, Implicitly-Defined-Destructor
See also:
• HIC++ v4.0 [9]: 12.5.2 Define special members =default if the behavior is
equivalent.
• C++ Core Guidelines [11]: C.80: Use =default if you have to be explicit about
using the default semantics.
6.12.8 Copying and moving class objectsIf a user-defined version of a special member function is the same as would be provided
by the compiler, it will be less error prone and more maintainable to replace it with
“=default” definition or leave it undefined to let the compiler define it implicitly .
Note that this rule applies to all special member functions of a class.
See: Implicitly-Defined-Default-Constructor, Implicitly-Defined-
Copy-Constructor, Implicitly-Defined-Move-Constructor,
Implicitly-Defined-Copy-Assignment-Operator, Implicitly-Defined-
Move-Assignment-Operator, Implicitly-Defined-Destructor
See also:
• HIC++ v4.0 [9]: 12.5.2 Define special members =default if the behavior is
equivalent.
• C++ Core Guidelines [11]: C.80: Use =default if you have to be explicit about
using the default semantics.
6.12.8 Copying and moving class objects
A12-8-2Advisory · Automated✓ compilable📄 공식 예제Official example
User-defined copy and move assignment operators should use user-defined no-throw swap function.User-defined copy and move assignment operators should use user-defined no-throw swap function.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-8-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <utility>
class A
{
public:
A(const A& oth)
{
// ...
}
A(A&& oth) noexcept
{
// ...
}
A& operator=(const A& oth) & // Compliant
{
A tmp(oth);
Swap(*this, tmp);
return *this;
}
A& operator=(A&& oth) & noexcept // Compliant
{
A tmp(std::move(oth));
Swap(*this, tmp);
return *this;
}
static void Swap(A& lhs, A& rhs) noexcept
{
std::swap(lhs.ptr1, rhs.ptr1);
std::swap(lhs.ptr2, rhs.ptr2);
}
private:
std::int32_t* ptr1;
std::int32_t* ptr2;
};
class B
{
public:
B& operator=(const B& oth) & // Non-compliant
{
if (this != &oth)
{
ptr1 = new std::int32_t( *oth.ptr1);
ptr2 = new std::int32_t(
*oth.ptr2); // Exception thrown here results in
// a memory leak of ptr1
}
return *this;
}
B& operator=(B&& oth) & noexcept // Non-compliant
{
if (this != &oth)
{
ptr1 = std::move(oth.ptr1);
ptr2 = std::move(oth.ptr2);
oth.ptr1 = nullptr;
oth.ptr2 = nullptr;
}
return *this;
}
private:
std::int32_t* ptr1;
std::int32_t* ptr2;
};⚠️ Using a non-throwing swap operation in the copy and move assignment operators
helps to achieve Strong Exception Safety . Each assignment operator is also simplified
because it does not require check for assignment to itself.
See also:
• HIC++ v4.0 [9]: 12.5.6 Use an atomic, non-throwing swap operation to implement
the copy and move assignment operatorsUsing a non-throwing swap operation in the copy and move assignment operators
helps to achieve Strong Exception Safety . Each assignment operator is also simplified
because it does not require check for assignment to itself.
See also:
• HIC++ v4.0 [9]: 12.5.6 Use an atomic, non-throwing swap operation to implement
the copy and move assignment operators
A12-8-4Required · Automated✓ compilable📄 공식 예제Official example
Move constructor shall not initialize its class members and base classes using copy semantics.Move constructor shall not initialize its class members and base classes using copy semantics.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility>
#include <stdexcept>
// $Id: A12-8-4.cpp 271696 2017-03-23 09:23:09Z piotr.tanski $
#include <cstdint>
#include <string>
class A
{
public:
// ...
A(A&& oth)
: x(std::move(oth.x)), // Compliant
s(std::move(oth.s)) // Compliant
{
}
private:
std::int32_t x;
std::string s;
};
class B
{
public:
// ...
B(B&& oth)
: x(oth.x), // Compliant by exception, std::int32_t is of scalar
// type
s(oth.s) // Non-compliant
{
}
private:
std::int32_t x;
std::string s;
};
class C
{
public:
// ...
C(C&& oth)
: x(oth.x), // Compliant by exception
s(std::move(oth.s)) // Compliant
{
}
private:
std::int32_t x = 0;
std::string s = "Default string";
};⚠️ Data members or base classes initialization in move constructor needs to be done
with move semantics. Move construction is an optimization strategy and the copy-
initialization for data members and base classes will have negative impact on the
program’s performance, as well as it does not meet developer expectations.
Exception:
In move constructor, copy initialization for data members of scalar types does not
violate this rule.
See: Scalar-Types.
See also:
• SEI CERT C++ [10]: OOP11-CPP Do not copy-initialize members or base classes
from a move constructor.Data members or base classes initialization in move constructor needs to be done
with move semantics. Move construction is an optimization strategy and the copy-
initialization for data members and base classes will have negative impact on the
program’s performance, as well as it does not meet developer expectations.
Exception:
In move constructor, copy initialization for data members of scalar types does not
violate this rule.
See: Scalar-Types.
See also:
• SEI CERT C++ [10]: OOP11-CPP Do not copy-initialize members or base classes
from a move constructor.
A12-8-6Required · Automated✓ compilable📄 공식 예제Official example
Copy and move constructors and copy assignment and move assignment operators shall be declared protected or defined “=delete” in base class.Copy and move constructors and copy assignment and move assignment operators shall be declared protected or defined “=delete” in base class.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-8-6.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <memory>
#include <utility>
#include <vector>
class A // Abstract base class
{
public:
A() = default;
A(A const&) = default; // Non-compliant
A(A&&) = default; // Non-compliant
virtual ~A() {}
A& operator=(A const&) = default; // Non-compliant
A& operator=(A&&) = default; // Non-compliant
};
class B : public A
{
};
class C // Abstract base class
{
public:
C() = default;
virtual ~C() {}
protected:
C(C const&) = default; // Compliant
C(C&&) = default; // Compliant
C& operator=(C const&) = default; // Compliant
C& operator=(C&&) = default; // Compliant
};
class D : public C
{
};
class E // Abstract base class
{
public:
E() = default;
virtual ~E() {}
E(E const&) = delete; // Compliant
E(E&&) = delete; // Compliant
E& operator=(E const&) = delete; // Compliant
E& operator=(E&&) = delete; // Compliant
};
class F : public E
{
};
class G // Non-abstract base class
{
public:
G() = default;
virtual ~G() = default;
G(G const&) = default; // Non-compliant
G(G&&) = default; // Non-compliant
G& operator=(G const&) = default; // Non-compliant
G& operator=(G&&) = default; // Non-compliant
};
class H : public G
{
};
void Fn1() noexcept
{
B obj1;
B obj2;
A* ptr1 = &obj1;
A* ptr2 = &obj2;
*ptr1 = *ptr2; // Partial assignment only
*ptr1 = std::move( *ptr2); // Partial move only
D obj3;
D obj4;
C* ptr3 = &obj3;
C* ptr4 = &obj4;
//*ptr3 = *ptr4; // Compilation error - copy assignment operator of class C
// is protected
//*ptr3 = std::move( *ptr4); // Compilation error - move assignment operator
// of class C is protected
F obj5;
F obj6;
E* ptr5 = &obj5;
E* ptr6 = &obj6;
//*ptr5 = *ptr6; // Compilation error - use of deleted copy assignment
// operator
//*ptr5 = std::move( *ptr6); // Compilation error - use of deleted move
// assignment operator
H obj7;
H obj8;
G* ptr7 = &obj7;
G* ptr8 = &obj8;
*ptr7 = *ptr8; // Partial assignment only
*ptr7 = std::move( *ptr8); // Partial move only
}
class I // Non-abstract base class
{
public:
I() = default;
~I() = default;
protected:
I(I const&) = default; // Compliant
I(I&&) = default; // Compliant
I& operator=(I const&) = default; // Compliant
I& operator=(I&&) = default; // Compliant
};
class J : public I
{
public:
J() = default;
~J() = default;
J(J const&) = default;
J(J&&) = default;
J& operator=(J const&) = default;
J& operator=(J&&) = default;
};
void Fn2() noexcept
{
std::vector<I> v1;
// v1.push_back(J{}); // Compilation-error on calling a deleted move
// constructor of I class, slicing does not occur
// v1.push_back(I{}); // Compilation-error on calling a deleted move
// constructor of I class
std::vector<J> v2;
v2.push_back(J{}); // No compilation error
std::vector<std::unique_ptr<I>> v3;
v3.push_back(std::unique_ptr<I>{}); // No compilation error
v3.push_back(std::make_unique<I>()); // No compilation error
v3.push_back(std::make_unique<J>()); // No compilation error
v3.emplace_back(); // No compilation error
}⚠️ Invoking copy or move constructor or copy assignment or move assignment operator
from the top of a class hierarchy bypasses the underlying implementations. This results
in “slicing” where only the base sub-objects being copied or moved.
See also:
• MISRA C++ 2008 [7]: Rule 12-8-2 The copy assignment operator shall be
declared protected or private in an abstract class.
• HIC++ v4.0 [9]: 12.5.8 Make the copy assignment operator of an abstract class
protected or define it =delete.
• C++ Core Guidelines [11]: C.67: A base class should suppress copying, and
provide a virtual clone instead if "‘copying"’ is desired.
• C++ Core Guidelines [11]: C.81: Use =delete when you want to disable default
behavior (without wanting an alternative).Invoking copy or move constructor or copy assignment or move assignment operator
from the top of a class hierarchy bypasses the underlying implementations. This results
in “slicing” where only the base sub-objects being copied or moved.
See also:
• MISRA C++ 2008 [7]: Rule 12-8-2 The copy assignment operator shall be
declared protected or private in an abstract class.
• HIC++ v4.0 [9]: 12.5.8 Make the copy assignment operator of an abstract class
protected or define it =delete.
• C++ Core Guidelines [11]: C.67: A base class should suppress copying, and
provide a virtual clone instead if "‘copying"’ is desired.
• C++ Core Guidelines [11]: C.81: Use =delete when you want to disable default
behavior (without wanting an alternative).
A12-8-7Advisory · Automated✓ compilable📄 공식 예제Official example
Assignment operators should be declared with the ref-qualifier &.Assignment operators should be declared with the ref-qualifier &.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A12-8-7.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
class A
{
public:
A() = default;
A& operator *=(std::int32_t i) // Non-compliant
{
// ...
return *this;
}
};
A F1() noexcept
{
return A{};
}
class B
{
public:
B() = default;
B& operator *=(std::int32_t) & // Compliant
{
// ...
return *this;
}
};
B F2() noexcept
{
return B{};
}
std::int32_t F3() noexcept
{
return 1;
}
int main(int, char **)
{
F1() *= 10; // Temporary result of f1() multiplied by 10. No compile-time
// error.
;
// f2() *= 10; // Compile-time error due to ref-qualifier
;
// f3() *= 10; // Compile-time error on built-in type
}⚠️ User declared assignment operators differ from built-in operators in a way that they
accept rvalues as parameters, which is confusing. Adding & to the function declaration
prohibits rvalue parameters and ensures that all of the calls can only be made on lvalue
objects, which results with the same behavior as for built-in types.
Note that this rule applies to all assignment operators, e.g. operator=(), operator*=(),
operator+=.
See also:
• HIC++ v4.0 [9]: 12.5.7 Declare assignment operators with the ref-qualifier &.
• cppreference.com [16]: Assignment operators.
6.13 Overloading
6.13.1 Overloadable declarationsUser declared assignment operators differ from built-in operators in a way that they
accept rvalues as parameters, which is confusing. Adding & to the function declaration
prohibits rvalue parameters and ensures that all of the calls can only be made on lvalue
objects, which results with the same behavior as for built-in types.
Note that this rule applies to all assignment operators, e.g. operator=(), operator*=(),
operator+=.
See also:
• HIC++ v4.0 [9]: 12.5.7 Declare assignment operators with the ref-qualifier &.
• cppreference.com [16]: Assignment operators.
6.13 Overloading
6.13.1 Overloadable declarations
A13A13 (AUTOSAR)A13 (AUTOSAR-original)
A13-2-1Required · Automated✓ compilable
대입 연산자는 *this 에 대한 참조(비-const lvalue ref)를 반환한다An assignment operator shall return a reference to this
❌ 위반 예시Non-compliant example
#include <iostream>
struct S {
int v;
void operator=(const S& o) { v = o.v; } // void 반환 — 연쇄 대입 불가
};
int main() {
S a{1}, b{2}, c{3};
// a = b = c; // void 반환이라 (b=c) 결과를 a 에 대입할 수 없음 — 컴파일 에러
a = c;
std::cout << a.v << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
struct S {
int v;
S& operator=(const S& o) { v = o.v; return *this; } // *this 참조 반환
};
int main() {
S a{1}, b{2}, c{3};
a = b = c; // 연쇄 대입 — 우→좌, 표준 관례대로 동작
std::cout << a.v << ' ' << b.v << '\n'; // 3 3
}⚠️ 근거: 내장 타입의 대입식은 대입된 객체를 lvalue 로 돌려주어 a = b = c 같은 연쇄 대입과 (a = b).method() 같은 관례가 성립하는데, 사용자 정의 operator= 가 이를 따르려면 *this 에 대한 비-const lvalue 참조를 반환해야 한다. 영향: void 나 값으로 반환하면 연쇄 대입이 컴파일되지 않거나 불필요한 사본이 생겨, 표준 컨테이너·제네릭 코드가 기대하는 대입 의미와 어긋난다. 대응: 모든 대입 연산자(복사·이동·복합)는 return *this; 로 *this 참조를 반환한다.Rationale: a built-in assignment expression yields the assigned object as an lvalue, enabling chained assignment like a = b = c and conventions like (a = b).method(), and a user-defined operator= must return a non-const lvalue reference to this to follow it. Impact: returning void or by value makes chained assignment fail to compile or creates needless copies, diverging from the assignment semantics expected by standard containers and generic code. Fix: have every assignment operator (copy, move, compound) return a reference to this via return *this;.
A13-2-3Required · Automated✓ compilable
관계(비교) 연산자는 bool 을 반환한다A relational operator shall return a boolean value
❌ 위반 예시Non-compliant example
#include <iostream>
struct S {
int v;
int operator<(const S& o) const { return v - o.v; } // int 반환 — 오용 유발
};
int main() {
S a{3}, b{3};
if (a < b) std::cout << "less\n"; // a<b 가 거짓이어야 하는데 0(거짓)이라 우연히 맞음
S c{5};
std::cout << (c < a) << '\n'; // 2 출력 — bool 이 아니라 차이값
}✅ 준수 예시Compliant example
#include <iostream>
struct S {
int v;
bool operator<(const S& o) const { return v < o.v; } // bool 반환
};
int main() {
S a{3}, b{3}, c{5};
if (a < b) std::cout << "less\n"; // 정확히 false
std::cout << std::boolalpha << (c < a) << '\n'; // false
}⚠️ 근거: <, <=, ==, > 같은 관계·동등 연산자는 의미상 참/거짓을 돌려주는 술어이며, 표준 알고리즘·컨테이너도 이들이 bool 로 변환되는 결과를 반환한다고 가정한다. 영향: int 같은 다른 타입을 반환하면 0 이 아닌 모든 값이 참으로 취급되어 a < b 가 차이값을 돌려주는 식의 오용이 생기고, std::sort 의 비교자나 if 조건에서 직관과 다른 결과를 낸다. 대응: 모든 관계·동등 연산자는 bool 을 반환하도록 정의한다.Rationale: relational and equality operators like <, <=, ==, > are predicates that semantically yield true/false, and standard algorithms and containers assume they return a result convertible to bool. Impact: returning another type such as int treats every non-zero value as true, allowing misuse like a < b returning a difference, and produces counterintuitive results in std::sort comparators or if conditions. Fix: define every relational and equality operator to return bool.
A13-5-2Required · Automated✓ compilable
사용자 정의 변환 연산자는 explicit 로 선언한다All user-defined conversion operators shall be defined explicit
❌ 위반 예시Non-compliant example
#include <iostream>
struct Handle {
int fd;
operator int() const { return fd; } // 암시적 변환 연산자
};
int main() {
Handle h{7};
int x = h + 1; // h 가 조용히 int 로 변환되어 산술에 끼어듦 — 의도 불명
std::cout << x << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
struct Handle {
int fd;
explicit operator int() const { return fd; } // 명시적 변환만
};
int main() {
Handle h{7};
int x = static_cast<int>(h) + 1; // 변환 의도를 명시
std::cout << x << '\n';
}⚠️ 근거: explicit 가 아닌 변환 연산자는 컴파일러가 그 타입을 대상 타입으로 암시적으로 바꾸도록 허용해, 산술·비교·함수 인자 등 예상치 못한 문맥에서 변환이 일어난다. 영향: Handle 이 조용히 int 로 바뀌어 fd 값이 산술에 끼어들거나, 여러 암시 변환이 겹쳐 오버로드 해석이 의도와 다른 함수를 고르는 미묘한 버그가 된다. 대응: 변환 연산자를 explicit 로 선언해 static_cast 같은 명시적 변환을 통해서만 쓰이게 한다(단, bool 문맥용 explicit operator bool 처럼 의도된 경우만 둔다).Rationale: a non-explicit conversion operator lets the compiler implicitly convert the type to the target type, so the conversion happens in unexpected contexts like arithmetic, comparison, or function arguments. Impact: a Handle silently becomes an int and its fd value slips into arithmetic, or stacked implicit conversions make overload resolution pick the wrong function — a subtle bug. Fix: declare conversion operators explicit so they are used only through explicit conversions like static_cast (keeping intended ones such as explicit operator bool for boolean contexts).
A13-1-2Required · Automated✓ compilable📄 공식 예제Official example
User defined suffixes of the user defined literal operators shall start with underscore followed by one or more letters.User defined suffixes of the user defined literal operators shall start with underscore followed by one or more letters.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A13-1-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ constexpr long double operator"" _m(long double meters) // Compliant { // Implementation return meters; } constexpr long double operator"" _kg(long double kilograms) // Compliant { // Implementation return kilograms; } constexpr long double operator"" m(long double meters) // Non-compliant { // Implementation return meters; } constexpr long double operator"" kilograms( long double kilograms) // Non-compliant { // Implementation return kilograms; } void Fn() { long double weight = 20.0_kg; long double distance = 204.8_m; }
⚠️ Suffixes that do not begin with the underscore character are reserved for operators
provided by the standard library .
See also:
• noneSuffixes that do not begin with the underscore character are reserved for operators
provided by the standard library .
See also:
• none
A13-1-3Required · Automated✓ compilable📄 공식 예제Official example
User defined literals operators shall only perform conversion of passed parameters. --- PAGE 234 ---User defined literals operators shall only perform conversion of passed parameters. --- PAGE 234 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A13-1-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <iostream>
struct Cube
{
unsigned long long int volume;
constexpr explicit Cube(unsigned long long int v) : volume(v) {}
};
constexpr Cube operator"" _m3(unsigned long long int volume)
{
return Cube(volume); // Compliant
}
struct Temperature
{
unsigned long long int kelvins;
constexpr explicit Temperature(unsigned long long int k) : kelvins(k) {}
};
constexpr Temperature operator"" _K(unsigned long long int kelvins)
{
return Temperature(kelvins); // Compliant
}
static void SumDistances(std::int32_t distance)
{
static std::int32_t overallDistance = 0;
overallDistance += distance;
}
struct Distance
{
long double kilometers;
explicit Distance(long double kms) : kilometers(kms) {}
};
Distance operator"" _m(long double meters)
{
SumDistances(meters); // Non-compliant - function has a side-effect
return Distance(meters / 1000);
}
void operator"" _print(const char * str)
{
std::cout << str << '\n'; // Non-compliant - user-defined literal operator
// does not perform conversion and has a
// side-effect
}⚠️ It is expected behavior that the user-defined literals operators are only used to convert
passed parameters to the type of declared return value. User-defined literals are not
supposed to provide any other side-effects.
See also:
• none
6.13.2 Declaration matchingIt is expected behavior that the user-defined literals operators are only used to convert
passed parameters to the type of declared return value. User-defined literals are not
supposed to provide any other side-effects.
See also:
• none
6.13.2 Declaration matching
A13-2-2Required · Automated✓ compilable📄 공식 예제Official example
A binary arithmetic operator and a bitwise operator shall return a “prvalue”.A binary arithmetic operator and a bitwise operator shall return a “prvalue”.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A13-2-2.cpp 271687 2017-03-23 08:57:35Z piotr.tanski $
#include <cstdint>
class A
{
};
A operator+(A const&, A const&) noexcept // Compliant
{
return A{};
}
std::int32_t operator/(A const&, A const&) noexcept // Compliant
{
return 0;
}
A operator&(A const&, A const&)noexcept // Compliant
{
return A{};
}
const A operator-(A const&, std::int32_t) noexcept // Non-compliant
{
return A{};
}
A* operator|(A const&, A const&) noexcept // Non-compliant
{
return new A{};
}⚠️ Returning a type “T” from binary arithmetic and bitwise operators is consistent with the
C++ Standard Library .
See: prvalue.
See also:
• HIC++ v4.0 [9]: 13.2.2 Ensure that the return type of an overloaded binary
operator matches the built-in counterparts.Returning a type “T” from binary arithmetic and bitwise operators is consistent with the
C++ Standard Library .
See: prvalue.
See also:
• HIC++ v4.0 [9]: 13.2.2 Ensure that the return type of an overloaded binary
operator matches the built-in counterparts.
A13-3-1Required · Automated✓ compilable📄 공식 예제Official example
A function that contains “forwarding reference” as its argument shall not be overloaded.A function that contains “forwarding reference” as its argument shall not be overloaded.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility>
#include <stdexcept>
// $Id: A13-3-1.cpp 309903 2018-03-02 12:54:18Z christof.meerwald $
#include <cstdint>
template <typename T>
void F1(T&& t) noexcept(false)
{
}
void F1(
std::int32_t&& t) noexcept // Non-compliant - overloading a function with
// forwarding reference
{
}
template <typename T>
void F2(T&& t) noexcept(false)
{
}
void F2(std::int32_t&) = delete; // Compliant by exception
class A
{
public:
// Compliant by exception, constrained to not match copy/move ctors
template<typename T,
std::enable_if_t<! std::is_same<std::remove_cv_t<std::
remove_reference_t<T>>, A>::value> * = nullptr>
A(T &&value);
};
int main(int, char **)
{
std::int32_t x = 0;
F1(x); // Calls f1(T&&) with T = int&
F1(+x); // Calls f1(std::int32_t&&)
F1(0); // Calls f1(std::int32_t&&)
F1(0U); // Calls f1(T&&) with T = unsigned int
F2(0); // Calls f2(T&&) with T = int
// f2(x); // Compilation error, the overloading function is deleted
}⚠️ A template parameter that is declared “T&&” (Scott Meters called it a “universal
reference”, while C++ Language Standard calls it a “forwarding reference”) will deduce
for any type. Overloading functions with “forwarding reference” argument may lead to
developer’s confusion on which function will be called.
Exception:
Declaring an overloading function that takes a “forwarding reference” parameter to be
“=delete” does not violate this rule.
Declaring a “forwarding constructor” that is constrained (via SFINAE) to not match any
other overloads also does not violate this rule, see A14-5-1.
See also:
• HIC++ v4.0 [9]: 13.1.2 If a member of a set of callable functions includes a
universal reference parameter, ensure that one appears in the same position for
all other members.
• Effective Modern C++ [13]: Item 26. Avoid overloading on universal references.
6.13.5 Overloaded operatorsA template parameter that is declared “T&&” (Scott Meters called it a “universal
reference”, while C++ Language Standard calls it a “forwarding reference”) will deduce
for any type. Overloading functions with “forwarding reference” argument may lead to
developer’s confusion on which function will be called.
Exception:
Declaring an overloading function that takes a “forwarding reference” parameter to be
“=delete” does not violate this rule.
Declaring a “forwarding constructor” that is constrained (via SFINAE) to not match any
other overloads also does not violate this rule, see A14-5-1.
See also:
• HIC++ v4.0 [9]: 13.1.2 If a member of a set of callable functions includes a
universal reference parameter, ensure that one appears in the same position for
all other members.
• Effective Modern C++ [13]: Item 26. Avoid overloading on universal references.
6.13.5 Overloaded operators
A13-5-1Required · Automated✓ compilable📄 공식 예제Official example
If “operator[]” is to be overloaded with a non-const version, const version shall also be implemented.If “operator[]” is to be overloaded with a non-const version, const version shall also be implemented.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A13-5-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
class Container1
{
public:
std::int32_t& operator[](
std::int32_t index) // Compliant - non-const version
{
return container[index];
}
std::int32_t operator[](
std::int32_t index) const // Compliant - const version
{
return container[index];
}
private:
static constexpr std::int32_t maxSize = 10;
std::int32_t container[maxSize];
};
void Fn() noexcept
{
Container1 c1;
std::int32_t e = c1[0]; // Non-const version called
c1[0] = 20; // Non-const version called
Container1 const c2{};
e = c2[0]; // Const version called
// c2[0] = 20; // Compilation error
}
class Container2 // Non-compliant - only non-const version of operator[]
// implemented
{
public:
std::int32_t& operator[](std::int32_t index) { return container[index]; }
private:
static constexpr std::int32_t maxSize = 10;
std::int32_t container[maxSize];
};⚠️ A non-const overload of the subscript operator allows an object to be modified, by
returning a reference to member data, but it does not allow reading from const objects.
The const version of “operator[]” needs to be implemented to ensure that the operator
can be invoked on a const object.
Note that one can provide a const version of operator[] (to support read-only access to
elements), but without a non-const version.
See also:
• HIC++ v4.0 [9]: 13.2.4 When overloading the subscript operator (operator[])
implement both const and non-const versions.A non-const overload of the subscript operator allows an object to be modified, by
returning a reference to member data, but it does not allow reading from const objects.
The const version of “operator[]” needs to be implemented to ensure that the operator
can be invoked on a const object.
Note that one can provide a const version of operator[] (to support read-only access to
elements), but without a non-const version.
See also:
• HIC++ v4.0 [9]: 13.2.4 When overloading the subscript operator (operator[])
implement both const and non-const versions.
A13-5-3Advisory · Automated✓ compilable📄 공식 예제Official example
User-defined conversion operators should not be used.User-defined conversion operators should not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A13-5-3.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
#include <iostream>
class Complex
{
public:
Complex (double r, double i = 0.0) : re(r), im(i) {}
explicit operator double() const noexcept { return re; }
double AsDouble() const noexcept { return re; }
private:
double re;
double im;
};
int main(void)
{
Complex c(2.0f);
std::cout << (double) c << std::endl; //compliant with A13-5-2, non-
compliant with A13-5-3
std::cout << c.AsDouble() << std::endl; //compliant
return 0;
}⚠️ Explicitly named conversions using dedicated member function eliminate any potential
errors that can arise if the type conversion operators have to be used.
If using conversion operators is fundamental in an application domain, see A13-5-2.
See also:
• JSF December 2005 [8]: AV Rule 177: User-defined conversion functions should
be avoided.
• C++ Core Guidelines [11]: C.164: Avoid conversion operators.Explicitly named conversions using dedicated member function eliminate any potential
errors that can arise if the type conversion operators have to be used.
If using conversion operators is fundamental in an application domain, see A13-5-2.
See also:
• JSF December 2005 [8]: AV Rule 177: User-defined conversion functions should
be avoided.
• C++ Core Guidelines [11]: C.164: Avoid conversion operators.
A13-5-4Required · Automated✓ compilable📄 공식 예제Official example
If two opposite operators are defined, one shall be defined in terms of the other.If two opposite operators are defined, one shall be defined in terms of the other.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A13-5-4.cpp 328319 2018-08-03 14:08:42Z christof.meerwald $ #include <cstdint> // non-compliant class A { public: explicit A(std::uint32_t d) : d(d) {} friend bool operator==(A const & lhs, A const & rhs) noexcept { return lhs.d == rhs.d; } friend bool operator!=(A const & lhs, A const & rhs) noexcept { return lhs.d != rhs.d; } private: std::uint32_t d; }; // compliant class B { public: explicit B(std::uint32_t d) : d(d) {} friend bool operator==(B const & lhs, B const & rhs) noexcept { return lhs.d == rhs.d; } friend bool operator!=(B const & lhs, B const & rhs) noexcept { return !(lhs == rhs); } private: std::uint32_t d; };
⚠️ Defining one operator in terms of the other simplifies maintenance and prevents from
accidental errors during code development.
Note: Completeness of relational operators can be achieved by implementing just
operator== and operator< and using namespace rel_ops.
See also:
• JSF December 2005 [8]: AV Rule 85: When two operators are opposites (such
as == and !=), both will be defined and one will be defined in terms of the other.Defining one operator in terms of the other simplifies maintenance and prevents from
accidental errors during code development.
Note: Completeness of relational operators can be achieved by implementing just
operator== and operator< and using namespace rel_ops.
See also:
• JSF December 2005 [8]: AV Rule 85: When two operators are opposites (such
as == and !=), both will be defined and one will be defined in terms of the other.
A13-5-5Required · Automated✓ compilable📄 공식 예제Official example
Comparison operators shall be non-member functions with identical parameter types and noexcept.Comparison operators shall be non-member functions with identical parameter types and noexcept.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A13-5-5.cpp 325916 2018-07-13 12:26:22Z christof.meerwald $
#include <cstdint>
class A
{
public:
explicit A(std::uint32_t d)
: m_d(d)
{ }
bool operator ==(A const & rhs) const // Non-compliant: member, not noexcept
{
return m_d == rhs.m_d;
}
private:
std::uint32_t m_d;
};
class C
{
public:
operator A() const { return A(0); }
};
void Foo(A const & a, C const & c)
{
a == c; // asymmetric as "a ==c" compiles, but "c == a" doesn't compile
}
class B
{
public:
explicit B(std::uint32_t d)
: m_d(d)
{ }
// Compliant: non-member, identical parameter types, noexcept
friend bool operator ==(B const & lhs, B const & rhs) noexcept
{
return lhs.m_d == rhs.m_d;
}
private:
std::uint32_t m_d;
};
class D
{
public:
operator B() const { return B(0); }
};
void Bar(B const & b, D const & d)
{
b == d;
d == b;
}⚠️ Any asymmetric behavior for comparison functions can be confusing. In order to
achieve fully symmetric treatment, comparison functions need to be defined as non-
member functions, as the implicit object parameter of a member function does not
allow user-defined conversions to be applied (but the right hand side would).
Since comparison is a fundamental operation, it should never throw an exception.
Note: This rule applies to ==, !=, <, <=, >, and >=
Note: Declaring a comparison operator as a friend allows it to access internal data
similar to a member function and is allowed by exception in rule A11-3-1.
See also:
• C++ Core Guidelines [11]: C.86: Make == symmetric with respect to operand
types and noexcept
6.13.6 Build-in operatorsAny asymmetric behavior for comparison functions can be confusing. In order to
achieve fully symmetric treatment, comparison functions need to be defined as non-
member functions, as the implicit object parameter of a member function does not
allow user-defined conversions to be applied (but the right hand side would).
Since comparison is a fundamental operation, it should never throw an exception.
Note: This rule applies to ==, !=, <, <=, >, and >=
Note: Declaring a comparison operator as a friend allows it to access internal data
similar to a member function and is allowed by exception in rule A11-3-1.
See also:
• C++ Core Guidelines [11]: C.86: Make == symmetric with respect to operand
types and noexcept
6.13.6 Build-in operators
A13-6-1Required · Automated✓ compilable📄 공식 예제Official example
Digit sequences separators ’ shall only be used as follows: (1) for decimal, every 3 digits, (2) for hexadecimal, every 2 digits, (3) for binary, every 4 digits.Digit sequences separators ’ shall only be used as follows: (1) for decimal, every 3 digits, (2) for hexadecimal, every 2 digits, (3) for binary, every 4 digits.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A13-6-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
void Fn() noexcept
{
std::uint32_t decimal1 = 3'000'000; // Compliant
std::uint32_t decimal2 = 4'500; // Compliant
std::uint32_t decimal3 = 54'00'30; // Non-compliant
float decimal4 = 3.141'592'653; // Compliant
float decimal5 = 3.1'4159'265'3; // Non-compliant
std::uint32_t hex1 = 0xFF'FF'FF'FF; // Compliant
std::uint32_t hex2 = 0xFAB'1'FFFFF; // Non-compliant
std::uint8_t binary1 = 0b1001'0011; // Compliant
std::uint8_t binary2 = 0b10'00'10'01; // Non-compliant
}⚠️ Since C++14 Language Standard it is allowed (optionally) to separate any two digits in
digit sequences with separator ’. However, to meet developer expectations, usage of
separator in integer and floating-point digit sequences should be unified:
• for decimal values, separator can be placed every 3 digits, e.g. 3’000’000,
3.141’592’653
• for hexadecimal values, separator can be placed every 2 digits, e.g.
0xFF’FF’FF’FF
• for binary values, separator can be placed very 4 digits, e.g. 0b1001’1101’0010
See also:
• ISO 26262-6 [5]: 8.4.4 e) readability and comprehensibility
6.14 Templates
6.14.0 General
6.14.1 Template parametersSince C++14 Language Standard it is allowed (optionally) to separate any two digits in
digit sequences with separator ’. However, to meet developer expectations, usage of
separator in integer and floating-point digit sequences should be unified:
• for decimal values, separator can be placed every 3 digits, e.g. 3’000’000,
3.141’592’653
• for hexadecimal values, separator can be placed every 2 digits, e.g.
0xFF’FF’FF’FF
• for binary values, separator can be placed very 4 digits, e.g. 0b1001’1101’0010
See also:
• ISO 26262-6 [5]: 8.4.4 e) readability and comprehensibility
6.14 Templates
6.14.0 General
6.14.1 Template parameters
A14A14 (AUTOSAR)A14 (AUTOSAR-original)
A14-8-2Required · Automated✓ compilable
함수 템플릿의 명시적 특수화를 사용하지 않는다Explicit specializations of function templates shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
template <typename T> void f(T) { std::cout << "generic\n"; }
template <> void f<int>(int) { std::cout << "int special\n"; } // 함수 템플릿 특수화
void f(int) { std::cout << "int overload\n"; } // 오버로드도 존재
int main() { f(3); } // 특수화가 아니라 오버로드가 선택됨 — 직관과 다른 함정✅ 준수 예시Compliant example
#include <iostream>
template <typename T> void f(T) { std::cout << "generic\n"; }
void f(int) { std::cout << "int overload\n"; } // 일반 오버로드만
int main() { f(3); } // int 오버로드가 명확히 선택됨⚠️ 근거: 함수 템플릿의 명시적 특수화는 오버로드 해석에 직접 참여하지 않고, 오버로드 해석이 먼저 기본 템플릿을 고른 뒤에만 그 특수화가 적용된다. 영향: 일반 함수 오버로드가 함께 있으면 직관과 달리 특수화가 아니라 오버로드가 선택되어, 어떤 함수가 호출될지 예측하기 어려운 함정이 된다. 대응: 타입별로 동작을 분기하려면 명시적 특수화 대신 일반 함수 오버로드(또는 클래스 템플릿 특수화)를 사용한다.Rationale: an explicit function-template specialization does not participate directly in overload resolution; it applies only after overload resolution has first chosen the primary template. Impact: when an ordinary function overload is also present, the overload — not the specialization — is selected against intuition, a trap that makes it hard to predict which function is called. Fix: to branch behaviour by type, use ordinary function overloads (or class-template specialization) instead of explicit function-template specialization.
A14-1-1Advisory · Non-automated✓ compilable📄 공식 예제Official example
A template should check if a specific template argument is suitable for this template.A template should check if a specific template argument is suitable for this template.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A14-1-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <utility>
class A
{
public:
A() = default;
~A() = default;
A(A const&) = delete;
A& operator=(A const&) = delete;
A(A&&) = delete;
A& operator=(A&&) = delete;
};
class B
{
public:
B() = default;
B(B const&) = default;
B& operator=(B const&) = default;
B(B&&) = default;
B& operator=(B&&) = default;
};
template <typename T>
void F1(T const& obj) noexcept(false)
{
static_assert(
std::is_copy_constructible<T>(),
"Given template type is not copy constructible."); // Compliant
}
template <typename T>
class C
{
// Compliant
static_assert(std::is_trivially_copy_constructible<T>(),
"Given template type is not trivially copy constructible.");
// Compliant
static_assert(std::is_trivially_move_constructible<T>(),
"Given template type is not trivially move constructible.");
// Compliant
static_assert(std::is_trivially_copy_assignable<T>(),
"Given template type is not trivially copy assignable.");
// Compliant
static_assert(std::is_trivially_move_assignable<T>(),
"Given template type is not trivially move assignable.");
public:
C() = default;
C(C const&) = default;
C& operator=(C const&) = default;
C(C&&) = default;
C& operator=(C&&) = default;
private:
T c;
};
template <typename T>
class D
{
public:
D() = default;
D(D const&) = default; // Non-compliant - T may not be copyable
D& operator=(D const&) = default; // Non-compliant - T may not be copyable
D(D&&) = default; // Non-compliant - T may not be movable
D& operator=(D&&) = default; // Non-compliant - T may not be movable
private:
T d;
};
void F2() noexcept
{
A a;
B b;
// f1<A>(a); // Class A is not copy constructible, compile-time error
// occurs
F1<B>(b); // Class B is copy constructible
// C<A> c1; // Class A can not be used for template class C, compile-time
// error occurs
C<B> c2; // Class B can be used for template class C
D<A> d1;
// D<A> d2 = d1; // Class D can not be copied, because class A is not
// copyable, compile=time error occurs
// D<A> d3 = std::move(d1); // Class D can not be moved, because class A is
// not movable, compile-time error occurs
D<B> d4;
D<B> d5 = d4;
D<B> d6 = std::move(d4);
}⚠️ If a template class or function requires specific characteristics from a template type
(e.g. if it is move constructible, copyable, etc.), then it needs to check whether the type
matches the requirements to detect possible faults. The goal of this rule is to ensure
that a template defines all of the preconditions that a template argument needs to fulfill
without having any information about the specific class.
This can be achieved in compile time using static_assert assertion.
See also:
• JSF December 2005 [8]: AV Rule 103: Constraint checks should be applied to
template arguments.
• C++ Core Guidelines [11]: T .150: Check that a class matches a concept using
static_assert.
6.14.5 Template declarationsIf a template class or function requires specific characteristics from a template type
(e.g. if it is move constructible, copyable, etc.), then it needs to check whether the type
matches the requirements to detect possible faults. The goal of this rule is to ensure
that a template defines all of the preconditions that a template argument needs to fulfill
without having any information about the specific class.
This can be achieved in compile time using static_assert assertion.
See also:
• JSF December 2005 [8]: AV Rule 103: Constraint checks should be applied to
template arguments.
• C++ Core Guidelines [11]: T .150: Check that a class matches a concept using
static_assert.
6.14.5 Template declarations
A14-5-1Required · Automated✓ compilable📄 공식 예제Official example
A template constructor shall not participate in overload resolution for a single argument of the enclosing class type.A template constructor shall not participate in overload resolution for a single argument of the enclosing class type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility>
// $Id: A14-5-1.cpp 309903 2018-03-02 12:54:18Z christof.meerwald $
#include <cstdint>
#include <type_traits>
class A
{
public:
// Compliant: template constructor does not participate in overload
// resolution for copy/move operations
template<typename T,
std::enable_if_t<! std::is_same<std::remove_cv_t<T>, A>::value> * =
nullptr>
A(const T &value)
: m_value { value }
{ }
private:
std::int32_t m_value;
};
void Foo(A const &a)
{
A myA { a }; // will use the implicit copy ctor, not the template converting
ctor
A a2 { 2 }; // will use the template converting ctor
}
class B
{
public:
B(const B &) = default;
B(B &&) = default;
// Compliant: forwarding constructor does not participate in overload
// resolution for copy/move operations
template<typename T,
std::enable_if_t<! std::is_same<std::remove_cv_t<std::
remove_reference_t<T>>, B>::value> * = nullptr>
B(T &&value);
};
void Bar(B b)
{
B myB { b }; // will use the copy ctor, not the forwarding ctor
}
class C
{
public:
C(const C &) = default;
C(C &&) = default;
// Non-Compliant: unconstrained template constructor
template<typename T>
C(T &);
};
void Bar(C c)
{
C myC { c }; // will use template ctor instead of copy ctor
}⚠️ A template constructor is never a copy or move constructor and therefore doesn’t
prevent the implicit definition of a copy or move constructor even if the template
constructor looks similar and might easily be confused.
At the same time, copy or move operations do not necessarily only use a copy or move
constructor, but go through the normal overload resolution process to find the best
matching function to use.
This can cause confusion in the following cases:
• a template constructor that looks like a copy/move constructor is not selected for a
copy/move operation because the compiler has generated an implicit copy/move
constructor as well
• a template constructor is selected in preference over a copy/move constructor
because the template constructor is a better match
T o avoid these confusing situations, template constructors shall not participate in
overload resolution for a single argument of the enclosing class type to avoid a template
constructor being selected for a copy/move operation. It also makes it clear that the
constructor is not a copy/move constructor and that it does not prevent the implicit
generation of copy/move constructors.
See also:
• MISRA C++ 2008 [7]: M14-5-2: A copy constructor shall be declared when there
is a template constructor with a single parameter that is a generic parameter.A template constructor is never a copy or move constructor and therefore doesn’t
prevent the implicit definition of a copy or move constructor even if the template
constructor looks similar and might easily be confused.
At the same time, copy or move operations do not necessarily only use a copy or move
constructor, but go through the normal overload resolution process to find the best
matching function to use.
This can cause confusion in the following cases:
• a template constructor that looks like a copy/move constructor is not selected for a
copy/move operation because the compiler has generated an implicit copy/move
constructor as well
• a template constructor is selected in preference over a copy/move constructor
because the template constructor is a better match
T o avoid these confusing situations, template constructors shall not participate in
overload resolution for a single argument of the enclosing class type to avoid a template
constructor being selected for a copy/move operation. It also makes it clear that the
constructor is not a copy/move constructor and that it does not prevent the implicit
generation of copy/move constructors.
See also:
• MISRA C++ 2008 [7]: M14-5-2: A copy constructor shall be declared when there
is a template constructor with a single parameter that is a generic parameter.
A14-5-2Advisory · Automated✓ compilable📄 공식 예제Official example
Class members that are not dependent on template class parameters should be defined in a separate base class.Class members that are not dependent on template class parameters should be defined in a separate base class.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A14-5-2.cpp 323444 2018-06-22 14:38:18Z christof.meerwald $
#include <cstdint>
template<typename T>
class A
{
public:
enum State // Non-Compliant: member doesn't depend on template parameter
{
State1,
State2
};
State GetState();
};
class B_Base
{
public:
enum State // Compliant: not a member of a class template
{
State1,
State2
};
};
template<typename T>
class B : B_Base
{
public:
State GetState();
};⚠️ Having non-dependent members in a class template can lead to unnecessary template
instantiations and potential code bloat. It is therefore preferred to move those members
to a non-dependent base class so they can be used without any template instantiation.
See also:
• C++ Core Guidelines [11]: T .62: Place non-dependent class template members
in a non-templated base classHaving non-dependent members in a class template can lead to unnecessary template
instantiations and potential code bloat. It is therefore preferred to move those members
to a non-dependent base class so they can be used without any template instantiation.
See also:
• C++ Core Guidelines [11]: T .62: Place non-dependent class template members
in a non-templated base class
A14-5-3Advisory · Automated✓ compilable📄 공식 예제Official example
A non-member generic operator shall only be declared in a namespace that does not contain class (struct) type, enum type or union type declarations.A non-member generic operator shall only be declared in a namespace that does not contain class (struct) type, enum type or union type declarations.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A14-5-3.cpp $
#include <cstdint>
template<typename T>
class B
{
public:
bool operator+( long rhs ) { return true; }
void f()
{
*this + 10;
}
};
namespace NS1
{
class A {};
template<typename T>
bool operator+( T, std::int32_t ); // Non-Compliant: a member of namespace
// with other declarations
}
namespace NS2
{
void g();
template<typename T>
bool operator+( T, std::int32_t ); // Compliant: a member of namespace
// with declarations of functions only
}
template class B<NS1::A>; // NS1::operator+ will be used in function B::f()
// instead of B::operator+⚠️ Argument-dependent lookup (ADL) adds additional associated namespaces to the set
of scopes searched when lookup is performed for the names of called functions. A
generic operator found in one of these additional namespaces would be added to
the overload set and choosen by overload resolution. ADL is complicated by several
possible use forms for operators (via function calls and via expression, operators can
be declared as members and as non-members) and lookup in those cases is different,
which is likely to be inconsistent with developer expectation.
Generic operator is a non-member operator template that can be called without
explicit template arguments and has at least one generic parameter. A template type
parameter T is a generic parameter if, in the function declaration, it has the (possibly
cv-qualified) form of T , or T & or T &&.
See also:
• MISRA C++ 2008 [7]: M14-5-1: A non-member generic function shall only be
declared in a namespace that containes only operator declarations.Argument-dependent lookup (ADL) adds additional associated namespaces to the set
of scopes searched when lookup is performed for the names of called functions. A
generic operator found in one of these additional namespaces would be added to
the overload set and choosen by overload resolution. ADL is complicated by several
possible use forms for operators (via function calls and via expression, operators can
be declared as members and as non-members) and lookup in those cases is different,
which is likely to be inconsistent with developer expectation.
Generic operator is a non-member operator template that can be called without
explicit template arguments and has at least one generic parameter. A template type
parameter T is a generic parameter if, in the function declaration, it has the (possibly
cv-qualified) form of T , or T & or T &&.
See also:
• MISRA C++ 2008 [7]: M14-5-1: A non-member generic function shall only be
declared in a namespace that containes only operator declarations.
A14-7-1Required · Automated✓ compilable📄 공식 예제Official example
A type used as a template argument shall provide all members that are used by the template.A type used as a template argument shall provide all members that are used by the template.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A14-7-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
class A
{
public:
void SetProperty(std::int32_t x) noexcept { property = x; }
void DoSomething() noexcept {}
private:
std::int32_t property;
};
struct B
{
};
class C
{
public:
void DoSomething() noexcept {}
};
template <typename T>
class D
{
public:
void F1() {}
void F2()
{
T t;
t.SetProperty(0);
}
void F3()
{
T t;
t.DoSomething();
}
};
void Fn() noexcept
{
D<A> d1; // Compliant - struct A provides all needed members
d1.F1();
d1.F2();
d1.F3();
D<B> d2; // Non-compliant - struct B does not provide needed members
d2.F1();
// d2.f2(); // Compilation error - no 'property' in struct B
// d2.f3(); // Compilation error - no member named 'doSomething' in struct
// B
D<C> d3; // Non-compliant - struct C does not provide property
d3.F1();
// d3.F2(); // Compilation error - no property in struct C
d3.F3();
}⚠️ If a type used as a template argument does not provide all the members used by the
template, the instantiation of the template will result in an ill-formed program. It is not
clear for developer whether the template should be used with the type.
See also:
• MISRA C++ 2008 [7]: Rule 14-7-2 (Required) For any given template
specialization, an explicit instantiation of the template with the template
arguments used in the specialization shall not render the program ill-formed.If a type used as a template argument does not provide all the members used by the
template, the instantiation of the template will result in an ill-formed program. It is not
clear for developer whether the template should be used with the type.
See also:
• MISRA C++ 2008 [7]: Rule 14-7-2 (Required) For any given template
specialization, an explicit instantiation of the template with the template
arguments used in the specialization shall not render the program ill-formed.
A14-7-2Required · Automated✓ compilable📄 공식 예제Official example
Template specialization shall be declared in the same file (1) as the primary template (2) as a user-defined type, for which the specialization is declared.Template specialization shall be declared in the same file (1) as the primary template (2) as a user-defined type, for which the specialization is declared.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef>
// $Id: A14-7-2.cpp 312645 2018-03-21 11:44:35Z michal.szczepankiewicz $
#include <cstdint>
//in A.hpp
#include <functional>
struct A
{
std::uint8_t x;
};
namespace std {
//compliant, case (2)
//template specialization for the user-defined type
//in the same file as the type declaration
template <>
struct hash<A>
{
size_t operator()(const A& a) const noexcept
{
return std::hash<decltype(a.x)>()(a.x);
}
};
}
//traits.hpp
#include <type_traits>
#include <cstdint>
template <typename T>
struct is_serializable : std::false_type {};
//compliant, case (1)
template <>
struct is_serializable<std::uint8_t> : std::true_type {};
//func.cpp
#include <vector>
//non-compliant, not declared
//in the same file as
//is_serializable class
template <>
struct is_serializable<std::uint16_t> : std::true_type {};
template <typename T, typename = std::enable_if<is_serializable<T>::value>>
std::vector<std::uint8_t> serialize(const T& t)
{
//only a basic stub
return std::vector<std::uint8_t>{t};
}
#include <string>
int main()
{
serialize(std::uint8_t{3});
}⚠️ It is undefined behavior, when a compiler sees the (partial or explicit) template
specialization after it already has instantiated the primary or less specialized template.
Moreover, the case (2) allows compile-time interfaces to be extensible, as developers
can safely provide custom specializations e.g. for traits classes or std::hash.
See also:
• MISRA C++ 2008 [7]: Rule 14-7-2 (Required) For any given template
specialization, an explicit instantiation of the template with the template
arguments used in the specialization shall not render the program ill-formed.
6.14.8 Function template specializationsIt is undefined behavior, when a compiler sees the (partial or explicit) template
specialization after it already has instantiated the primary or less specialized template.
Moreover, the case (2) allows compile-time interfaces to be extensible, as developers
can safely provide custom specializations e.g. for traits classes or std::hash.
See also:
• MISRA C++ 2008 [7]: Rule 14-7-2 (Required) For any given template
specialization, an explicit instantiation of the template with the template
arguments used in the specialization shall not render the program ill-formed.
6.14.8 Function template specializations
A15A15 (AUTOSAR)A15 (AUTOSAR-original)
A15-1-1Required · Automated✓ compilable
std::exception 에서 파생된 타입만 예외로 사용한다Only instances of types derived from std::exception should be thrown
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
try {
throw 42; // 정수 예외 — 표준 핸들링 계층과 무관, 메시지 없음
}
catch (int e) { std::cout << "caught int " << e << '\n'; }
// 다른 곳의 catch(const std::exception&) 는 이 예외를 잡지 못함
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
int main() {
try {
throw std::runtime_error("invalid state"); // 표준 예외 계층
}
catch (const std::exception& e) { std::cout << "caught: " << e.what() << '\n'; }
}⚠️ 근거: int·문자열·임의 사용자 타입을 던지면 표준 예외 계층(std::exception)과 무관해, 공통 기반으로 일괄 포착(catch(const std::exception&))하거나 what() 으로 진단 메시지를 얻을 수 없다. 영향: 라이브러리·상위 계층이 std::exception 만 잡는 일반 핸들러를 두면 비표준 예외가 그 그물을 빠져나가 처리되지 않은 채 terminate 로 이어진다. 대응: 예외는 std::exception 에서 파생된 타입(표준 예외 또는 그것을 상속한 사용자 예외)만 사용해 일관된 포착과 메시지 전달을 보장한다.Rationale: throwing an int, a string, or an arbitrary user type is unrelated to the standard exception hierarchy (std::exception), so it cannot be caught uniformly through a common base (catch(const std::exception&)) or yield a diagnostic via what(). Impact: when a library or upper layer installs a general handler catching only std::exception, a non-standard exception slips through that net and goes unhandled to terminate. Fix: throw only types derived from std::exception (standard exceptions or user exceptions inheriting them) to guarantee consistent catching and message delivery.
A15-1-2Required · Automated✓ compilable
예외 객체를 포인터로 throw 하지 않는다(값으로 throw)An exception object shall not be a pointer
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
struct MyError : std::runtime_error { using std::runtime_error::runtime_error; };
int main() {
try { throw new MyError("disk"); } // 포인터 throw — 누가 delete? 누수/이중해제
catch (MyError* e) { std::cout << e->what() << '\n'; delete e; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct MyError : std::runtime_error { using std::runtime_error::runtime_error; };
int main() {
try { throw MyError("disk"); } // 값으로 throw
catch (const MyError& e) { std::cout << e.what() << '\n'; } // const 참조로 catch
}⚠️ 근거: 예외를 포인터로 던지면 그 예외 객체의 메모리를 누가·언제 해제해야 하는지가 catch 측에 위임되어 소유권이 모호해진다. 영향: catch 가 delete 를 빠뜨리면 누수, 두 번 delete 하면 이중 해제가 되고, 던진 포인터가 지역 객체를 가리키면 댕글링이 된다. 대응: 예외는 값으로 던지고 const 참조로 잡아, 예외 객체의 수명을 런타임이 자동으로 관리하게 한다.Rationale: throwing an exception by pointer delegates to the catch site the question of who frees the exception object and when, making ownership ambiguous. Impact: the catch leaks if it forgets delete, double-frees if it deletes twice, and dangles if the thrown pointer refers to a local object. Fix: throw by value and catch by const reference so the runtime manages the lifetime of the exception object automatically.
A15-1-5Required · Automated✓ compilable
예외를 실행 경계(스레드·콜백 경계 등) 너머로 던지지 않는다Exceptions shall not be thrown across execution boundaries
❌ 위반 예시Non-compliant example
#include <thread>
#include <stdexcept>
int main(int argc, char**) {
std::thread t([argc]{
if (argc < 0) throw std::runtime_error("escapes thread"); // 스레드 밖으로 → terminate
}); // (가드로 실제 throw 는 회피; 패턴 자체가 결함 — 스레드 함수의 예외는 잡을 곳이 없음)
t.join();
}✅ 준수 예시Compliant example
#include <iostream>
#include <thread>
#include <stdexcept>
#include <exception>
int main() {
std::exception_ptr err;
std::thread t([&err]{
try { throw std::runtime_error("work failed"); } // 경계 내부에서 포착
catch (...) { err = std::current_exception(); } // 전달 가능한 형태로 저장
});
t.join();
if (err) { try { std::rethrow_exception(err); }
catch (const std::exception& e) { std::cout << "from thread: " << e.what() << '\n'; } }
}⚠️ 근거: 스레드 진입 함수나 C 콜백 같은 실행 경계는 C++ 예외 전파 메커니즘 밖이라, 예외가 그 경계를 넘어 빠져나가면 표준은 std::terminate 를 호출하도록 규정한다. 영향: 스레드 함수에서 예외가 탈출하면 그 예외를 잡을 호출자 프레임이 없어 프로그램이 정리 없이 강제 종료된다. 대응: 경계 안에서 catch(...) 로 예외를 포착하고 std::exception_ptr 같은 전달 가능한 형태로 저장해, 경계 밖(join 이후 등)에서 다시 던져 처리한다.Rationale: an execution boundary such as a thread entry function or a C callback is outside the C++ exception propagation mechanism, so the standard calls std::terminate if an exception escapes across it. Impact: an exception escaping a thread function has no caller frame to catch it, so the program is forcibly terminated without cleanup. Fix: catch the exception inside the boundary with catch(...) and store it in a transferable form like std::exception_ptr, then rethrow and handle it outside the boundary (e.g. after join).
A15-2-2Required · Automated✓ compilable
생성자가 실패하면 이미 획득한 자원을 모두 해제한다If a constructor is not noexcept and the constructor cannot finish, all already-allocated resources shall be released
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
struct S {
int* a_;
int* b_;
S(int argc) : a_(new int(1)), b_(new int(2)) {
if (argc >= 0) throw std::runtime_error("ctor fail"); // a_,b_ 는 소멸자 미호출 → 누수
}
~S() { delete a_; delete b_; }
};
int main(int argc, char**) {
try { S s(argc); } catch (...) { std::cout << "leaked a_ and b_\n"; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
#include <stdexcept>
struct S {
std::unique_ptr<int> a_;
std::unique_ptr<int> b_;
S(int argc) : a_(std::make_unique<int>(1)), b_(std::make_unique<int>(2)) {
if (argc >= 0) throw std::runtime_error("ctor fail"); // 이미 만든 멤버는 자동 해제
}
};
int main(int argc, char**) {
try { S s(argc); } catch (...) { std::cout << "no leak (members RAII-freed)\n"; }
}⚠️ 근거: 생성자 본문에서 예외가 던져지면 그 객체의 소멸자는 호출되지 않지만, 이미 완전히 생성된 멤버(서브오브젝트)의 소멸자는 호출된다. 영향: 멤버를 raw 포인터로 두고 생성자에서 new 로 할당한 뒤 예외가 나면, 객체 소멸자가 불리지 않아 그 raw 자원이 누수된다. 대응: 멤버를 unique_ptr·컨테이너 같은 RAII 타입으로 두어, 생성자가 중간에 실패해도 이미 생성된 멤버가 스택 풀기에서 자동 해제되게 한다.Rationale: if an exception is thrown in a constructor body, the destructor of that object is not called, but destructors of already fully-constructed members (subobjects) are. Impact: keeping members as raw pointers and allocating them with new in the constructor leaks those raw resources when an exception follows, since the object destructor never runs. Fix: hold members in RAII types like unique_ptr or containers so that already-constructed members are freed automatically during unwinding even if the constructor fails partway.
A15-3-5Required · Automated✓ compilable
클래스 타입 예외는 (const) 참조로 catch 한다A class type exception shall be caught by reference or const reference
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
int main() {
try { throw std::runtime_error("boom"); }
catch (std::exception e) { // 값 catch — 파생 예외가 base 로 슬라이싱
std::cout << e.what() << '\n'; // 파생 정보 손실, 불필요한 복사
}
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
int main() {
try { throw std::runtime_error("boom"); }
catch (const std::exception& e) { // const 참조 — 다형성·메시지 보존
std::cout << e.what() << '\n';
}
}⚠️ 근거: 예외를 값으로 잡으면 던져진 객체가 핸들러 매개변수 타입으로 복사되며, 그 타입이 기반 클래스면 파생 부분이 잘려 나간다(slicing). 영향: 파생 예외가 담은 오류 코드·문맥과 다형적 what() 동작을 잃어 진단 정보가 사라지고, 복사 자체가 예외를 던지면(메모리 부족 등) 처리 중 또 다른 문제가 생긴다. 대응: 클래스 타입 예외는 const 참조로 잡아 복사·슬라이싱 없이 실제 동적 타입의 정보를 보존한다.Rationale: catching an exception by value copies the thrown object into the handler parameter type, and if that type is a base class the derived part is sliced off. Impact: the error code, context, and polymorphic what() behaviour carried by the derived exception are lost, and if the copy itself throws (e.g. out of memory) another problem arises during handling. Fix: catch class-type exceptions by const reference to preserve the actual dynamic type information without a copy or slicing.
A15-4-2Required · Automated✓ compilable
noexcept 함수에서 예외가 빠져나가지 않게 한다If a function is declared to be noexcept, it shall not exit with an exception
❌ 위반 예시Non-compliant example
#include <stdexcept>
static void may_throw(int argc) { if (argc >= 0) throw std::runtime_error("x"); }
static void f(int argc) noexcept { may_throw(argc); } // noexcept 인데 예외 탈출 → terminate
int main(int argc, char**) { f(argc); }✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
static void may_throw() { throw std::runtime_error("x"); }
static void f() noexcept {
try { may_throw(); }
catch (...) { std::cout << "absorbed inside noexcept fn\n"; } // 명세 준수
}
int main() { f(); }⚠️ 근거: noexcept 로 선언한 함수에서 예외가 빠져나가면 표준은 즉시 std::terminate 를 호출하도록 규정하며 이는 되돌릴 수 없다. 영향: 호출자가 noexcept 를 믿고 예외 처리를 생략한 상태에서 프로그램이 정리 없이 강제 종료되고, 이동 연산이 noexcept 가 아니면 표준 컨테이너가 더 느린 복사 경로를 택하는 부작용도 있다. 대응: noexcept 함수 내부에서 예외를 try/catch 로 흡수하거나, 예외가 빠져나갈 수 있으면 noexcept 를 떼어 명세를 사실에 맞춘다.Rationale: if an exception escapes a function declared noexcept, the standard mandates an immediate, unrecoverable call to std::terminate. Impact: callers that trusted noexcept and omitted handling see the program forcibly terminated without cleanup, and a move operation that is not noexcept has the side effect of standard containers choosing a slower copy path. Fix: absorb exceptions inside the noexcept function with try/catch, or remove noexcept so the specification matches reality if exceptions can escape.
A15-4-4Required · Automated✓ compilable
예외를 던지지 않는 함수는 noexcept 로 표시한다A declaration of a non-throwing function shall contain noexcept
❌ 위반 예시Non-compliant example
#include <iostream>
struct Buf {
int n_ = 0;
int size() const { return n_; } // 던지지 않는데 noexcept 미표시
};
int main() { Buf b; std::cout << b.size() << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
struct Buf {
int n_ = 0;
int size() const noexcept { return n_; } // 비-throw 보장을 명시
};
int main() { Buf b; std::cout << b.size() << '\n'; }⚠️ 근거: 예외를 절대 던지지 않는 함수에 noexcept 를 명시하면, 호출자와 표준 라이브러리가 그 보장에 기대 더 나은 최적화와 예외 안전 결정을 내릴 수 있다. 영향: 특히 이동 생성자·소멸자·swap 이 noexcept 가 아니면 std::vector 같은 컨테이너가 강한 예외 보장을 위해 이동 대신 복사를 선택해 성능이 저하되고, 인터페이스의 비-throw 의도가 코드에 드러나지 않는다. 대응: 던지지 않음이 확실한 함수(특히 이동·swap·관찰자)에 noexcept 를 붙여 보장을 명시한다.Rationale: marking a function that never throws as noexcept lets callers and the standard library rely on that guarantee for better optimization and exception-safety decisions. Impact: in particular, when a move constructor, destructor, or swap is not noexcept, containers like std::vector choose copy over move to preserve the strong guarantee, degrading performance, and the non-throwing intent of the interface is not visible in the code. Fix: add noexcept to functions that certainly do not throw (especially move, swap, and observers) to state the guarantee.
A15-5-1Required · Automated✓ compilable
특수 멤버(소멸자·이동·swap)는 예외를 던지지 않게 한다All user-provided class destructors, deallocation functions, move constructors, move assignment operators and swap functions shall not exit with an exception
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
struct Conn {
bool open_ = true;
void send_close() { throw std::runtime_error("net error"); }
~Conn() { if (open_) send_close(); } // 던지는 소멸자 — 스택 풀기 중이면 terminate
};
int main() {
try { Conn c; } catch (const std::exception& e) { std::cout << e.what() << '\n'; }
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct Conn {
bool open_ = true;
void send_close() { throw std::runtime_error("net error"); }
~Conn() noexcept {
try { if (open_) send_close(); }
catch (...) { std::cerr << "close failed in dtor, logged\n"; } // 흡수
}
};
int main() { Conn c; std::cout << "clean\n"; }⚠️ 근거: 소멸자·이동 연산·swap 은 예외 안전성의 기반으로, 다른 예외로 스택이 풀리는 도중 이들이 또 예외를 던지면 두 예외가 동시에 전파되어 std::terminate 가 호출된다. 영향: 던지는 소멸자는 정상 오류 처리 경로에서도 프로그램을 강제 종료시키고, 던지는 이동 연산은 컨테이너가 강한 예외 보장을 깨뜨려 객체를 일관성 없는 상태로 남길 수 있다. 대응: 이 특수 멤버들을 noexcept 로 선언하고 내부에서 발생 가능한 예외를 try/catch 로 흡수해 로깅만 한다.Rationale: destructors, move operations, and swap are the foundation of exception safety, and if they themselves throw while the stack is already unwinding from another exception, two exceptions propagate at once and std::terminate is called. Impact: a throwing destructor forcibly terminates the program even on a normal error path, and a throwing move operation can break the strong guarantee of containers and leave objects in an inconsistent state. Fix: declare these special members noexcept and absorb any internal exception with try/catch, logging only.
A15-0-1Required · Non-automated✓ compilable📄 공식 예제Official example
non-automated) A function shall not exit with an exception if it is able to complete its task.non-automated) A function shall not exit with an exception if it is able to complete its task.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstdint>
#include <cstddef>
//% $Id: A15-0-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <fstream>
#include <stdexcept>
#include <string>
#include <vector>
std::uint8_t ComputeCrc(std::string& msg) { return 0; }
bool IsMessageCrcCorrect1(std::string& message)
{
std::uint8_t computedCRC = ComputeCrc(message);
std::uint8_t receivedCRC = message.at(0);
if (computedCRC != receivedCRC)
{
throw std::logic_error(
"Computed CRC is invalid."); // Non-compliant - CheckMessageCRC()
// was able to perform
// its task, nothing exceptional about its invalid result
}
return true;
}
bool IsMessageCrcCorrect2(std::string& message)
{
bool isCorrect = true;
std::uint8_t computedCRC = ComputeCrc(message);
std::uint8_t receivedCRC = message.at(0);
if (computedCRC != receivedCRC)
{
isCorrect =
false; // Compliant - if CRC is not correct, then return "false"
}
return isCorrect;
}
void SendData(std::string message)
{
if (message.empty())
{
throw std::logic_error("Preconditions are not met."); // Compliant -
// SendData() was
// not able to
// perform its
// task
}
bool sendTimeoutReached = false;
// Implementation
if (sendTimeoutReached)
{
throw std::runtime_error(
"Timeout on sending a message has been reached."); // Compliant -
// SendData()
// did not
// perform its
// task
}
}
std::int32_t FindIndex(std::vector<std::int32_t>& v, std::int32_t x) noexcept
{
try
{
std::size_t size = v.size();
for (std::size_t i = 0U; i < size; ++i)
{
if (v.at(i) == x) // v.at() throws an std::out_of_range exception
{
throw i; // Non-compliant - nothing exceptional about finding a
// value in vector
}
}
}
catch (std::size_t
foundIdx) // Non-compliant - nothing exceptional about finding a
// value in vector
{
return foundIdx;
}
catch (std::out_of_range&
e) // Compliant - std::out_of_range error shall be handled
{
return -1;
}
return -1;
}
bool ReadFile(std::string& filename) noexcept
{
try
{
std::ifstream file(filename, std::ios_base::in);
if (!file.is_open())
{
throw std::runtime_error(
"File cannot be opened"); // Compliant - error on opening a
// file is an exceptional case
}
char c = file.get();
if (!file.good())
{
throw std::runtime_error(
"Cannot read from file"); // Compliant - error on reading from
// file is an exceptional case
}
}
catch (std::exception& e)
{
return false;
}
return true;
}
void Fn1(
std::uint32_t x) // Non-compliant - inefficient and less readable version
// than its obvious alternative, e.g. fn2()
// function
{
try
{
if (x < 10)
{
throw 10;
}
// Action "A"
}
catch (std::int32_t y)
{
// Action "B"
}
}
void Fn2(
std::uint32_t x) // Compliant - the same functionality as fn1() function
{
if (x < 10)
{
// Action "B"
}
else
{
// Action "A"
}
}⚠️ “The notion of an exception is provided to help get information from the point where an
error is detected to a point where it can be handled. A function that cannot cope with
a problem throws an exception, hoping that its (direct or indirect) caller can handle the
problem. A function that wants to handle a kind of problem indicates that by catching
the corresponding exception. ” [The C++ Programming Language [14]]
Exceptions are only supposed to be used to capture incorrect, and which is not
expected to be seen in normal program, execution. Using exception handling
mechanism to transfer control back up the call stack, in error-free situation, leads to
code that is difficult to understand and significantly less efficient than returning from a
function.
Note that most of the monitoring or supervision functions are not supposed to throw an
exception when an error is detected.
See also:
• MISRA C++ 2008 [7]: 15-0-1 (Document) Exceptions shall only be used for error
handling.
• C++ Core Guidelines [11]: E.3: Use exceptions for error handling only
• Effective Java 2nd Edition [15]: Item 57: Use exceptions only for exceptional
conditions
• The C++ Programming Language [14], 13.1.1. Exceptions“The notion of an exception is provided to help get information from the point where an
error is detected to a point where it can be handled. A function that cannot cope with
a problem throws an exception, hoping that its (direct or indirect) caller can handle the
problem. A function that wants to handle a kind of problem indicates that by catching
the corresponding exception. ” [The C++ Programming Language [14]]
Exceptions are only supposed to be used to capture incorrect, and which is not
expected to be seen in normal program, execution. Using exception handling
mechanism to transfer control back up the call stack, in error-free situation, leads to
code that is difficult to understand and significantly less efficient than returning from a
function.
Note that most of the monitoring or supervision functions are not supposed to throw an
exception when an error is detected.
See also:
• MISRA C++ 2008 [7]: 15-0-1 (Document) Exceptions shall only be used for error
handling.
• C++ Core Guidelines [11]: E.3: Use exceptions for error handling only
• Effective Java 2nd Edition [15]: Item 57: Use exceptions only for exceptional
conditions
• The C++ Programming Language [14], 13.1.1. Exceptions
A15-0-2Required · Partially automated✓ compilable📄 공식 예제Official example
automated) At least the basic guarantee for exception safety shall be provided for all operations. In addition, each function may offer either the strong guarantee or the nothrow guaranteeautomated) At least the basic guarantee for exception safety shall be provided for all operations. In addition, each function may offer either the strong guarantee or the nothrow guarantee
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef>
#include <stdexcept>
//% $Id: A15-0-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <cstring>
class C1
{
public:
C1(const C1& rhs)
{
CopyBad(rhs); // Non-compliant - if an exception is thrown, an object
// will be left in an indeterminate state
CopyGood(rhs); // Compliant - full object will be properly copied or
// none of its properties will be changed
}
~C1() { delete[] e; }
void CopyBad(const C1& rhs)
{
if (this != &rhs)
{
delete[] e;
e = nullptr; // e changed before the block where an exception can
// be thrown
s = rhs.s; // s changed before the block where an exception can be
// thrown
if (s > 0)
{
e = new std::int32_t[s]; // If an exception will be thrown
// here, the
// object will be left in an indeterminate
// state
std::memcpy(e, rhs.e, s * sizeof(std::int32_t));
}
}
}
void CopyGood(const C1& rhs)
{
std::int32_t* eTmp = nullptr;
if (rhs.s > 0)
{
eTmp = new std::int32_t[rhs.s]; // If an exception will be thrown
// here, the
// object will be left unchanged
std::memcpy(eTmp, rhs.e, rhs.s * sizeof(std::int32_t));
}
delete[] e;
e = eTmp;
s = rhs.s;
}
private:
std::int32_t* e;
std::size_t s;
};
class A
{
public:
A() = default;
};
class C2
{
public:
C2() : a1(new A), a2(new A) // Non-compliant - if a2 memory allocation
// fails, a1 will never be deallocated
{
}
private:
A* a1;
A* a2;
};
class C3
{
public:
C3() : a1(nullptr), a2(nullptr) // Compliant
{
try
{
a1 = new A;
a2 = new A; // If memory allocation for a2 fails, catch-block will
// deallocate a1
}
catch (...)
{
delete a1;
a1 = nullptr;
delete a2;
a2 = nullptr;
throw;
}
}
private:
A* a1;
A* a2;
};⚠️ Exceptions introduce additional data flow into a program. It is important to consider all
the effects of code taking such paths to always recover from an exception error properly
and always preserve object’s invariants.
“Well-designed functions are exception safe, meaning they offer at least the basic
exception safety guarantee (i.e., the basic guarantee). Such functions assure callers
that even if an exception is thrown, program invariants remain intact (i.e., no data
structures are corrupted) and no resources are leaked. Functions offering the strong
exception safety guarantee (i.e., the strong guarantee) assure callers that if an
exception arises, the state of the program remains as it was prior to the call. ” [effective
modern c++]
The C++ standard library always provides one of the following guarantees for its
operations, the same needs to be followed by code compliant to the guidelines. “
• Basic guarantee for all operations: The basic invariants of all objects are
maintained, and no resources, such as memory , are leaked. In particular, the
basic invariants of every built-in and standard-library type guarantee that you can
destroy an object or assign to it after every standard-library operation
• Strong guarantee for key operations: in addition to providing the basic guarantee,
either the operation succeeds, or it has no effect.
• Nothrow guarantee for some operations: in addition to providing the basic
guarantee, some operations are guaranteed not to throw any exception.
” [C++ Programming Reference]
Nothrow means in this context that the function not only does not exit with an exception,
but also that internally an exception cannot occur.
See also:
• SEI CERT C++ [10]: ERR56-CPP . Guarantee exception safetyExceptions introduce additional data flow into a program. It is important to consider all
the effects of code taking such paths to always recover from an exception error properly
and always preserve object’s invariants.
“Well-designed functions are exception safe, meaning they offer at least the basic
exception safety guarantee (i.e., the basic guarantee). Such functions assure callers
that even if an exception is thrown, program invariants remain intact (i.e., no data
structures are corrupted) and no resources are leaked. Functions offering the strong
exception safety guarantee (i.e., the strong guarantee) assure callers that if an
exception arises, the state of the program remains as it was prior to the call. ” [effective
modern c++]
The C++ standard library always provides one of the following guarantees for its
operations, the same needs to be followed by code compliant to the guidelines. “
• Basic guarantee for all operations: The basic invariants of all objects are
maintained, and no resources, such as memory , are leaked. In particular, the
basic invariants of every built-in and standard-library type guarantee that you can
destroy an object or assign to it after every standard-library operation
• Strong guarantee for key operations: in addition to providing the basic guarantee,
either the operation succeeds, or it has no effect.
• Nothrow guarantee for some operations: in addition to providing the basic
guarantee, some operations are guaranteed not to throw any exception.
” [C++ Programming Reference]
Nothrow means in this context that the function not only does not exit with an exception,
but also that internally an exception cannot occur.
See also:
• SEI CERT C++ [10]: ERR56-CPP . Guarantee exception safety
A15-0-4Required · Non-automated✓ compilable📄 공식 예제Official example
non-automated) Unchecked exceptions shall be used to represent errors from which the caller cannot reasonably be expected to recover. --- PAGE 269 ---non-automated) Unchecked exceptions shall be used to represent errors from which the caller cannot reasonably be expected to recover. --- PAGE 269 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A15-0-4.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #include <cstdint> #include <stdexcept> #include <vector> class InvalidArguments : public std::logic_error // Compliant - invalid // arguments error is // "unchecked" exception { public: using std::logic_error::logic_error; }; class OutOfMemory : public std::bad_alloc // Compliant - insufficient memory // error is "unchecked" exception { public: using std::bad_alloc::bad_alloc; }; class DivisionByZero : public std::logic_error // Compliant - division by zero // error is "unchecked" // exception { public: using std::logic_error::logic_error; }; class CommunicationError : public std::logic_error // Non-compliant - // communication error // should be "checked" // exception but defined to be "unchecked" { public: using std::logic_error::logic_error; }; double Division(std::int32_t a, std::int32_t b) noexcept(false) { // ... if (b == 0) { throw DivisionByZero( "Division by zero error"); // Unchecked exception thrown correctly } // ... } void Allocate(std::uint32_t bytes) noexcept(false) { // ... throw OutOfMemory(); // Unchecked exception thrown correctly } void InitializeSocket() noexcept(false) { bool validParameters = true; // ... if (!validParameters) { throw InvalidArguments("Invalid parameters passed"); // Unchecked // exception // thrown // correctly } } void SendData(std::int32_t socket) noexcept(false) { // ... bool isSentSuccessfully = true; // ... if (!isSentSuccessfully) { throw CommunicationError("Could not send data"); // Unchecked exception // thrown when checked // exception should // be. } } void IterateOverContainer(const std::vector<std::int32_t>& container, std::uint64_t length) noexcept(false) { for (std::uint64_t idx{0U}; idx < length; ++idx) { int32_t value = container.at(idx); // at() throws std::out_of_range // exception when passed integer // exceeds the size of container. // Unchecked exception thrown // correctly } }
⚠️ Problems that are unpreventable and not expected by the caller are represented with
instances of unchecked exceptions category . Such problems include:
• Software errors, i.e. preconditions/postconditions violations, arithmetic errors,
failed assertions, sanity checks or invalid variable access, that in C++ are typically
represented by logic_error, bad_exception, bad_cast and bad_typeid exceptions
or their subclasses
• Internal errors of the executable (like VirtualMachineError of Java language), that
in C++ are represented by bad_alloc and bad_array_new_length exceptions
It is not possible to recover from such errors in a meaningful way .
See also:
• Effective Java: Item 58: Use checked exceptions for recoverable conditions and
runtime exceptions for programming errors, Item 60: Favor the use of standard
exceptionsProblems that are unpreventable and not expected by the caller are represented with
instances of unchecked exceptions category . Such problems include:
• Software errors, i.e. preconditions/postconditions violations, arithmetic errors,
failed assertions, sanity checks or invalid variable access, that in C++ are typically
represented by logic_error, bad_exception, bad_cast and bad_typeid exceptions
or their subclasses
• Internal errors of the executable (like VirtualMachineError of Java language), that
in C++ are represented by bad_alloc and bad_array_new_length exceptions
It is not possible to recover from such errors in a meaningful way .
See also:
• Effective Java: Item 58: Use checked exceptions for recoverable conditions and
runtime exceptions for programming errors, Item 60: Favor the use of standard
exceptions
A15-0-5Required · Non-automated✓ compilable📄 공식 예제Official example
non-automated) Checked exceptions shall be used to represent errors from which the caller can reasonably be expected to recover.non-automated) Checked exceptions shall be used to represent errors from which the caller can reasonably be expected to recover.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <thread> //% $Id: A15-0-5.cpp 309502 2018-02-28 09:17:39Z michal.szczepankiewicz $ #include <cstdint> #include <stdexcept> #include <system_error> // @checkedException class CommunicationError : public std::exception // Compliant - communication error is "checked" { public: explicit CommunicationError(const char * message) : msg(message) {} CommunicationError(CommunicationError const&) noexcept = default; CommunicationError& operator=(CommunicationError const&) noexcept = default; ~CommunicationError() override = default; const char * what() const noexcept override { return msg; } private: const char * msg; }; // @checkedException class BusError : public CommunicationError // Compliant - bus error is "checked" { public: using CommunicationError::CommunicationError; }; // @checkedException class Timeout : public std::runtime_error // Compliant - communication timeout // is "checked" { public: using std::runtime_error::runtime_error; }; // @checkedException class PreconditionsError : public std::exception // Non-compliant - error on // preconditions check should // be "unchecked" but is // defined to be "checked" { // Implementation }; void Fn1(std::uint8_t * buffer, std::uint8_t bufferLength) noexcept(false) { bool sentSuccessfully = true; // ... if (!sentSuccessfully) { throw CommunicationError( "Could not send data"); // Checked exception thrown correctly } } void Fn2(std::uint8_t * buffer, std::uint8_t bufferLength) noexcept(false) { bool initSuccessfully = true; if (!initSuccessfully) { throw PreconditionsError(); // An exception thrown on preconditions // check failure should be "Unchecked", but // PreconditionsError is "Checked" } // ... bool sentSuccessfully = true; bool isTimeout = false; // ... if (!sentSuccessfully) { throw BusError( "Could not send data"); // Checked exception thrown correctly } // ... if (isTimeout) { throw Timeout("Timeout reached"); // Checked exception thrown correctly } } void Fn3(std::uint8_t * buffer) noexcept(false) { bool isResourceBusy = false; // ... if (isResourceBusy) { throw std::runtime_error( "Resource is busy now"); // Checked exception thrown correctly } } class Thread // Class which mimics the std::thread { public: // Implementation Thread() noexcept(false) { bool resourcesAvailable = false; // ... if (!resourcesAvailable) { throw std::system_error( static_cast<int>(std::errc::resource_unavailable_try_again), std::generic_category()); // Compliant - correct usage of // checked exception system_error } } };
⚠️ All expected by the caller, but also reasonable to recover from, problems are
represented with instances of checked exceptions. Such problems include input/output
and other application’s runtime errors. It is possible to handle such errors in a
meaningful way .
“Overuse of checked exceptions can make an API far less pleasant to use. If a method
throws one or more checked exceptions, the code that invokes the method must handle
the exceptions in one or more catch blocks, or it must declare that it throws the
exceptions and let them propagate outward. Either way , it places a nontrivial burden
on the programmer.
The burden is justified if the exceptional condition cannot be prevented by proper
use of the API and the programmer using the API can take some useful action once
confronted with the exception. Unless both of these conditions hold, an unchecked
exception is more appropriate. ” [Effective Java 2nd Edition [15]]
See also:
• Effective Java: Item 58 - Use checked exceptions for recoverable conditions and
runtime exceptions for programming errors.All expected by the caller, but also reasonable to recover from, problems are
represented with instances of checked exceptions. Such problems include input/output
and other application’s runtime errors. It is possible to handle such errors in a
meaningful way .
“Overuse of checked exceptions can make an API far less pleasant to use. If a method
throws one or more checked exceptions, the code that invokes the method must handle
the exceptions in one or more catch blocks, or it must declare that it throws the
exceptions and let them propagate outward. Either way , it places a nontrivial burden
on the programmer.
The burden is justified if the exceptional condition cannot be prevented by proper
use of the API and the programmer using the API can take some useful action once
confronted with the exception. Unless both of these conditions hold, an unchecked
exception is more appropriate. ” [Effective Java 2nd Edition [15]]
See also:
• Effective Java: Item 58 - Use checked exceptions for recoverable conditions and
runtime exceptions for programming errors.
A15-0-6Required · Non-automated✓ compilable📄 공식 예제Official example
An analysis shall be performed to analyze the failure modes of exception handling. In particular, the following failure modes shall be analyzed: (a) worst time execution time not existing or cannot be determined, (b) stack not correctly unwound, (c) exception not thrown, other exception thrown, wrong catch activated, (d) memory not available while exception handling.An analysis shall be performed to analyze the failure modes of exception handling. In particular, the following failure modes shall be analyzed: (a) worst time execution time not existing or cannot be determined, (b) stack not correctly unwound, (c) exception not thrown, other exception thrown, wrong catch activated, (d) memory not available while exception handling.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A15-0-6: An analysis shall be performed to analyze the failure modes of exception handling. In particular, the following failure modes shall be analyzed: (a) worst time execution time not existing or cannot be determined, (b) stack not correctly unwound, (c) exception not thrown, other exception thrown, wrong catch activated, (d) memory not available while exception handling. // No code example provided in the official guideline PDF.
⚠️ Note that the worst-case execution time and behavior of exception handling can be
hardware specific. This rule requires only that the exception handling is deterministic
in the sense that it has a deterministic behavior.
Note: this analysis can be performed by the compiler supplier or it can be done by the
project.
See also:
• noneNote that the worst-case execution time and behavior of exception handling can be
hardware specific. This rule requires only that the exception handling is deterministic
in the sense that it has a deterministic behavior.
Note: this analysis can be performed by the compiler supplier or it can be done by the
project.
See also:
• none
A15-0-8Required · Non-automated✓ compilable📄 공식 예제Official example
A worst-case execution time (WCET) analysis shall be performed to determine maximum execution time constraints of the software, covering in particular the exceptions processing.A worst-case execution time (WCET) analysis shall be performed to determine maximum execution time constraints of the software, covering in particular the exceptions processing.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A15-0-8: A worst-case execution time (WCET) analysis shall be performed to determine maximum execution time constraints of the software, covering in particular the exceptions processing. // No code example provided in the official guideline PDF.
⚠️ Some systems require a guarantee that an action will be performed within predictable
time constraints. Such real-time systems are allowed to use exception handling
mechanism only if there is a tool support for accurate predicting such maximum time
boundaries.
“Before deciding that you cannot afford or don’t like exception-based error handling,
have a look at the alternatives; they have their own complexities and problems. Also, as
far as possible, measure before making claims about efficiency . ” [C++ Core Guidelines]
See also:
• MISRA C++ 2008 [7]: 15-0-1 (Document) Exceptions shall only be used for error
handling.
• open-std.org [18]: ISO/IEC TR 18015:2006(E). Technical Report on C++
Performance
6.15.1 Throwing an exceptionSome systems require a guarantee that an action will be performed within predictable
time constraints. Such real-time systems are allowed to use exception handling
mechanism only if there is a tool support for accurate predicting such maximum time
boundaries.
“Before deciding that you cannot afford or don’t like exception-based error handling,
have a look at the alternatives; they have their own complexities and problems. Also, as
far as possible, measure before making claims about efficiency . ” [C++ Core Guidelines]
See also:
• MISRA C++ 2008 [7]: 15-0-1 (Document) Exceptions shall only be used for error
handling.
• open-std.org [18]: ISO/IEC TR 18015:2006(E). Technical Report on C++
Performance
6.15.1 Throwing an exception
A15-1-3Advisory · Automated✓ compilable📄 공식 예제Official example
All thrown exceptions should be unique.All thrown exceptions should be unique.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstdint>
//% $Id: A15-1-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
static std::string ComposeMessage(const char * file,
const char * func,
std::int32_t line,
const std::string& message) noexcept
{
std::stringstream s;
s << "(" << file << ", " << func << ":" << line << "): " << message;
return s.str();
}
void F1()
{
// ...
throw std::logic_error("Error");
}
void F2()
{
// ...
throw std::logic_error("Error"); // Non-compliant - both exception type and
// error message are not unique
}
void F3()
{
// ...
throw std::invalid_argument(
"Error"); // Compliant - exception type is unique
}
void F4() noexcept(false)
{
// ...
throw std::logic_error("f3(): preconditions were not met"); // Compliant -
// error
// message is
// unique
}
void F5() noexcept(false)
{
// ...
throw std::logic_error(ComposeMessage(
__FILE__,
__func__,
__LINE__,
"postconditions were not met")); // Compliant - error message is unique
}
void F6() noexcept
{
try
{
F1();
F2();
F3();
}
catch (std::invalid_argument& e)
{
std::cout << e.what() << '\n'; // Only f3() throws this type of
// exception, it is easy to deduce which
// function threw
}
catch (std::logic_error& e)
{
std::cout << e.what() << '\n'; // f1() and f2() throw exactly the same
// exceptions, unable to deduce which
// function threw
}
try
{
F4();
F5();
}
catch (std::logic_error& e)
{
std::cout << e.what() << '\n'; // Debugging process simplified, because
// of unique error message it is known
// which function threw
}
}⚠️ Defining unique exceptions in the project significantly simplifies debug process.
An exception is considered to be unique if at least one of the following conditions is
fulfilled:
• The type of the exception does not occur in any other place in the project
• The error message (i.e. message itself, error code, etc.) of the exception does
not occur in any other place in the project
See also:
• Effective Java 2nd Edition [15]: Item 63: Include failure-capture information in
detail messagesDefining unique exceptions in the project significantly simplifies debug process.
An exception is considered to be unique if at least one of the following conditions is
fulfilled:
• The type of the exception does not occur in any other place in the project
• The error message (i.e. message itself, error code, etc.) of the exception does
not occur in any other place in the project
See also:
• Effective Java 2nd Edition [15]: Item 63: Include failure-capture information in
detail messages
A15-1-4Required · Partially automated✓ compilable📄 공식 예제Official example
If a function exits with an exception, then before a throw, the function shall place all objects/resources that the function constructed in valid states or it shall delete them.If a function exits with an exception, then before a throw, the function shall place all objects/resources that the function constructed in valid states or it shall delete them.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A15-1-4.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <memory>
#include <stdexcept>
std::uint32_t F1() { return 0; }
void FVeryBad() noexcept(false)
{
std::logic_error* e = new std::logic_error("Logic Error 1");
// ...
std::uint32_t i = F1();
if (i < 10)
{
throw(*e); // Non-compliant - fVeryBad() is not able to clean-up
// allocated memory
}
// ...
delete e;
}
void FBad() noexcept(false)
{
std::int32_t* x = new std::int32_t(0);
// ...
std::uint32_t i = F1();
if (i < 10)
{
throw std::logic_error("Logic Error 2"); // Non-compliant - exits from
// fBad() without cleaning-up
// allocated resources and
// causes a memory leak
}
else if (i < 20)
{
throw std::runtime_error("Runtime Error 3"); // Non-compliant - exits
// from fBad() without
// cleaning-up allocated
// resources and causes a
// memory leak
}
// ...
delete x; // Deallocates claimed resource only in the end of fBad() scope
}
void FGood() noexcept(false)
{
std::int32_t* y = new std::int32_t(0);
// ...
std::uint32_t i = F1();
if (i < 10)
{
delete y; // Deletes allocated resource before throwing an exception
throw std::logic_error("Logic Error 4"); // Compliant - deleting y
// variable before exception
// leaves the fGood() scope
}
else if (i < 20)
{
delete y; // Deletes allocated resource before throwing an exception
throw std::runtime_error("Runtime Error 5"); // Compliant - deleting y
// variable before
// exception leaves the
// fGood() scope
}
else if (i < 30)
{
delete y; // Deletes allocated resource before throwing an exception
// again, difficult to maintain
throw std::invalid_argument(
"Invalid Argument 1"); // Compliant - deleting
// y variable before
// exception leaves the
// fGood() scope
}
// ...
delete y; // Deallocates claimed resource also in the end of fGood() scope
}
void FBest() noexcept(false)
{
std::unique_ptr<std::int32_t> z = std::make_unique<std::int32_t>(0);
// ...
std::uint32_t i = F1();
if (i < 10)
{
throw std::logic_error("Logic Error 6"); // Compliant - leaving the
// fBest() scope causes
// deallocation of all
// automatic variables, unique_ptrs, too
}
else if (i < 20)
{
throw std::runtime_error("Runtime Error 3"); // Compliant - leaving the
// fBest() scope causes
// deallocation of all
// automatic variables,
// unique_ptrs, too
}
else if (i < 30)
{
throw std::invalid_argument(
"Invalid Argument 2"); // Compliant - leaving the fBest() scope
// causes deallocation of all automatic
// variables, unique_ptrs,
// too
}
// ...
// z is deallocated automatically here, too
}
class CRaii // Simple class that follows RAII pattern
{
public:
CRaii(std::int32_t* pointer) noexcept : x(pointer) {}
~CRaii()
{
delete x;
x = nullptr;
}
private:
std::int32_t* x;
};
void FBest2() noexcept(false)
{
CRaii a1(new std::int32_t(10));
// ...
std::uint32_t i = F1();
if (i < 10)
{
throw std::logic_error("Logic Error 7"); // Compliant - leaving the
// fBest2() scope causes a1
// variable deallocation
// automatically
}
else if (i < 20)
{
throw std::runtime_error("Runtime Error 4"); // Compliant - leaving the
// fBest2() scope causes
// a1 variable
// deallocation
// automatically
}
else if (i < 30)
{
throw std::invalid_argument(
"Invalid Argument 3"); // Compliant - leaving the fBest2() scope
// causes a1 variable deallocation
// automatically
}
// ...
// a1 is deallocated automatically here, too
}⚠️ If the only handler to dynamically allocated memory or system resource (e.g. file, lock,
network connection or thread) goes out of scope due to throwing an exception, memory
leak occurs. Memory leaks lead to performance degradation, security violations and
software crashes.
Allocated memory or system resource can be released by explicit call to resource
deinitialization or memory deallocation function (such as operator delete), before each
return/try/break/continue statement. However, this solution is error prone and difficult
to maintain.
The recommended way of releasing dynamically allocated objects and resources is
to follow RAII ("‘Resource Acquisition Is Initialization"’) design pattern, also known as
Scope-Bound Resource Management or “Constructor Acquires, Destructor Releases”
(CADRe). It allows to bind the life cycle of the resource to the lifetime of a scope-bound
object. It guarantees that resources are properly deinitialized and released when data
flow reaches the end of the scope.
Examples of RAII design pattern that significantly simplifies releasing
objects/resources on throwing an exception are C++ smart pointers: std::unique_ptr
and std::shared_ptr.
See also:
• SEI CERT C++ [10]: ERR57-CPP . Do not leak resources when handling
exceptions
• C++ Core Guidelines [11]: E.6: Use RAII to prevent leaks.If the only handler to dynamically allocated memory or system resource (e.g. file, lock,
network connection or thread) goes out of scope due to throwing an exception, memory
leak occurs. Memory leaks lead to performance degradation, security violations and
software crashes.
Allocated memory or system resource can be released by explicit call to resource
deinitialization or memory deallocation function (such as operator delete), before each
return/try/break/continue statement. However, this solution is error prone and difficult
to maintain.
The recommended way of releasing dynamically allocated objects and resources is
to follow RAII ("‘Resource Acquisition Is Initialization"’) design pattern, also known as
Scope-Bound Resource Management or “Constructor Acquires, Destructor Releases”
(CADRe). It allows to bind the life cycle of the resource to the lifetime of a scope-bound
object. It guarantees that resources are properly deinitialized and released when data
flow reaches the end of the scope.
Examples of RAII design pattern that significantly simplifies releasing
objects/resources on throwing an exception are C++ smart pointers: std::unique_ptr
and std::shared_ptr.
See also:
• SEI CERT C++ [10]: ERR57-CPP . Do not leak resources when handling
exceptions
• C++ Core Guidelines [11]: E.6: Use RAII to prevent leaks.
A15-2-1Required · Automated✓ compilable📄 공식 예제Official example
Constructors that are not noexcept shall not be invoked before program startup.Constructors that are not noexcept shall not be invoked before program startup.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A15-2-1.cpp 271927 2017-03-24 12:01:35Z piotr.tanski $
#include <cstdint>
#include <stdexcept>
class A
{
public:
A() noexcept : x(0)
{
// ...
}
explicit A(std::int32_t n) : x(n)
{
// ...
throw std::runtime_error("Unexpected error");
}
A(std::int32_t i, std::int32_t j) noexcept : x(i + j)
{
try
{
// ...
throw std::runtime_error("Error");
// ...
}
catch (std::exception& e)
{
}
}
private:
std::int32_t x;
};
static A a1; // Compliant - default constructor of type A is noexcept
static A a2(5); // Non-compliant - constructor of type A throws, and the
// exception will not be caught by the handler in main function
static A a3(5, 10); // Compliant - constructor of type A is noexcept, it
// handles exceptions internally
int main(int, char **)
{
try
{
// program code
}
catch (...)
{
// Handle exceptions
}
return 0;
}⚠️ Before the program starts executing the body of main function, it is in a start-up phase,
constructing and initializing static objects. There is nowhere an exception handler can
be placed to catch exceptions thrown during this phase, so if an exception is thrown it
leads to the program being terminated in an implementation-defined manner.
Such errors may be more difficult to find because an error message can not be logged,
due to lack of exception handling mechanism during static initialization.
See also:
• SEI CERT C++ [10]: ERR51-CPP . Handle all exceptions.Before the program starts executing the body of main function, it is in a start-up phase,
constructing and initializing static objects. There is nowhere an exception handler can
be placed to catch exceptions thrown during this phase, so if an exception is thrown it
leads to the program being terminated in an implementation-defined manner.
Such errors may be more difficult to find because an error message can not be logged,
due to lack of exception handling mechanism during static initialization.
See also:
• SEI CERT C++ [10]: ERR51-CPP . Handle all exceptions.
A15-3-2Required · Non-automated✓ compilable📄 공식 예제Official example
If a function throws an exception, it shall be handled when meaningful actions can be taken, otherwise it shall be propagated.If a function throws an exception, it shall be handled when meaningful actions can be taken, otherwise it shall be propagated.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A15-3-2.cpp 309502 2018-02-28 09:17:39Z michal.szczepankiewicz $
#include <cstdint>
#include <iostream>
#include <stdexcept>
#include <memory>
/// @checkedException
class CommunicationError : public std::exception
{
// Implementation
};
/// @throw CommunicationError Exceptional communication errors
void Send(std::uint8_t * buffer) noexcept(false) {}
void SendData1(std::uint8_t * data) noexcept(false)
{
try
{
Send(data);
}
catch (CommunicationError& e)
{
std::cerr << "Communication error occured" << std::endl;
throw; // Non-compliant - exception is not handled, just re-thrown
}
}
extern void BusRestart() noexcept;
extern void BufferClean() noexcept;
void SendData2(std::uint8_t * data) noexcept(false)
{
try
{
Send(data);
}
catch (CommunicationError& e)
{
std::cerr << "Communication error occured" << std::endl;
BufferClean();
throw; // Compliant - exception is partially handled and re-thrown
}
}
void F1() noexcept
{
std::uint8_t* buffer = nullptr;
// ...
try
{
SendData2(buffer);
}
catch (CommunicationError& e)
{
std::cerr << "Communication error occured" << std::endl;
BusRestart();
// Compliant - including SendData2() exception handler, exception is now
// fully handled
}
}
void SendData3(std::uint8_t * data) noexcept
{
try
{
Send(data);
}
catch (CommunicationError& e)
{
std::cerr << "Communication error occured" << std::endl;
BufferClean();
BusRestart();
// Compliant - exception is fully handled
}
}
struct A
{
std::uint32_t x;
};
std::unique_ptr<A[]> Func1()
{
//rather throws std::bad_alloc
return std::make_unique<A[]>(999999999999999999);
}
std::unique_ptr<A[]> Func2()
{
//does not catch std::bad_alloc
//because nothing meaningful can be done here
return Func1();
}
std::unique_ptr<A[]> Func3()
{
//does not catch std::bad_alloc
//because nothing meaningful can be done here
return Func2();
}
extern void Cleanup() noexcept;
int main(void)
{
try
{
Func3();
}
catch (const std::exception& ex)
{
//catches std::bad_alloc here and
//terminates the application
//gracefully
Cleanup();
}
return 0;
}⚠️ Provide exception handlers only for functions that actually are able to take recovery
or cleanup actions. Implementing meaningless exception handlers that only re-throw
caught exception results in an implementation that is inefficient and difficult to maintain.
See also:
• noneProvide exception handlers only for functions that actually are able to take recovery
or cleanup actions. Implementing meaningless exception handlers that only re-throw
caught exception results in an implementation that is inefficient and difficult to maintain.
See also:
• none
A15-3-3Required · Automated✓ compilable📄 공식 예제Official example
Main function and a task main function shall catch at least: base class exceptions from all third-party libraries used, std::exception and all otherwise unhandled exceptions.Main function and a task main function shall catch at least: base class exceptions from all third-party libraries used, std::exception and all otherwise unhandled exceptions.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <thread>
//% $Id: A15-3-3.cpp 309502 2018-02-28 09:17:39Z michal.szczepankiewicz $
#include <stdexcept>
//base exception class from external library that is used
class ExtLibraryBaseException {};
int MainGood(int, char **) // Compliant
{
try
{
// program code
}
catch (std::runtime_error& e)
{
// Handle runtime errors
}
catch (std::logic_error& e)
{
// Handle logic errors
}
catch (ExtLibraryBaseException &e)
{
// Handle all expected exceptions
// from an external library
}
catch (std::exception& e)
{
// Handle all expected exceptions
}
catch (...)
{
// Handle all unexpected exceptions
}
return 0;
}
int MainBad(int, char **) // Non-compliant - neither unexpected exceptions
// nor external libraries exceptions are caught
{
try
{
// program code
}
catch (std::runtime_error& e)
{
// Handle runtime errors
}
catch (std::logic_error& e)
{
// Handle logic errors
}
catch (std::exception& e)
{
// Handle all expected exceptions
}
return 0;
}
void ThreadMainGood() // Compliant
{
try
{
// thread code
}
catch (ExtLibraryBaseException &e)
{
// Handle all expected exceptions
// from an external library
}
catch (std::exception& e)
{
// Handle all expected exception
}
catch (...)
{
// Handle all unexpected exception
}
}
void ThreadMainBad() // Non-compliant - neither unexpected exceptions
// nor external libraries exceptions are caught
{
try
{
// thread code
}
catch (std::exception& e)
{
// Handle all expected exceptions
}
// Uncaught unexpected exception will cause an immediate program termination
}⚠️ If a program throws an unhandled exception in main function, as well as in init thread
function, the program terminates in an implementation-defined manner. In particular,
it is implementation-defined whether the call stack is unwound, before termination, so
the destructors of any automatic objects may or may not be executed. By enforcing
the provision of a “last-ditch catch-all”, the developer can ensure that the program
terminates in a consistent manner.
Exceptions hierarchy from external libraries may be completely separate from C++
Standard Library std::exception. Handling such base exception classes separately
may provide some additional information about application termination causes.
See also:
• MISRA C++ 2008 [7]: 15-3-2 There should be at least one exception handler to
catch all otherwise unhandled exceptions.
• SEI CERT C++ [10]: ERR51-CPP . Handle all exceptions
• Effective Java 2nd Edition [15]: Item 65: Don’t ignore exceptionsIf a program throws an unhandled exception in main function, as well as in init thread
function, the program terminates in an implementation-defined manner. In particular,
it is implementation-defined whether the call stack is unwound, before termination, so
the destructors of any automatic objects may or may not be executed. By enforcing
the provision of a “last-ditch catch-all”, the developer can ensure that the program
terminates in a consistent manner.
Exceptions hierarchy from external libraries may be completely separate from C++
Standard Library std::exception. Handling such base exception classes separately
may provide some additional information about application termination causes.
See also:
• MISRA C++ 2008 [7]: 15-3-2 There should be at least one exception handler to
catch all otherwise unhandled exceptions.
• SEI CERT C++ [10]: ERR51-CPP . Handle all exceptions
• Effective Java 2nd Edition [15]: Item 65: Don’t ignore exceptions
A15-3-4Required · Non-automated✓ compilable📄 공식 예제Official example
Catch-all (ellipsis and std::exception) handlers shall be used only in (a) main, (b) task main functions, (c) in functions that are supposed to isolate independent components and (d) when calling third-party code that uses exceptions not according to AUTOSAR C++14 guidelines.Catch-all (ellipsis and std::exception) handlers shall be used only in (a) main, (b) task main functions, (c) in functions that are supposed to isolate independent components and (d) when calling third-party code that uses exceptions not according to AUTOSAR C++14 guidelines.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstdint>
//% $Id: A15-3-4.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <stdexcept>
#include <thread>
std::int32_t Fn() { return 0; } // Prototype of external third-party library function
void F1() noexcept(false)
{
try
{
std::int32_t ret = Fn();
// ...
}
// ...
catch (...) // Compliant
{
// Handle all unexpected exceptions from fn() function
}
}
void F2() noexcept(false)
{
std::int32_t ret =
Fn(); // Non-compliant - can not be sure whether fn() throws or not
if (ret < 10)
{
throw std::underflow_error("Error");
}
else if (ret < 20)
{
// ...
}
else if (ret < 30)
{
throw std::overflow_error("Error");
}
else
{
throw std::range_error("Error");
}
}
void F3() noexcept(false)
{
try
{
F2();
}
catch (std::exception& e) // Non-compliant - caught exception is too
// general, no information which error occured
{
// Nothing to do
throw;
}
}
void F4() noexcept(false)
{
try
{
F3();
}
catch (...) // Non-compliant - no information about the exception
{
// Nothing to do
throw;
}
}
class ExecutionManager
{
public:
ExecutionManager() = default;
void Execute() noexcept(false)
{
try
{
F3();
}
// ...
catch (std::exception& e) // Compliant
{
// Handle all expected exceptions
}
catch (...) // Compliant
{
// Handle all unexpected exceptions
}
}
};
void ThreadMain() noexcept
{
try
{
F3();
}
// ...
catch (std::exception& e) // Compliant
{
// Handle all expected exceptions
}
catch (...) // Compliant
{
// Handle all unexpected exceptions
}
}
int main(int, char **)
{
try
{
ExecutionManager execManager;
execManager.Execute();
// ...
std::thread t(&ThreadMain);
// ...
F4();
}
// ...
catch (std::exception& e) // Compliant
{
// Handle all expected exceptions
}
catch (...) // Compliant
{
// Handle all unexpected exceptions
}
return 0;
}⚠️ Catching an exception through catch-all handlers does not provide any detailed
information about caught exception. This does not allow to take meaningful actions
to recover from an exception other than to re-throw it. This is inefficient and results in
code that is difficult to maintain.
See also:
• noneCatching an exception through catch-all handlers does not provide any detailed
information about caught exception. This does not allow to take meaningful actions
to recover from an exception other than to re-throw it. This is inefficient and results in
code that is difficult to maintain.
See also:
• none
A15-4-1Required · Automated✓ compilable📄 공식 예제Official example
Dynamic exception-specification shall not be used.Dynamic exception-specification shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A15-4-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #include <stdexcept> void F1() noexcept; // Compliant - note that noexcept is the same as // noexcept(true) void F2() throw(); // Non-compliant - dynamic exception-specification is // deprecated void F3() noexcept(false); // Compliant void F4() throw(std::runtime_error); // Non-compliant - dynamic // exception-specification is deprecated void F5() throw( ...); // Non-compliant - dynamic exception-specification is deprecated template <class T> void F6() noexcept(noexcept(T())); // Compliant
⚠️ This feature was deprecated in the 2011 C++ Language Standard (See: Deprecating
Exception Specifications).
Main issues with dynamic exception specifications are:
1. Run-time checking: Exception specifications are checked at runtime, so the
program does not guarantee that all exceptions will be handled. The run-time
failure mode does not lend itself to recovery .
2. Run-time overhead: Run-time checking requires the compiler to produce
additional code that hampers optimizations.
3. Unusable in generic code: It is not possible to know what types of exceptions
may be thrown from templates arguments operations, so a precise exception
specification cannot be written.
In place of dynamic exception-specification, use noexcept specification that allows to
declare whether a function throws or does not throw exceptions.
Note: std::unexpected_handler shall not be used.
See also:
• C++ Core Guidelines [11]: E.12: Use noexcept when exiting a function because
of a throw is impossible or unacceptable
• open-std.org [18]: open std Deprecating Exception Specifications
• mill22: A Pragmatic Look at Exception SpecificationsThis feature was deprecated in the 2011 C++ Language Standard (See: Deprecating
Exception Specifications).
Main issues with dynamic exception specifications are:
1. Run-time checking: Exception specifications are checked at runtime, so the
program does not guarantee that all exceptions will be handled. The run-time
failure mode does not lend itself to recovery .
2. Run-time overhead: Run-time checking requires the compiler to produce
additional code that hampers optimizations.
3. Unusable in generic code: It is not possible to know what types of exceptions
may be thrown from templates arguments operations, so a precise exception
specification cannot be written.
In place of dynamic exception-specification, use noexcept specification that allows to
declare whether a function throws or does not throw exceptions.
Note: std::unexpected_handler shall not be used.
See also:
• C++ Core Guidelines [11]: E.12: Use noexcept when exiting a function because
of a throw is impossible or unacceptable
• open-std.org [18]: open std Deprecating Exception Specifications
• mill22: A Pragmatic Look at Exception Specifications
A15-4-3Required · Automated✓ compilable📄 공식 예제Official example
The noexcept specification of a function shall either be identical across all translation units, or identical or more restrictive between a virtual member function and an overrider.The noexcept specification of a function shall either be identical across all translation units, or identical or more restrictive between a virtual member function and an overrider.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <stdexcept> //% $Id: A15-4-3.cpp 317753 2018-04-27 07:44:02Z jan.babst $ // f1.hpp void Fn() noexcept; // f1.cpp // #include <f1.hpp> void Fn() noexcept // Compliant { // Implementation } // f2.cpp // #include <f1.hpp> void Fn_bad() noexcept(false) // Non-compliant - different exception specifier { // Implementation } class A { public: void F() noexcept; void G() noexcept(false); virtual void V1() noexcept = 0; virtual void V2() noexcept(false) = 0; }; void A::F() noexcept // Compliant // void A::F() noexcept(false) // Non-compliant - different exception specifier // than in declaration { // Implementation } void A::G() noexcept(false) // Compliant // void A::G() noexcept // Non-compliant - different exception specifier than // in declaration { // Implementation } class B : public A { public: void V1() noexcept override // Compliant // void V1() noexcept(false) override // Non-compliant - less restrictive // exception specifier in derived method, non-compilable { // Implementation } void V2() noexcept override // Compliant - stricter noexcept specification { // Implementation } };
⚠️ Declarations of the same function, even in different translation units, have to specify
the same noexcept specification. Overriding functions have to specify the same or a
stricter noexcept specification than the base class function which they override.
Note that in many cases, a violation of this rule will lead to a compilation error. This is
not guaranteed, however, in particular when function declarations appear in separate
translation units.
See also:
• MISRA C++ 2008 [7]: 15-4-1: If a function is declared with an exception-
specification, then all declarations of the same function (in other translation units)
shall be declared with the same set of type-ids.Declarations of the same function, even in different translation units, have to specify
the same noexcept specification. Overriding functions have to specify the same or a
stricter noexcept specification than the base class function which they override.
Note that in many cases, a violation of this rule will lead to a compilation error. This is
not guaranteed, however, in particular when function declarations appear in separate
translation units.
See also:
• MISRA C++ 2008 [7]: 15-4-1: If a function is declared with an exception-
specification, then all declarations of the same function (in other translation units)
shall be declared with the same set of type-ids.
A15-4-5Required · Automated✓ compilable📄 공식 예제Official example
Checked exceptions that could be thrown from a function shall be specified together with the function declaration and they shall be identical in all function declarations and for all its overriders.Checked exceptions that could be thrown from a function shall be specified together with the function declaration and they shall be identical in all function declarations and for all its overriders.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A15-4-5.cpp 309502 2018-02-28 09:17:39Z michal.szczepankiewicz $
#include <cstdint>
#include <stdexcept>
/// @checkedException
class CommunicationError : public std::exception
{
// Implementation
};
/// @checkedException
class BusError : public CommunicationError
{
// Implementation
};
/// @checkedException
class Timeout : public std::runtime_error
{
public:
using std::runtime_error::runtime_error;
// Implementation
};
/// @throw CommunicationError Communication error
/// @throw BusError Bus error
/// @throw Timeout On send timeout exception
void Send1(
std::uint8_t* buffer,
std::uint8_t bufferLength) noexcept(false) // Compliant - All and only
// those checked exceptions
// that can be thrown are
// specified
{
// ...
throw CommunicationError();
// ...
throw BusError();
// ...
throw Timeout("Timeout reached");
// ...
}
/// @throw CommunicationError Communication error
void Send2(
std::uint8_t* buffer,
std::uint8_t bufferLength) noexcept(false) // Non-compliant - checked
// exceptions that can be
// thrown are missing from
// specification
{
// ...
throw CommunicationError();
// ...
throw Timeout("Timeout reached");
// ...
}
class MemoryPartitioningError : std::exception
{
// Implementation
};
/// @throw CommunicationError Communication error
/// @throw BusError Bus error
/// @throw Timeout On send timeout exception
/// @throw MemoryPartitioningError Memory partitioning error prevents message
/// from being sent.
void Send3(
std::uint8_t* buffer,
std::uint8_t bufferLength) noexcept(false) // Non-compliant - additional
// checked exceptions are
// specified
{
// ...
throw CommunicationError();
// ...
throw Timeout("Timeout reached");
// ...
}⚠️ In C++ language, all exceptions are unchecked, because the compiler does not force
to either handle the exception or specify it. Because dynamic-exception specification is
obsolete and error prone, an alternative mechanism of specifying checked exceptions
using C++ comments along with function declarations is used. It is a concept that is
based on Java exception handling mechanism.
When analyzing a given function f, a static code analysis needs to analyze functions
invoked by f and analyze if they throw any checked exceptions that are not caught by f
and not listed by f in the function comment.
Exception:
Within generic code, it is not generally possible to know what types of exceptions may
be thrown from operations on template arguments, so a precise exception specification
cannot be written. Therefore, this rule does not apply for templates.
See also:
• Effective Java 2nd Edition [15]: Item 62: Document all exceptions thrown by each
method
6.15.5 Special functionsIn C++ language, all exceptions are unchecked, because the compiler does not force
to either handle the exception or specify it. Because dynamic-exception specification is
obsolete and error prone, an alternative mechanism of specifying checked exceptions
using C++ comments along with function declarations is used. It is a concept that is
based on Java exception handling mechanism.
When analyzing a given function f, a static code analysis needs to analyze functions
invoked by f and analyze if they throw any checked exceptions that are not caught by f
and not listed by f in the function comment.
Exception:
Within generic code, it is not generally possible to know what types of exceptions may
be thrown from operations on template arguments, so a precise exception specification
cannot be written. Therefore, this rule does not apply for templates.
See also:
• Effective Java 2nd Edition [15]: Item 62: Document all exceptions thrown by each
method
6.15.5 Special functions
A15-5-2Required · Partially automated✓ compilable📄 공식 예제Official example
Program shall not be abruptly terminated. In particular, an implicit or --- PAGE 314 --- explicit invocation of std::abort(), std::quick_exit(), std::_Exit(), std::terminate() shall not be done.Program shall not be abruptly terminated. In particular, an implicit or --- PAGE 314 --- explicit invocation of std::abort(), std::quick_exit(), std::_Exit(), std::terminate() shall not be done.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cmath>
#include <stdexcept>
//% $Id: A15-5-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdlib>
#include <exception>
void F1() noexcept(false) {}
void F2() // Non-compliant
{
F1(); // A call to throwing f1() may result in an implicit call to
// std::terminate()
}
void F3() // Compliant
{
try
{
F1(); // Handles all exceptions from f1() and does not re-throw
}
catch (...)
{
// Handle an exception
}
}
void F4(const char * log)
{
// Report a log error
// ...
std::exit(0); // Call std::exit() function which safely cleans up resources
}
void F5() // Compliant by exception
{
try
{
F1();
}
catch (...)
{
F4("f1() function failed");
}
}
int main(int, char **)
{
if (std::atexit(&F2) != 0)
{
// Handle an error
}
if (std::atexit(&F3) != 0)
{
// Handle an error
}
// ...
return 0;
}⚠️ Functions that are used to terminate the program in an immediate fashion, i.e.
std::abort(), std::quick_exit(), std::_Exit(), do so without calling exit handlers or calling
destructors of automatic, thread or static storage duration objects. It is implementation-
defined whether opened streams are flushed and closed, and temporary files are
removed.
The std::terminate() function calls std::abort() implicitly in its terminate handler, and it
is implementation-defined whether or not stack unwinding will occur.
Note: std::terminate_handler shall not be used.
See also:
• MISRA C++ 2008 [7]: 15-5-3 (Required) The terminate() function shall not be
called implicitly .
• HIC++ v4.0 [9]: 15.3.2 Ensure that a program does not result in a call to
std::terminate
• SEI CERT C++ [10]: ERR50-CPP . Do not abruptly terminate the programFunctions that are used to terminate the program in an immediate fashion, i.e.
std::abort(), std::quick_exit(), std::_Exit(), do so without calling exit handlers or calling
destructors of automatic, thread or static storage duration objects. It is implementation-
defined whether opened streams are flushed and closed, and temporary files are
removed.
The std::terminate() function calls std::abort() implicitly in its terminate handler, and it
is implementation-defined whether or not stack unwinding will occur.
Note: std::terminate_handler shall not be used.
See also:
• MISRA C++ 2008 [7]: 15-5-3 (Required) The terminate() function shall not be
called implicitly .
• HIC++ v4.0 [9]: 15.3.2 Ensure that a program does not result in a call to
std::terminate
• SEI CERT C++ [10]: ERR50-CPP . Do not abruptly terminate the program
A15-5-3Required · Automated✓ compilable📄 공식 예제Official example
The std::terminate() function shall not be called implicitly.The std::terminate() function shall not be called implicitly.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A15-5-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <stdexcept>
#include <thread>
bool F1() { return true; }
class A
{
public:
A() noexcept(false)
{
// ...
throw std::runtime_error("Error1");
}
~A()
{
// ...
throw std::runtime_error("Error2"); // Non-compliant - std::terminate()
// called on throwing an exception
// from noexcept(true) destructor
}
};
class B
{
public:
~B() noexcept(false)
{
// ...
throw std::runtime_error("Error3");
}
};
void F2()
{
throw;
}
void ThreadFunc()
{
A a; // Throws an exception from a's constructor and does not handle it in
// thread_func()
}
void F3()
{
try
{
std::thread t(&ThreadFunc); // Non-compliant - std::terminate() called
// on throwing an exception from
// thread_func()
if (F1())
{
throw std::logic_error("Error4");
}
else
{
F2(); // Non-compliant - std::terminate() called if there is no
// active exception to be re-thrown by f2
}
}
catch (...)
{
B b; // Non-compliant - std::terminate() called on throwing an
// exception from b's destructor during exception handling
// ...
F2();
}
}
static A a; // Non-compliant - std::terminate() called on throwing an exception
// during program's start-up phase
int main(int, char **)
{
F3(); // Non-compliant - std::terminate() called if std::logic_error is
// thrown
return 0;
}⚠️ It is implementation-defined whether the call stack is unwound before std::terminate() is
called. There is no guarantee that the destructors of automatic thread or static storage
duration objects will be called.
These are following ways to call std::terminate() function implicitly , according to
(std::terminate() in CppReference [16]):
1. an exception is thrown and not caught (it is implementation-defined whether any
stack unwinding is done in this case)
2. an exception is thrown during exception handling (e.g. from a destructor of some
local object, or from a function that had to be called during exception handling)
3. the constructor or the destructor of a static or thread-local object throws an
exception
4. a function registered with std::atexit or std::at_quick_exit throws an exception
5. a noexcept specification is violated (it is implementation-defined whether any
stack unwinding is done in this case)
6. a dynamic exception specification is violated and the default handler for
std::unexpected is executed
7. a non-default handler for std::unexpected throws an exception that violates the
previously violated dynamic exception specification, if the specification does not
include std::bad_exception
8. std::nested_exception::rethrow_nested is called for an object that isn’t holding a
captured exception
9. an exception is thrown from the initial function of std::thread
10. a joinable std::thread is destroyed or assigned to
Note: std::terminate_handler shall not be used.
See also:
• MISRA C++ 2008 [7]: 15-5-3 (Required) The terminate() function shall not be
called implicitly .
6.16 Preprocessing directives
6.16.0 GeneralIt is implementation-defined whether the call stack is unwound before std::terminate() is
called. There is no guarantee that the destructors of automatic thread or static storage
duration objects will be called.
These are following ways to call std::terminate() function implicitly , according to
(std::terminate() in CppReference [16]):
1. an exception is thrown and not caught (it is implementation-defined whether any
stack unwinding is done in this case)
2. an exception is thrown during exception handling (e.g. from a destructor of some
local object, or from a function that had to be called during exception handling)
3. the constructor or the destructor of a static or thread-local object throws an
exception
4. a function registered with std::atexit or std::at_quick_exit throws an exception
5. a noexcept specification is violated (it is implementation-defined whether any
stack unwinding is done in this case)
6. a dynamic exception specification is violated and the default handler for
std::unexpected is executed
7. a non-default handler for std::unexpected throws an exception that violates the
previously violated dynamic exception specification, if the specification does not
include std::bad_exception
8. std::nested_exception::rethrow_nested is called for an object that isn’t holding a
captured exception
9. an exception is thrown from the initial function of std::thread
10. a joinable std::thread is destroyed or assigned to
Note: std::terminate_handler shall not be used.
See also:
• MISRA C++ 2008 [7]: 15-5-3 (Required) The terminate() function shall not be
called implicitly .
6.16 Preprocessing directives
6.16.0 General
M6M6 (MISRA 유래)M6 (MISRA-origin)
M6-2-1Required · Automated✓ compilable
대입을 하위 표현식(subexpression)에서 수행하지 않는다Assignment operators shall not be used in sub-expressions
❌ 위반 예시Non-compliant example
#include <iostream>
static int next() { static int n = 0; return ++n; }
int main() {
int x = 0;
if ((x = next()) != 0) std::cout << "x=" << x << '\n'; // 조건 안 대입 — == 오타와 혼동
}✅ 준수 예시Compliant example
#include <iostream>
static int next() { static int n = 0; return ++n; }
int main() {
int x = next(); // 대입을 독립 문장으로 분리
if (x != 0) std::cout << "x=" << x << '\n';
}⚠️ 근거: 조건식·인자 같은 하위 표현식 안에 대입을 끼워 넣으면, 의도한 = 인지 비교 == 의 오타인지 한눈에 구분되지 않고 부작용이 식 안에 숨는다. 영향: if (x = f()) 처럼 쓰면 비교를 의도했는데 대입이 일어나 항상 참이 되는 흔한 버그가 생기고, 평가 순서·부작용이 얽혀 분석이 어려워진다. 대응: 대입은 독립된 문장으로 분리해 부작용을 드러내고, 조건에는 비교만 둔다.Rationale: embedding an assignment inside a sub-expression like a condition or argument makes it hard to tell at a glance whether = is intended or a typo for ==, and hides the side effect inside the expression. Impact: writing if (x = f()) when a comparison was intended performs an assignment and is always true — a common bug — and tangles evaluation order with side effects, hindering analysis. Fix: split assignment into its own statement to expose the side effect and keep only comparisons in conditions.
M6-2-2Required · Automated✓ compilable
부동소수 값을 등호(==)로 비교하지 않는다Floating-point expressions shall not be directly or indirectly tested for equality or inequality
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
double x = 0.1 + 0.2; // 0.30000000000000004 (표현 오차)
if (x == 0.3) std::cout << "equal\n";
else std::cout << "NOT equal (representation error)\n"; // 실제로 이쪽
}✅ 준수 예시Compliant example
#include <iostream>
#include <cmath>
int main() {
double x = 0.1 + 0.2;
const double eps = 1e-9;
if (std::fabs(x - 0.3) < eps) std::cout << "equal within tolerance\n"; // 의도대로
else std::cout << "different\n";
}⚠️ 근거: 부동소수 수는 십진 소수를 이진으로 정확히 표현하지 못해 0.1 + 0.2 가 0.3 과 비트 단위로 같지 않은 등 미세한 표현 오차를 갖는다. 영향: == / != 로 정확한 동등을 검사하면 수학적으로 같아야 할 값이 거의 항상 다르다고 판정되어, 종료 조건·상태 비교가 의도와 다르게 동작한다. 대응: 두 값의 차이의 절댓값이 문제 규모에 맞는 허용 오차(epsilon) 미만인지로 비교하고, 가능하면 상대 오차도 함께 고려한다.Rationale: floating-point numbers cannot represent decimal fractions exactly in binary, so values carry tiny representation errors — for example 0.1 + 0.2 is not bit-identical to 0.3. Impact: testing exact equality with == / != judges values that should be mathematically equal as almost always different, making termination conditions and state comparisons misbehave. Fix: compare whether the absolute difference is below a tolerance (epsilon) sized to the problem, also considering relative error where possible.
M6-3-1Required · Automated✓ compilable
반복문/조건문의 본문은 복합문(중괄호)으로 감싼다The statement forming the body of a loop or selection shall be a compound statement
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int n = 3;
for (int i = 0; i < n; ++i)
std::cout << "loop ";
std::cout << "once\n"; // 들여쓰기 착시 — 사실 루프 밖, 1회만 실행
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int n = 3;
for (int i = 0; i < n; ++i) {
std::cout << "loop ";
}
std::cout << "once\n"; // 의도가 명확
}⚠️ 근거: 반복문·조건문의 본문을 중괄호 없이 단일 문으로 쓰면, 본문에 포함된 문장은 첫 한 문장뿐인데 들여쓰기는 여러 줄을 본문처럼 보이게 한다. 영향: 나중에 줄을 추가하면(예제의 둘째 출력) 그 줄이 루프 밖에 놓여 들여쓰기 착시와 실제 흐름이 어긋나는 결함이 되며, 이는 보안 패치에서 유명한 버그 유형이다. 대응: 반복문·조건문의 본문을 항상 중괄호로 감싸 범위를 명확히 한다.Rationale: writing a loop or selection body as a single statement without braces means only the first statement is in the body, yet indentation makes several lines look like the body. Impact: later adding a line (the second print in the example) places it outside the loop, creating a mismatch between the indentation illusion and the actual flow — a famously dangerous bug type in security patches. Fix: always wrap loop and selection bodies in braces to make their extent clear.
M6-4-2Required · Automated✓ compilable
if-else if 사슬은 else 로 마무리한다All if-else if constructs shall be terminated with an else statement
❌ 위반 예시Non-compliant example
#include <iostream>
static const char* mode_name(int m) {
if (m == 1) return "read";
else if (m == 2) return "write"; // 그 외 값은 처리되지 않음
return "?"; // (함수 반환이라 그나마 동작; 부작용 코드였다면 조용히 누락)
}
int main() { std::cout << mode_name(9) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
static const char* mode_name(int m) {
if (m == 1) return "read";
else if (m == 2) return "write";
else return "unknown"; // 나머지 경우를 명시적으로 처리
}
int main() { std::cout << mode_name(9) << '\n'; }⚠️ 근거: if-else if 사슬을 마지막 else 로 닫으면, 앞의 어떤 조건에도 맞지 않는 "그 외 모든 경우"가 반드시 한 곳에서 명시적으로 처리된다. 영향: else 로 닫지 않으면 예상치 못한 입력이 조용히 아무 분기도 타지 않고 지나가, 상태 갱신·검증이 누락되어 결함이 숨고 새 값 추가 시 처리가 빠진다. 대응: 모든 if-else if 사슬을 else 로 마무리해 나머지 경우를 명시 처리하거나, 최소한 도달하면 안 되는 경우임을 단언(assert)한다.Rationale: terminating an if-else if chain with a final else ensures that the "all other cases" not matching any prior condition is handled explicitly in one place. Impact: without a closing else, unexpected input silently falls through taking no branch, so state updates or validation are missed, hiding defects and dropping handling when new values are added. Fix: terminate every if-else if chain with an else that handles the remaining cases, or at least assert that the case should be unreachable.
M6-4-3Required · Automated✓ compilable
switch 문은 잘 정의된 형태(각 절 break, default 포함)를 따른다A switch statement shall be a well-formed switch statement
❌ 위반 예시Non-compliant example
#include <iostream>
static void run(int x) {
switch (x) {
case 1: std::cout << "one "; // break 누락 → case 2 로 흘러내림(fall-through)
case 2: std::cout << "two\n"; break;
// default 없음
}
}
int main() { run(1); } // "one two" 출력 — 의도치 않은 fall-through✅ 준수 예시Compliant example
#include <iostream>
static void run(int x) {
switch (x) {
case 1: std::cout << "one\n"; break;
case 2: std::cout << "two\n"; break;
default: std::cout << "other\n"; break;
}
}
int main() { run(1); } // "one" 만 출력⚠️ 근거: switch 의 각 case 절은 break(또는 return·throw, 의도된 fall-through 는 명시 표시)로 끝나야 하고 default 절을 두어야 잘 정의된 형태가 된다. 영향: break 를 빠뜨리면 다음 case 로 의도치 않게 흘러내려(fall-through) 여러 분기가 실행되는 흔한 버그가 생기고, default 가 없으면 예상 못한 값이 조용히 무시된다. 대응: 각 절을 break 등으로 종료하고, 의도된 fall-through 는 [[fallthrough]] 로 표시하며, default 절을 두어 나머지 값을 처리한다.Rationale: each case label in a switch must end with break (or return/throw, with intended fall-through explicitly marked) and a default label must be present for it to be well-formed. Impact: omitting break falls through to the next case unintentionally, executing multiple branches — a common bug — and a missing default silently ignores unexpected values. Fix: terminate each label with break or similar, mark intended fall-through with [[fallthrough]], and include a default to handle the remaining values.
M6-4-6Required · Automated✓ compilable
switch 의 default 절은 마지막에 둔다The final clause of a switch statement shall be the default-clause
❌ 위반 예시Non-compliant example
#include <iostream>
static void run(int x) {
switch (x) {
default: std::cout << "other\n"; break; // default 가 중간/처음에 위치 — 가독성 저하
case 1: std::cout << "one\n"; break;
case 2: std::cout << "two\n"; break;
}
}
int main() { run(2); }✅ 준수 예시Compliant example
#include <iostream>
static void run(int x) {
switch (x) {
case 1: std::cout << "one\n"; break;
case 2: std::cout << "two\n"; break;
default: std::cout << "other\n"; break; // 마지막에 위치 — 관례적, 읽기 쉬움
}
}
int main() { run(2); }⚠️ 근거: default 절을 switch 의 맨 마지막에 두는 것은 널리 통용되는 관례로, 모든 명시적 case 를 먼저 보고 그 외 처리를 마지막에서 확인하는 자연스러운 읽기 순서를 만든다. 영향: default 가 case 들 사이나 앞에 끼면 흐름을 오해하기 쉽고, 위에서 아래로 훑는 독자가 default 를 일반 case 로 착각하거나 fall-through 관계를 잘못 읽을 수 있다. 대응: default 절을 항상 switch 의 마지막에 배치한다.Rationale: placing the default clause last in a switch is a widely followed convention that creates a natural reading order — all explicit cases first, then the catch-all handling at the end. Impact: a default wedged between or before cases is easy to misread, and a reader scanning top to bottom may mistake default for an ordinary case or misread the fall-through relationships. Fix: always place the default clause last in the switch.
M6-6-1Required · Automated✓ compilable
비구조적 점프(goto 등)를 사용하지 않는다Any label referenced by a goto statement shall be declared in the same block, or in a block enclosing the goto statement
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int attempts = 0;
retry: // 임의 점프 대상 — 비구조적 흐름
++attempts;
if (attempts < 3) goto retry;
std::cout << "attempts=" << attempts << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int attempts = 0;
while (attempts < 3) { ++attempts; } // 구조적 반복으로 의도를 명확히
std::cout << "attempts=" << attempts << '\n';
}⚠️ 근거: goto 는 함수 안 임의 라벨로 제어를 옮겨 위→아래로 읽는 구조적 흐름을 깨뜨리고, 점프 방향(앞/뒤)에 따라 반복·분기·예외 처리가 뒤섞일 수 있다. 영향: 비구조적 점프는 제어 흐름 그래프를 복잡하게 만들어 정적 분석과 사람의 추론을 어렵게 하고, 객체 초기화·정리를 건너뛰는 점프는 미묘한 자원 결함을 부른다. 대응: 반복은 while/for, 조기 종료는 break/continue/return, 정리는 RAII 같은 구조적 제어로 대체한다.Rationale: goto transfers control to an arbitrary label in a function, breaking the top-to-bottom structured flow, and depending on jump direction (forward/backward) it can entangle loops, branches, and exception handling. Impact: non-structured jumps complicate the control-flow graph, hindering static analysis and human reasoning, and jumps that skip object initialization or cleanup invite subtle resource defects. Fix: replace with structured control — while/for for loops, break/continue/return for early exit, and RAII for cleanup.
M6-2-3Required · Automated✓ compilable📄 공식 예제Official example
Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-2-3: Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.6.3 Compound statement or blockSee MISRA C++ 2008 [7]
6.6.3 Compound statement or block
M6-4-1Required · Automated✓ compilable📄 공식 예제Official example
An if ( condition ) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement.An if ( condition ) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-4-1: An if ( condition ) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M6-4-4Required · Automated✓ compilable📄 공식 예제Official example
A switch-label shall only be used when the most closely-enclosing compound statement is the body of a switch statement.A switch-label shall only be used when the most closely-enclosing compound statement is the body of a switch statement.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-4-4: A switch-label shall only be used when the most closely-enclosing compound statement is the body of a switch statement. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M6-4-5Required · Automated✓ compilable📄 공식 예제Official example
An unconditional throw or break statement shall terminate every non-empty switch-clause.An unconditional throw or break statement shall terminate every non-empty switch-clause.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-4-5: An unconditional throw or break statement shall terminate every non-empty switch-clause. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M6-4-7Required · Automated✓ compilable📄 공식 예제Official example
The condition of a switch statement shall not have bool type.The condition of a switch statement shall not have bool type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-4-7: The condition of a switch statement shall not have bool type. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: "‘The condition shall be of integral type, enumeration type, or class type. If of
class type, the condition is contextually implicitly converted (Clause 4) to an integral or
enumeration type."’ [C++14 Language Standard, 6.4.2 The switch statement]See MISRA C++ 2008 [7]
Note: "‘The condition shall be of integral type, enumeration type, or class type. If of
class type, the condition is contextually implicitly converted (Clause 4) to an integral or
enumeration type."’ [C++14 Language Standard, 6.4.2 The switch statement]
M6-5-2Required · Automated✓ compilable📄 공식 예제Official example
If loop-counter is not modified by −− or ++, then, within condition, the loop-counter shall only be used as an operand to <=, <, > or >=.If loop-counter is not modified by −− or ++, then, within condition, the loop-counter shall only be used as an operand to <=, <, > or >=.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-5-2: If loop-counter is not modified by −− or ++, then, within condition, the loop-counter shall only be used as an operand to <=, <, > or >=. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M6-5-3Required · Automated✓ compilable📄 공식 예제Official example
The loop-counter shall not be modified within condition or statement.The loop-counter shall not be modified within condition or statement.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-5-3: The loop-counter shall not be modified within condition or statement. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M6-5-4Required · Automated✓ compilable📄 공식 예제Official example
The loop-counter shall be modified by one of: −−, ++, − = n, or + = n; where n remains constant for the duration of the loop.The loop-counter shall be modified by one of: −−, ++, − = n, or + = n; where n remains constant for the duration of the loop.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-5-4: The loop-counter shall be modified by one of: −−, ++, − = n, or + = n; where n remains constant for the duration of the loop. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: “n remains constant for the duration of the loop” means that “n” can be either a
literal, a constant or constexpr value.See MISRA C++ 2008 [7]
Note: “n remains constant for the duration of the loop” means that “n” can be either a
literal, a constant or constexpr value.
M6-5-5Required · Automated✓ compilable📄 공식 예제Official example
A loop-control-variable other than the loop-counter shall not be modified within condition or expression.A loop-control-variable other than the loop-counter shall not be modified within condition or expression.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-5-5: A loop-control-variable other than the loop-counter shall not be modified within condition or expression. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M6-5-6Required · Automated✓ compilable📄 공식 예제Official example
A loop-control-variable other than the loop-counter which is modified in statement shall have type bool.A loop-control-variable other than the loop-counter which is modified in statement shall have type bool.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-5-6: A loop-control-variable other than the loop-counter which is modified in statement shall have type bool. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M6-6-2Required · Automated✓ compilable📄 공식 예제Official example
The goto statement shall jump to a label declared later in the same function body.The goto statement shall jump to a label declared later in the same function body.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-6-2: The goto statement shall jump to a label declared later in the same function body. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M6-6-3Required · Automated✓ compilable📄 공식 예제Official example
The continue statement shall only be used within a well-formed for loop.The continue statement shall only be used within a well-formed for loop.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M6-6-3: The continue statement shall only be used within a well-formed for loop. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.7 Declaration
6.7.1 SpecifiersSee MISRA C++ 2008 [7]
6.7 Declaration
6.7.1 Specifiers
M7M7 (MISRA 유래)M7 (MISRA-origin)
M7-1-2Required · Automated✓ compilable
수정되지 않는 포인터/참조 매개변수는 const 를 가리키게 한다A pointer or reference parameter in a function shall be declared as pointing to const if the corresponding object is not modified
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstddef>
static std::size_t length(char* s) { // s 내용을 수정하지 않는데 비-const
std::size_t n = 0;
while (s[n] != '\0') ++n;
return n;
}
int main() {
char buf[] = "hello";
std::cout << length(buf) << '\n';
// length("literal"); // const 리터럴을 넘길 수 없어 컴파일 에러
}✅ 준수 예시Compliant example
#include <iostream>
#include <cstddef>
static std::size_t length(const char* s) { // 읽기 전용 의도를 const 로 표현
std::size_t n = 0;
while (s[n] != '\0') ++n;
return n;
}
int main() {
std::cout << length("literal") << '\n'; // const 객체도 자유롭게 전달 가능
}⚠️ 근거: 함수가 포인터·참조로 받은 객체를 수정하지 않는다면 그 매개변수를 const 를 가리키게 선언함으로써, 읽기 전용이라는 계약을 인터페이스에 드러내고 컴파일러가 우발적 수정을 막게 한다. 영향: 비-const 로 두면 const 객체(문자열 리터럴·const 변수)를 인자로 넘길 수 없어 호출이 제한되고, 독자는 함수가 대상을 바꿀 수 있다고 오해해 불필요한 방어 코드를 넣는다. 대응: 수정하지 않는 모든 포인터·참조 매개변수를 const 를 가리키도록 선언한다.Rationale: if a function does not modify the object received by pointer or reference, declaring that parameter as pointing to const expresses the read-only contract in the interface and lets the compiler prevent accidental modification. Impact: leaving it non-const prevents passing const objects (string literals, const variables) as arguments, restricting calls, and leads readers to assume the function may change the target and add unnecessary defensive code. Fix: declare every pointer or reference parameter that is not modified as pointing to const.
M7-3-6Required · Automated✓ compilable
헤더(또는 넓은 범위)에서 using 지시문으로 이름을 도입하지 않는다using-directives and using-declarations shall not be used in header files
❌ 위반 예시Non-compliant example
#include <iostream>
using namespace std; // 넓은 범위에 std 전체 도입 — 이름 충돌·모호성 위험
static int count(int) { return 1; } // std::count 와 이름이 겹칠 소지
int main() { cout << count(0) << "\n"; }✅ 준수 예시Compliant example
#include <iostream>
static int count_items(int) { return 1; } // 완전 한정 이름 + 고유 이름
int main() { std::cout << count_items(0) << "\n"; }⚠️ 근거: using namespace 지시문은 대상 네임스페이스의 모든 이름을 현재 범위로 끌어들이는데, 이를 헤더나 넓은 범위에 두면 그 헤더를 포함하는 모든 번역단위가 의도치 않게 오염된다. 영향: 사용자 이름과 표준 라이브러리 이름(count, distance 등)이 겹쳐 모호성 오류가 나거나, 오버로드 해석이 예상 밖 함수를 골라 조용한 버그가 되며, 충돌은 포함 순서에 따라 산발적으로 나타난다. 대응: 헤더에서는 완전 한정 이름(std::)을 쓰고, using 은 함수·블록 같은 좁은 범위에 한정해 필요한 이름만 도입한다.Rationale: a using namespace directive pulls every name of the target namespace into the current scope, and placing it in a header or broad scope unintentionally pollutes every translation unit that includes the header. Impact: user names clash with standard-library names (count, distance), causing ambiguity errors or silent bugs where overload resolution picks an unexpected function, and conflicts appear sporadically by include order. Fix: use fully qualified names (std::) in headers and confine using to narrow scopes like functions or blocks, importing only the needed names.
M7-5-1Required · Automated✓ compilable
함수는 자동(지역) 객체에 대한 참조/포인터를 반환하지 않는다A function shall not return a reference or a pointer to an automatic variable
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
static const std::string& name() {
std::string s = "node"; // 자동(지역) 객체
return s; // 함수 종료 시 소멸되는 객체의 참조 반환 — 댕글링
}
int main() { std::cout << name() << '\n'; } // 무효 참조 접근 — 미정의 동작✅ 준수 예시Compliant example
#include <iostream>
#include <string>
static std::string name() {
return std::string{"node"}; // 값으로 반환(이동/RVO)
}
int main() { std::cout << name() << '\n'; }⚠️ 근거: 함수의 자동(지역) 변수는 함수가 반환하는 순간 수명이 끝나므로, 그 변수에 대한 참조나 주소를 반환하면 호출자는 이미 소멸한 객체를 가리키게 된다. 영향: 호출자가 그 댕글링 참조·포인터를 사용하면 해제된 스택 메모리를 읽어 쓰레기 값·크래시가 나고, 입력에 따라 동작이 달라지는 보안 취약점이 된다. 대응: 필요한 값은 값으로 반환하거나(이동·RVO 로 효율적), 수명이 호출자보다 긴 객체(멤버·정적·힙 소유)를 가리키게 한다.Rationale: a function automatic (local) variable ends its lifetime the moment the function returns, so returning a reference or address to it makes the caller point at an already-destroyed object. Impact: using that dangling reference or pointer reads freed stack memory, yielding garbage or crashes, and becomes a security vulnerability whose behaviour varies with input. Fix: return needed values by value (efficient via move/RVO) or point to objects that outlive the caller (member, static, or heap-owned).
M7-3-1Required · Automated✓ compilable📄 공식 예제Official example
The global namespace shall only contain main, namespace declarations and extern "C" declarations.The global namespace shall only contain main, namespace declarations and extern "C" declarations.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M7-3-1: The global namespace shall only contain main, namespace declarations and extern "C" declarations. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M7-3-2Required · Automated✓ compilable📄 공식 예제Official example
The identifier main shall not be used for a function other than the global function main.The identifier main shall not be used for a function other than the global function main.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M7-3-2: The identifier main shall not be used for a function other than the global function main. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M7-3-3Required · Automated✓ compilable📄 공식 예제Official example
There shall be no unnamed namespaces in header files.There shall be no unnamed namespaces in header files.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M7-3-3: There shall be no unnamed namespaces in header files. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M7-3-4Required · Automated✓ compilable📄 공식 예제Official example
Using-directives shall not be used.Using-directives shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M7-3-4: Using-directives shall not be used. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
See: Using-directive [16] concerns an inclusion of specific namespace with all its types,
e.g. using namespace std.See MISRA C++ 2008 [7]
See: Using-directive [16] concerns an inclusion of specific namespace with all its types,
e.g. using namespace std.
M7-4-1Required · Non-automated✓ compilable📄 공식 예제Official example
All usage of assembler shall be documented.All usage of assembler shall be documented.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M7-4-1: All usage of assembler shall be documented. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M7-4-2Required · Automated✓ compilable📄 공식 예제Official example
Assembler instructions shall only be introduced using the asm declaration.Assembler instructions shall only be introduced using the asm declaration.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M7-4-2: Assembler instructions shall only be introduced using the asm declaration. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M7-4-3Required · Automated✓ compilable📄 공식 예제Official example
Assembly language shall be encapsulated and isolated.Assembly language shall be encapsulated and isolated.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M7-4-3: Assembly language shall be encapsulated and isolated. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.7.5 Linkage specificationSee MISRA C++ 2008 [7]
6.7.5 Linkage specification
M7-5-2Required · Non-automated✓ compilable📄 공식 예제Official example
The address of an object with automatic storage shall not be assigned to another object that may persist after the first object has ceased to exist.The address of an object with automatic storage shall not be assigned to another object that may persist after the first object has ceased to exist.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M7-5-2: The address of an object with automatic storage shall not be assigned to another object that may persist after the first object has ceased to exist. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: C++ specifies that binding a temporary object (e.g. automatic variable returned
from a function) to a reference to const prolongs the lifetime of the temporary to the
lifetime of the reference.
Note: Rule 7-5-2 concerns C++11 smart pointers, i.e. std::unique_ptr, std::shared_ptr
and std::weak_ptr, too.
See also:
• C++ Core Guidelines [11]: F .45: Don’t return a T&&.See MISRA C++ 2008 [7]
Note: C++ specifies that binding a temporary object (e.g. automatic variable returned
from a function) to a reference to const prolongs the lifetime of the temporary to the
lifetime of the reference.
Note: Rule 7-5-2 concerns C++11 smart pointers, i.e. std::unique_ptr, std::shared_ptr
and std::weak_ptr, too.
See also:
• C++ Core Guidelines [11]: F .45: Don’t return a T&&.
M8M8 (MISRA 유래)M8 (MISRA-origin)
M8-4-2Required · Automated✓ compilable
함수 선언과 정의의 매개변수 이름을 일치시킨다The identifiers used in the declaration and definition of a function shall be identical
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstring>
static void copy_n(char* dst, const char* src, std::size_t n); // 선언: dst, src
static void copy_n(char* a, const char* b, std::size_t n) { // 정의: a, b — 이름 불일치
std::memcpy(a, b, n);
}
int main() { char d[4]; copy_n(d, "abc", 4); std::cout << d << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
#include <cstring>
static void copy_n(char* dst, const char* src, std::size_t n); // 선언
static void copy_n(char* dst, const char* src, std::size_t n) { // 정의 — 동일 이름
std::memcpy(dst, src, n);
}
int main() { char d[4]; copy_n(d, "abc", 4); std::cout << d << '\n'; }⚠️ 근거: 함수 선언(헤더)과 정의(소스)의 매개변수 이름이 같으면, 헤더만 보는 호출자와 정의를 보는 구현자가 같은 어휘로 각 인자의 의미를 이해한다. 영향: 이름이 다르면(dst/src 대 a/b) 인자 순서·역할을 헷갈려 dst 와 src 를 바꿔 호출하는 등의 실수를 부르고, 검토·디버깅 시 두 위치를 대조하기 어렵다. 대응: 선언과 정의에서 매개변수 이름을 동일하게 맞춰 인터페이스 문서성과 일관성을 유지한다.Rationale: when the parameter names in a function declaration (header) and definition (source) match, callers who see only the header and implementers who see the definition understand each argument with the same vocabulary. Impact: differing names (dst/src vs a/b) confuse argument order and roles, inviting mistakes like swapping dst and src in a call, and make it hard to cross-reference the two locations during review and debugging. Fix: keep parameter names identical in the declaration and definition to preserve interface documentation and consistency.
M8-5-1Required · Automated✓ compilable
모든 변수는 사용되기 전에 정의된 값을 가져야 한다All variables shall have a defined value before they are used
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int total; // 초기화 누락
int a[3] = {1, 2, 3};
for (int i = 0; i < 3; ++i) total += a[i]; // 미초기화 total 에 누적 — 미정의 동작
std::cout << total << '\n'; // 쓰레기 값에 6 을 더한 결과
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int total = 0; // 사용 전에 명확히 초기화
int a[3] = {1, 2, 3};
for (int i = 0; i < 3; ++i) total += a[i];
std::cout << total << '\n'; // 6
}⚠️ 근거: 자동 저장 기간의 기본 타입 변수는 명시적으로 초기화하지 않으면 불확정 값을 가지며, 그 값을 읽는 것은 미정의 동작이다. 영향: 미초기화 누적 변수(total)에 값을 더하면 쓰레기 초기값 위에 계산이 쌓여 결과가 매 실행·빌드마다 달라지는 재현 어려운 버그가 되고, 보안상 이전 스택 내용이 노출될 수 있다. 대응: 모든 변수를 선언과 동시에(또는 첫 사용 이전에) 명확한 값으로 초기화하고, 컴파일러 경고(-Wuninitialized)와 정적 분석을 활용한다.Rationale: a fundamental-type variable with automatic storage has an indeterminate value unless explicitly initialized, and reading that value is undefined behaviour. Impact: adding to an uninitialized accumulator (total) stacks the computation on a garbage initial value, producing a hard-to-reproduce bug that differs per run or build, and may expose prior stack contents as a security issue. Fix: initialize every variable to a defined value at declaration (or before first use) and rely on compiler warnings (-Wuninitialized) and static analysis.
M8-0-1Required · Automated✓ compilable📄 공식 예제Official example
An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively.An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M8-0-1: An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.8.2 Ambiguity resolutionSee MISRA C++ 2008 [7]
6.8.2 Ambiguity resolution
M8-3-1Required · Automated✓ compilable📄 공식 예제Official example
Parameters in an overriding virtual function shall either use the same default arguments as the function they override, or else shall not specify any default arguments.Parameters in an overriding virtual function shall either use the same default arguments as the function they override, or else shall not specify any default arguments.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M8-3-1: Parameters in an overriding virtual function shall either use the same default arguments as the function they override, or else shall not specify any default arguments. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Overriding non-virtual functions in a subclass is called function “hiding” or
“redefining”. It is prohibited by A10-2-1.
6.8.4 Function definitionsSee MISRA C++ 2008 [7]
Note: Overriding non-virtual functions in a subclass is called function “hiding” or
“redefining”. It is prohibited by A10-2-1.
6.8.4 Function definitions
M8-4-4Required · Automated✓ compilable📄 공식 예제Official example
A function identifier shall either be used to call the function or it shall be preceded by &.A function identifier shall either be used to call the function or it shall be preceded by &.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M8-4-4: A function identifier shall either be used to call the function or it shall be preceded by &. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M8-5-2Required · Automated✓ compilable📄 공식 예제Official example
Braces shall be used to indicate and match the structure in the non-zero initialization of arrays and structures.Braces shall be used to indicate and match the structure in the non-zero initialization of arrays and structures.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M8-5-2: Braces shall be used to indicate and match the structure in the non-zero initialization of arrays and structures. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M9M9 (MISRA 유래)M9 (MISRA-origin)
M9-3-1Required · Automated✓ compilable
const 멤버 함수가 내부 데이터에 대한 비-const 핸들을 반환하지 않게 한다const member functions shall not return non-const pointers or references to class-data
❌ 위반 예시Non-compliant example
#include <iostream>
class C {
int data_ = 7;
public:
int* get() const { return const_cast<int*>(&data_); } // const 함수가 수정 핸들 노출
};
int main() {
const C c;
*c.get() = 99; // const 객체의 내부를 수정 — const 계약 위반
std::cout << *c.get() << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
class C {
int data_ = 7;
public:
const int* get() const { return &data_; } // const 함수는 const 핸들만 반환
void set(int v) { data_ = v; } // 변경은 비-const 메서드로
};
int main() {
C c; c.set(99);
std::cout << *c.get() << '\n'; // 99 — 읽기는 const 핸들로
}⚠️ 근거: const 멤버 함수는 그 객체의 논리적 상태를 바꾸지 않겠다는 계약이며, 그 일부로 내부 데이터에 대한 수정 가능한 핸들을 외부에 넘기지 않아야 한다. 영향: const 함수가 비-const 포인터·참조를 반환하면 const 객체를 통해서도 내부가 수정될 수 있어 const 보장이 무너지고, const_cast 로 const 를 벗긴 경우 진짜 const 객체 수정으로 미정의 동작까지 갈 수 있다. 대응: const 멤버 함수는 const 포인터·참조만 반환하고, 수정이 필요한 접근은 별도의 비-const 멤버 함수로 제공한다.Rationale: a const member function is a contract not to change the logical state of the object, and as part of that it must not hand out a modifiable handle to internal data. Impact: a const function returning a non-const pointer or reference lets the internals be modified even through a const object, breaking the const guarantee, and casting away const can escalate to modifying a truly const object — undefined behaviour. Fix: have const member functions return only const pointers/references and provide a separate non-const member function for accesses that need modification.
M9-3-3Required · Automated✓ compilable
상태를 바꾸지 않는 멤버 함수는 const 로 선언한다If a member function can be made static then it shall be made static, otherwise if it can be made const then it shall be made const
❌ 위반 예시Non-compliant example
#include <iostream>
class C {
int v_ = 42;
public:
int value() { return v_; } // 상태를 바꾸지 않는데 비-const
};
int main() {
const C c;
// std::cout << c.value(); // const 객체에서 비-const 함수 호출 불가 — 컴파일 에러
C m; std::cout << m.value() << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
class C {
int v_ = 42;
public:
int value() const { return v_; } // 상태 불변임을 const 로 명시
};
int main() {
const C c;
std::cout << c.value() << '\n'; // const 객체에서도 호출 가능
}⚠️ 근거: 객체의 논리적 상태를 변경하지 않는 멤버 함수를 const 로 선언하면, 그 불변성이 인터페이스에 드러나고 const 객체에서도 호출할 수 있게 된다(멤버를 전혀 쓰지 않으면 static 이 더 적절하다). 영향: const 로 표시하지 않으면 const 객체·const 참조를 통해 그 함수를 호출할 수 없어 사용이 제한되고, 함수가 상태를 바꿀 수 있다고 독자가 오해한다. 대응: 상태를 바꾸지 않는 관찰자(getter·조회) 함수는 const 로, 인스턴스 데이터를 쓰지 않는 함수는 static 으로 선언한다.Rationale: declaring a member function that does not change the logical state of the object as const makes that immutability visible in the interface and allows calling it on const objects (and if it uses no members at all, static is more appropriate). Impact: not marking it const prevents calling the function through const objects or const references, restricting use, and leads readers to assume the function may change state. Fix: declare observer (getter/query) functions that do not change state as const, and functions that use no instance data as static.
M9-5-1Required · Automated✓ compilable
union 을 사용하지 않는다(타입 퍼닝 금지)Unions shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
union U { int i; float f; };
int main() {
U u; u.i = 1065353216; // i 를 활성화
std::cout << u.f << '\n'; // 비활성 멤버 f 로 읽기(타입 퍼닝) — 미정의 동작
}✅ 준수 예시Compliant example
#include <iostream>
#include <variant>
int main() {
std::variant<int, float> u = 1.0f; // 활성 타입을 스스로 추적
if (std::holds_alternative<float>(u))
std::cout << std::get<float>(u) << '\n'; // 잘못된 타입 접근은 예외
}⚠️ 근거: union 의 모든 멤버는 같은 메모리를 공유하지만, 한 멤버에 쓴 뒤 다른(비활성) 멤버로 읽는 타입 퍼닝(type punning)은 표준상 미정의 동작이고, union 은 현재 활성 멤버를 스스로 추적하지 않는다. 영향: 활성 멤버를 잘못 추적하면 쓰레기 값을 읽거나, 비trivial 타입을 담으면 생성·소멸 관리가 복잡해져 누수·손상이 발생하는데 컴파일러가 막아주지 못한다. 대응: 합집합이 필요하면 활성 타입을 추적하고 잘못된 접근을 예외로 막는 std::variant 를, 비트 재해석이 목적이면 std::memcpy/std::bit_cast 를 사용한다.Rationale: all members of a union share the same memory, but writing one member and reading another (inactive) member — type punning — is undefined behaviour in the standard, and a union does not track its currently active member itself. Impact: mistracking the active member reads garbage, and holding non-trivial types complicates construction/destruction, causing leaks or corruption that the compiler cannot prevent. Fix: use std::variant when a union is needed (it tracks the active type and blocks wrong accesses with an exception), and std::memcpy/std::bit_cast when bitwise reinterpretation is the goal.
M9-6-1Required · Non-automated✓ compilable📄 공식 예제Official example
When the absolute positioning of bits representing a bit-field is required, then the behavior and packing of bit-fields shall be documented.When the absolute positioning of bits representing a bit-field is required, then the behavior and packing of bit-fields shall be documented.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M9-6-1: When the absolute positioning of bits representing a bit-field is required, then the behavior and packing of bit-fields shall be documented. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M9-6-4Required · Automated✓ compilable📄 공식 예제Official example
Named bit-fields with signed integer type shall have a length of more than one bit.Named bit-fields with signed integer type shall have a length of more than one bit.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M9-6-4: Named bit-fields with signed integer type shall have a length of more than one bit. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: The signed exact-width integer types like std::int16_t are guaranteed to
have a two’s complement representation (see also A9-6-1). In this case, a single bit
signed bit-field contains only a sign bit, thus it can represent values either ( -1) or ( 0).
Therefore, to avoid developers’ confusion, it is recommended to use unsigned types
for single bit bit-fields.
6.10 Derived Classes
6.10.0 GeneralSee MISRA C++ 2008 [7]
Note: The signed exact-width integer types like std::int16_t are guaranteed to
have a two’s complement representation (see also A9-6-1). In this case, a single bit
signed bit-field contains only a sign bit, thus it can represent values either ( -1) or ( 0).
Therefore, to avoid developers’ confusion, it is recommended to use unsigned types
for single bit bit-fields.
6.10 Derived Classes
6.10.0 General
A16A16 (AUTOSAR)A16 (AUTOSAR-original)
A16-2-2Required · Automated✓ compilable
사용되지 않는 #include 를 두지 않는다There shall be no unused include directives
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector> // 이 파일에서 vector 를 전혀 사용하지 않음 — 불필요한 의존
#include <string>
int main() {
std::string s = "hi";
std::cout << s << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <string> // 실제 사용하는 헤더만 포함
int main() {
std::string s = "hi";
std::cout << s << '\n';
}⚠️ 근거: 어떤 헤더의 심볼을 전혀 쓰지 않으면서 그 헤더를 포함하면, 코드가 실제로 무엇에 의존하는지 흐려지고 불필요한 컴파일 의존이 생긴다. 영향: 사용되지 않는 #include 는 컴파일 시간을 늘리고, 그 헤더가 바뀔 때 불필요한 재빌드를 유발하며, 모듈 간 결합을 실제보다 커 보이게 한다. 대응: 파일이 실제로 사용하는 심볼을 제공하는 헤더만 포함하고, 사용하지 않게 된 포함은 제거한다.Rationale: including a header while using none of its symbols obscures what the code actually depends on and creates an unnecessary compile dependency. Impact: an unused #include increases compile time, triggers needless rebuilds when that header changes, and makes inter-module coupling look larger than it is. Fix: include only headers that provide symbols the file actually uses, and remove includes that are no longer needed.
A16-7-1Required · Automated✓ compilable
#pragma 지시문을 사용하지 않는다The #pragma directive shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#pragma pack(1) // 구현정의 패킹 — 컴파일러마다 다르게 동작/무시될 수 있음
struct Packet { char tag; int value; };
#pragma pack()
int main() { std::cout << sizeof(Packet) << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
#include <cstdint>
// 표준 메커니즘으로 명시적 레이아웃 표현(필요한 정렬을 alignas 로)
struct alignas(4) Packet { char tag; std::int32_t value; };
int main() { std::cout << sizeof(Packet) << '\n'; }⚠️ 근거: #pragma 의 의미는 표준이 정의하지 않고 전적으로 구현(컴파일러)에 맡겨져 있어, 같은 #pragma 가 컴파일러마다 다르게 동작하거나 조용히 무시될 수 있다. 영향: #pragma pack 같은 지시문에 의존하면 구조체 레이아웃이 컴파일러·버전에 따라 달라져 직렬화·ABI 가 깨지고, 이식할 때 진단 없는 결함이 된다. 대응: 정렬·표현이 필요하면 alignas 같은 표준 언어 기능으로 명시하고, 컴파일러 고유 동작이 불가피하면 한 곳에 격리해 문서화한다.Rationale: the meaning of #pragma is not defined by the standard and is left entirely to the implementation, so the same #pragma may behave differently across compilers or be silently ignored. Impact: relying on directives like #pragma pack makes struct layout vary by compiler and version, breaking serialization and ABI and becoming a defect with no diagnostic when porting. Fix: express needed alignment/representation with standard language features like alignas, and isolate and document any unavoidable compiler-specific behaviour in one place.
A16-0-1Required · Automated✓ compilable📄 공식 예제Official example
The pre-processor shall only be used for unconditional and conditional file inclusion and include guards, and using the following directives: (1) #ifndef, (2) #ifdef, (3) #if, (4) #if defined, (5) #elif, (6) #else, (7) #define, (8) #endif, (9) #include.The pre-processor shall only be used for unconditional and conditional file inclusion and include guards, and using the following directives: (1) #ifndef, (2) #ifdef, (3) #if, (4) #if defined, (5) #elif, (6) #else, (7) #define, (8) #endif, (9) #include.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <string> // $Id: A16-0-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #pragma once // Non-compliant - implementation-defined feature #ifndef HEADER_FILE_NAME // Compliant - include guard #define HEADER_FILE_NAME // Compliant - include guard #include <cstdint> // Compliant - unconditional file inclusion #ifdef WIN32 #include <windows.h> // Compliant - conditional file inclusion #endif #ifdef WIN32 std::int32_t fn1( std::int16_t x, std::int16_t y) noexcept; // Non-compliant - not a file inclusion #endif #if defined VERSION && VERSION > 2011L // Compliant #include <array> // Compliant - conditional file inclusion #elif VERSION > 1998L // Compliant #include <vector> // Compliant - conditional file inclusion #endif // Compliant #define MAX_ARRAY_SIZE 1024U // Non-compliant #ifndef MAX_ARRAY_SIZE // Non-compliant #error "MAX_ARRAY_SIZE has not been defined" // Non-compliant #endif // Non-compliant #undef MAX_ARRAY_SIZE // Non-compliant #define MIN(a, b) (((a) < (b)) ? (a) : (b)) // Non-compliant #define PLUS2(X) ((X) + 2) // Non-compliant - function should be used instead #define PI 3.14159F // Non-compliant - constexpr should be used instead #define std ::int32_t long // Non-compliant - 'using' should be used instead #define STARTIF if( // Non-compliant - language redefinition #define HEADER "filename.h" // Non-compliant - string literal void Fn2() noexcept { #ifdef __linux__ // Non-compliant - ifdef not used for file inclusion // ... #elif WIN32 // Non-compliant - elif not used for file inclusion // ... #elif __APPLE__ // Non-compliant - elif not used for file inclusion // ... #else // Non-compliant - else not used for file inclusion // ... #endif // Non-compliant - endif not used for file inclusion or include guards } #endif // Compliant - include guard
⚠️ C++ provides safer, more readable and easier to maintain ways of achieving what is
often done using the pre-processor. The pre-processor does not obey the linkage,
lookup and function call semantics. Instead, constant objects, constexprs, inline
functions and templates are to be used.
See also:
• MISRA C++ 2008 [7]: Rule 16-2-1 The pre-processor shall only be used for file
inclusion and include guards.
• MISRA C++ 2008 [7]: Rule 16-2-2 C++ macros shall only be used for: include
guards, type qualifiers, or storage class specifiers.
• JSF December 2005 [8]: AV Rule 26 Only the following pre-processor directives
shall be used: 1. #ifndef 2. #define 3. #endif 4. #include.
• JSF December 2005 [8]: AV Rule 27 #ifndef, #define and #endif will be used to
prevent multiple inclusions of the same header file. Other techniques to prevent
the multiple inclusions of header files will not be used.
• JSF December 2005 [8]: AV Rule 28 The #ifndef and #endif pre-processor
directives will only be used as defined in AV Rule 27 to prevent multiple inclusions
of the same header file.
• JSF December 2005 [8]: AV Rule 29 The #define pre-processor directive shall
not be used to create inline macros. Inline functions shall be used instead.
• JSF December 2005 [8]: AV Rule 30 The #define pre-processor directive shall not
be used to define constant values. Instead, the const qualifier shall be applied to
variable declarations to specify constant values.
• JSF December 2005 [8]: AV Rule 31 The #define pre-processor directive will
only be used as part of the technique to prevent multiple inclusions of the same
header file.
• JSF December 2005 [8]: AV Rule 32 The #include pre-processor directive will
only be used to include header (*.h) files.
• HIC++ v4.0 [9]: 16.1.1 Use the preprocessor only for implementing include
guards, and including header files with include guards.C++ provides safer, more readable and easier to maintain ways of achieving what is
often done using the pre-processor. The pre-processor does not obey the linkage,
lookup and function call semantics. Instead, constant objects, constexprs, inline
functions and templates are to be used.
See also:
• MISRA C++ 2008 [7]: Rule 16-2-1 The pre-processor shall only be used for file
inclusion and include guards.
• MISRA C++ 2008 [7]: Rule 16-2-2 C++ macros shall only be used for: include
guards, type qualifiers, or storage class specifiers.
• JSF December 2005 [8]: AV Rule 26 Only the following pre-processor directives
shall be used: 1. #ifndef 2. #define 3. #endif 4. #include.
• JSF December 2005 [8]: AV Rule 27 #ifndef, #define and #endif will be used to
prevent multiple inclusions of the same header file. Other techniques to prevent
the multiple inclusions of header files will not be used.
• JSF December 2005 [8]: AV Rule 28 The #ifndef and #endif pre-processor
directives will only be used as defined in AV Rule 27 to prevent multiple inclusions
of the same header file.
• JSF December 2005 [8]: AV Rule 29 The #define pre-processor directive shall
not be used to create inline macros. Inline functions shall be used instead.
• JSF December 2005 [8]: AV Rule 30 The #define pre-processor directive shall not
be used to define constant values. Instead, the const qualifier shall be applied to
variable declarations to specify constant values.
• JSF December 2005 [8]: AV Rule 31 The #define pre-processor directive will
only be used as part of the technique to prevent multiple inclusions of the same
header file.
• JSF December 2005 [8]: AV Rule 32 The #include pre-processor directive will
only be used to include header (*.h) files.
• HIC++ v4.0 [9]: 16.1.1 Use the preprocessor only for implementing include
guards, and including header files with include guards.
A16-2-1Required · Automated✓ compilable📄 공식 예제Official example
The ’, ", / *, //, \ characters shall not occur in a header file name or in #include directive.The ’, ", / *, //, \ characters shall not occur in a header file name or in #include directive.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A16-2-1.cpp 271687 2017-03-23 08:57:35Z piotr.tanski $ // #include <directory/headerfile.hpp> // Compliant // #include <headerfile.hpp> // Compliant // #include "directory/headerfile.hpp" // Compliant // #include "headerfile.hpp" // Compliant // #include <directory/ *.hpp> // Non-compliant // #include <header'file.hpp> // Non-compliant // #include <"headerfile.hpp"> // Non-compliant // #include <directory\\headerfile.hpp> // Non-compliant
⚠️ It is undefined behavior if the ’, ", / *, //, \\ characters are used in #include
directive, between < and > or “ ” delimiters.
See also:
• MISRA C++ 2008 [7]: Rule 16-2-4 The ’, ", /* or // characters shall not occur in a
header file name.
• MISRA C++ 2008 [7]: Rule 16-2-5 The \character shall not occur in a header file
name.It is undefined behavior if the ’, ", / *, //, \\ characters are used in #include
directive, between < and > or “ ” delimiters.
See also:
• MISRA C++ 2008 [7]: Rule 16-2-4 The ’, ", /* or // characters shall not occur in a
header file name.
• MISRA C++ 2008 [7]: Rule 16-2-5 The \character shall not occur in a header file
name.
A16-2-3Required · Non-automated✓ compilable📄 공식 예제Official example
An include directive shall be added explicitly for every symbol used in a file.An include directive shall be added explicitly for every symbol used in a file.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility> // $Id: A16-2-3.hpp 319944 2018-05-21 09:00:40Z ilya.burylov $ #ifndef HEADER_HPP #define HEADER_HPP #include <array> #include <stdexcept> #include <cstdint> class B; // Compliant - type B can be included using forward declaration class OutOfRangeException : public std::out_of_range // Non-compliant - <stdexcept> which defines // out_of_range included // implicitly through <array> { public: using std::out_of_range::out_of_range; }; class A { public: // Interface of class A private: std::array<std::uint32_t, 10> mArray; // Compliant - <array> included explicitly B* mB; std::int32_t mX; // Compliant - <cstdint> included explicitly }; #endif
⚠️ All header files that define types or functions used in a file should be included explicitly .
The actual header to include depends on the specification of the library/component
used.
Exception:
Types defined via forward declarations do not violate this rule.
See also:
• none
6.16.3 Macro replacementAll header files that define types or functions used in a file should be included explicitly .
The actual header to include depends on the specification of the library/component
used.
Exception:
Types defined via forward declarations do not violate this rule.
See also:
• none
6.16.3 Macro replacement
A16-6-1Required · Automated✓ compilable📄 공식 예제Official example
#error directive shall not be used.#error directive shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A16-6-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ #include <cstdint> #include <type_traits> constexpr std::int32_t value = 0; #if value > 10 #error "Incorrect value" // Non-compliant #endif void F1() noexcept { static_assert(value <= 10, "Incorrect value"); // Compliant // ... } template <typename T> void F2(T& a) { static_assert(std::is_copy_constructible<T>::value, "f2() function requires copying"); // Compliant // ... }
⚠️ Using the pre-processor #error directive may lead to code that is complicated and not
clear for developers. The #error directive can not be applied to templates as it will not
be evaluated as a per-instance template deduction.
Static assertion, similarly to #error directive, provides a compile-time error checking.
However, static_assert behaves correctly in all C++ concepts and makes the code
more readable and does not rely on pre-processor directives.
Note: “#error” is anyway not allowed, see A16-0-1. This rule is kept in case A16-0-1 is
disabled in a project.
See also:
• none
6.16.7 Pragma directiveUsing the pre-processor #error directive may lead to code that is complicated and not
clear for developers. The #error directive can not be applied to templates as it will not
be evaluated as a per-instance template deduction.
Static assertion, similarly to #error directive, provides a compile-time error checking.
However, static_assert behaves correctly in all C++ concepts and makes the code
more readable and does not rely on pre-processor directives.
Note: “#error” is anyway not allowed, see A16-0-1. This rule is kept in case A16-0-1 is
disabled in a project.
See also:
• none
6.16.7 Pragma directive
A17A17 (AUTOSAR)A17 (AUTOSAR-original)
A17-1-1Required · Non-automated✓ compilable
C 라이브러리 기능 대신 C++ 표준 라이브러리 대안을 사용한다Use of the C Standard Library shall be encapsulated and isolated
❌ 위반 예시Non-compliant example
#include <cstdio>
#include <iostream>
int main() {
int v = 42;
char buf[4]; // 작은 고정 버퍼
std::sprintf(buf, "%d", v); // 경계 미검사 C 함수 — 큰 값이면 오버플로우
std::cout << buf << '\n';
}✅ 준수 예시Compliant example
#include <string>
#include <iostream>
int main() {
int v = 42;
std::string s = std::to_string(v); // 타입 안전·길이 자동 관리
std::cout << s << '\n';
}⚠️ 근거: sprintf·strcpy 같은 C 라이브러리 함수는 형식 문자열과 인자의 타입 일치를 컴파일러가 보장하지 못하고 대상 버퍼 크기를 받지 않아 경계 검사가 없다. 영향: 형식·타입 불일치나 버퍼 초과가 미정의 동작·버퍼 오버플로우로 이어져, 흔한 보안 취약점의 원천이 된다. 대응: 동등한 C++ 표준 라이브러리 기능(std::to_string, std::string, <iostream>·<format>)을 우선 사용하고, 불가피한 C API 호출은 안전한 래퍼로 캡슐화·격리한다.Rationale: C library functions like sprintf and strcpy give the compiler no way to verify that the format string matches argument types and take no destination buffer size, so there is no bounds checking. Impact: a format/type mismatch or buffer overrun leads to undefined behaviour and buffer overflow, a frequent source of security vulnerabilities. Fix: prefer the equivalent C++ standard-library facilities (std::to_string, std::string, <iostream>/<format>), and encapsulate any unavoidable C API call in a safe wrapper.
A17-0-1Required · Automated✓ compilable📄 공식 예제Official example
Reserved identifiers, macros and functions in the C++ standard library shall not be defined, redefined or undefined.Reserved identifiers, macros and functions in the C++ standard library shall not be defined, redefined or undefined.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A17-0-1.cpp 271389 2017-03-21 14:41:05Z piotr.tanski $ #undef __TIME__ // Non-compliant #define __LINE__ 20 // Non-compliant
⚠️ It is generally bad practice to #undef a macro that is defined in the standard library .
It is also bad practice to #define a macro name that is a C++ reserved identifier, or
C++ keyword or the name of any macro, object or function in the standard library . For
example, there are some specific reserved words and function names that are known
to give rise to undefined behavior if they are redefined or undefined, including defined,
__LINE__, __FILE__, __DA TE__, __TIME__, __STDC__, errno and assert.
Refer to C++ Language Standard for a list of the identifiers that are reserved. Generally ,
all identifiers that begin with the underscore character are reserved.
Note that this rule applies regardless of which header files, if any , are actually included.
See also:
• MISRA C++ 2008 [7]: Rule 17-0-1 Reserved identifiers, macros and functions in
the standard library shall not be defined, redefined or undefined.It is generally bad practice to #undef a macro that is defined in the standard library .
It is also bad practice to #define a macro name that is a C++ reserved identifier, or
C++ keyword or the name of any macro, object or function in the standard library . For
example, there are some specific reserved words and function names that are known
to give rise to undefined behavior if they are redefined or undefined, including defined,
__LINE__, __FILE__, __DA TE__, __TIME__, __STDC__, errno and assert.
Refer to C++ Language Standard for a list of the identifiers that are reserved. Generally ,
all identifiers that begin with the underscore character are reserved.
Note that this rule applies regardless of which header files, if any , are actually included.
See also:
• MISRA C++ 2008 [7]: Rule 17-0-1 Reserved identifiers, macros and functions in
the standard library shall not be defined, redefined or undefined.
A17-0-2Required · Non-automated✓ compilable📄 공식 예제Official example
All project’s code including used libraries (including standard and user-defined libraries) and any third-party user code shall conform to the AUTOSAR C++14 Coding Guidelines.All project’s code including used libraries (including standard and user-defined libraries) and any third-party user code shall conform to the AUTOSAR C++14 Coding Guidelines.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A17-0-2: All project's code including used libraries (including standard and user-defined libraries) and any third-party user code shall conform to the AUTOSAR C++14 Coding Guidelines. // No code example provided in the official guideline PDF.
⚠️ Note that library code can be provided as source code or be provided in a compiled
form. The rule applies for any form of libraries.
As for any rule in this standard, a deviation procedure can be performed for this rule
and the project needs to argue what are the measures ensuring that non-compliant
libraries can be used in a project, addressing:
1. interference from the non-compliant code (for example, a library function
overwrites the stack or heap of the caller)
2. residual errors in non-compliant code resulting with its wrong outputs, which are
subsequently used (for example, a library function delivers wrong return value
used by the caller).
Exception:
If a function is defined in a library or any third-party user code but it is ensured that the
function will not be used (directly or indirectly) in the project, then the function may not
conform to the AUTOSAR C++14 Coding Guidelines.
See also:
• noneNote that library code can be provided as source code or be provided in a compiled
form. The rule applies for any form of libraries.
As for any rule in this standard, a deviation procedure can be performed for this rule
and the project needs to argue what are the measures ensuring that non-compliant
libraries can be used in a project, addressing:
1. interference from the non-compliant code (for example, a library function
overwrites the stack or heap of the caller)
2. residual errors in non-compliant code resulting with its wrong outputs, which are
subsequently used (for example, a library function delivers wrong return value
used by the caller).
Exception:
If a function is defined in a library or any third-party user code but it is ensured that the
function will not be used (directly or indirectly) in the project, then the function may not
conform to the AUTOSAR C++14 Coding Guidelines.
See also:
• none
A17-6-1Required · Automated✓ compilable📄 공식 예제Official example
Non-standard entities shall not be added to standard namespaces.Non-standard entities shall not be added to standard namespaces.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef>
// $Id: A17-6-1.cpp 305588 2018-01-29 11:07:35Z michal.szczepankiewicz $
#include <cstdint>
#include <limits>
#include <memory>
#include <type_traits>
#include <utility>
namespace std
{
// Non-compliant - An alias definition is added to namespace std.
// This is a compile error in C++17, since std::byte is already defined.
using byte = std::uint8_t;
// Non-compliant - A function definition added to namespace std.
pair<int, int> operator+(pair<int, int> const& x, pair<int, int> const& y)
{
return pair<int, int>(x.first + y.first, x.second + y.second);
}
} // namespace std
struct MyType
{
int value;
};
namespace std
{
// Non-compliant - std::numeric_limits may not be specialized for
// non-arithmetic types [limits.numeric].
template <>
struct numeric_limits<MyType> : numeric_limits<int>
{
};
// Non-compliant - Structures in <type_traits>, except for std::common_type,
// may not be specialized [meta.type.synop].
template <>
struct is_arithmetic<MyType> : true_type
{
};
// Compliant - std::hash may be specialized for a user type if the
// specialization fulfills the requirements in [unord.hash].
template <>
struct hash<MyType>
{
using result_type = size_t; // deprecated in C++17
using argument_type = MyType; // deprecated in C++17
size_t operator()(MyType const& x) const noexcept
{
return hash<int>()(x.value);
}
};
} // namespace std⚠️ Adding declarations or definitions to namespace std or its sub-namespaces, or to
namespace posix or its sub-namespaces leads to undefined behavior.
Declaring an explicit specialization of a member function or member function template
of a standard library class or class template leads to undefined behavior.
Declaring an explicit or partial specialization of a member class template of a standard
library class or class template leads to undefined behavior.
Exception:
It is allowed by the language standard to add a specialization to namespace std if the
declaration depends on a user-defined type, meets the requirements for the original
template and is not explicitly forbidden.
It is allowed by the language standard to explicitly instantiate a template defined in
the standard library if the declaration depends on a user defined type and meets the
requirements for the original template.
See also:
• SEI CERT C++ Coding Standard [10]: DCL58-CPP: Do not modify the standard
namespaces
• C++ Core Guidelines [11]: SL.3: Do not add non-standard entities to namespace
std
• ISO/IEC 14882:2014 [3]: 17.6.4.2: [namespace.constraints]
• ISO/IEC 14882:2014 [3]: 18.3.2.1: [limits.numeric]
• ISO/IEC 14882:2014 [3]: 20.9.13: [unord.hash]
• ISO/IEC 14882:2014 [3]: 20.10.2: [meta.type.synop]
6.18 Language support library - partial
The corresponding chapter in the C++ standard defines the fundamental support
libraries, including integer types, dynamic memory , start and termination.
6.18.0 GeneralAdding declarations or definitions to namespace std or its sub-namespaces, or to
namespace posix or its sub-namespaces leads to undefined behavior.
Declaring an explicit specialization of a member function or member function template
of a standard library class or class template leads to undefined behavior.
Declaring an explicit or partial specialization of a member class template of a standard
library class or class template leads to undefined behavior.
Exception:
It is allowed by the language standard to add a specialization to namespace std if the
declaration depends on a user-defined type, meets the requirements for the original
template and is not explicitly forbidden.
It is allowed by the language standard to explicitly instantiate a template defined in
the standard library if the declaration depends on a user defined type and meets the
requirements for the original template.
See also:
• SEI CERT C++ Coding Standard [10]: DCL58-CPP: Do not modify the standard
namespaces
• C++ Core Guidelines [11]: SL.3: Do not add non-standard entities to namespace
std
• ISO/IEC 14882:2014 [3]: 17.6.4.2: [namespace.constraints]
• ISO/IEC 14882:2014 [3]: 18.3.2.1: [limits.numeric]
• ISO/IEC 14882:2014 [3]: 20.9.13: [unord.hash]
• ISO/IEC 14882:2014 [3]: 20.10.2: [meta.type.synop]
6.18 Language support library - partial
The corresponding chapter in the C++ standard defines the fundamental support
libraries, including integer types, dynamic memory , start and termination.
6.18.0 General
A18A18 (AUTOSAR)A18 (AUTOSAR-original)
A18-0-2Required · Automated✓ compilable
문자열→숫자 변환의 오류 상태를 검사한다The error state of conversion from string to a numeric value shall be checked
❌ 위반 예시Non-compliant example
#include <cstdlib>
#include <iostream>
#include <string>
int main() {
std::string s = "not a number";
int n = std::atoi(s.c_str()); // 변환 실패를 정상 0 과 구분 못함
std::cout << n << '\n'; // 0 — 입력이 숫자가 아닌데 성공으로 오인
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
#include <stdexcept>
int main() {
std::string s = "not a number";
try {
std::size_t pos;
int n = std::stoi(s, &pos);
if (pos != s.size()) throw std::invalid_argument("trailing chars");
std::cout << n << '\n';
} catch (const std::exception& e) { std::cout << "convert error: " << e.what() << '\n'; }
}⚠️ 근거: atoi 는 변환에 실패해도 0 을 반환할 뿐 오류 신호가 없고, 어디까지 변환했는지도 알려주지 않으며 범위 초과를 미정의 동작으로 둔다. 영향: 입력 "0" 과 변환 실패가 구분되지 않고 "12abc" 처럼 일부만 변환된 값이 조용히 통과해, 잘못된 수치가 계산·인덱스로 흘러든다. 대응: 예외를 던지는 std::stoi/stol(또는 std::from_chars)을 사용하고, 변환 종료 위치(pos)로 전체 문자열이 정확히 소비됐는지 확인한다.Rationale: atoi returns 0 even on failure with no error signal, does not report how far it converted, and leaves out-of-range as undefined behaviour. Impact: input "0" is indistinguishable from a failure and partially converted values like "12abc" pass silently, letting a wrong number flow into computations or indices. Fix: use std::stoi/stol (or std::from_chars) which signal errors, and check the end position (pos) to confirm the whole string was consumed.
A18-1-1Required · Automated✓ compilable
C 스타일 배열을 사용하지 않는다C-style arrays shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstddef>
static std::size_t count(int arr[]) { // 배열이 포인터로 붕괴 — 크기 정보 손실
return sizeof(arr) / sizeof(arr[0]); // 포인터 크기 / int 크기 (보통 2) — 틀림
}
int main() {
int a[10] = {0};
std::cout << count(a) << '\n'; // 10 이 아니라 2 — 크기 추론 실패
}✅ 준수 예시Compliant example
#include <iostream>
#include <array>
static std::size_t count(const std::array<int,10>& arr) {
return arr.size(); // 크기가 타입에 보존됨
}
int main() {
std::array<int,10> a{};
std::cout << count(a) << '\n'; // 10
}⚠️ 근거: C 스타일 배열은 함수에 전달될 때 첫 원소를 가리키는 포인터로 붕괴(decay)해 크기 정보를 잃고, 경계 검사도 제공하지 않는다. 영향: 함수 안에서 sizeof 로 원소 수를 구하려 하면 포인터 크기를 재게 되어 틀린 값이 나오고, 인덱스 접근의 경계를 알 수 없어 오버런이 숨는다. 대응: 크기를 타입에 보존하고 .size()·범위 기반 접근·경계 검사(at)를 제공하는 std::array(고정 크기)·std::vector(가변 크기)를 사용한다.Rationale: a C-style array decays to a pointer to its first element when passed to a function, losing size information and providing no bounds checking. Impact: trying to get the element count with sizeof inside the function measures the pointer instead, giving a wrong value, and the bounds for index access are unknown so overruns hide. Fix: use std::array (fixed size) or std::vector (dynamic) which preserve size in the type and provide .size(), range-based access, and bounds-checked at().
A18-1-2Required · Automated✓ compilable
std::vector<bool> 을 사용하지 않는다The std::vector<bool> specialization shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
int main() {
std::vector<bool> flags(4, false); // 비트 압축 특수화
auto ref = flags[0]; // bool& 가 아니라 프록시 객체 — auto 가 프록시를 잡음
flags[1] = true;
ref = true; // 프록시를 통한 대입 — 일반 vector 와 의미가 다름
std::cout << flags[0] << flags[1] << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <cstdint>
int main() {
std::vector<std::uint8_t> flags(4, 0); // 일반 컨테이너 — 원소 참조가 진짜 참조
std::uint8_t& ref = flags[0];
flags[1] = 1;
ref = 1;
std::cout << int(flags[0]) << int(flags[1]) << '\n';
}⚠️ 근거: std::vector<bool> 은 메모리 절약을 위해 각 원소를 1비트로 압축한 특수화라, operator[] 가 bool& 가 아니라 비트를 가리키는 프록시 객체를 반환한다. 영향: auto x = v[i] 가 프록시를 잡아 예상과 다르게 동작하고, &v[i] 로 진짜 bool* 를 얻을 수 없으며, 다른 컨테이너를 가정한 제네릭 코드가 깨진다. 대응: 불리언 시퀀스가 필요하면 크기가 고정이면 std::bitset 을, 가변이면 std::vector<std::uint8_t>(또는 char) 처럼 일반 원소 의미를 갖는 타입을 사용한다.Rationale: std::vector<bool> is a specialization that packs each element into a single bit to save memory, so operator[] returns a proxy object referring to a bit, not a bool&. Impact: auto x = v[i] captures the proxy and behaves unexpectedly, you cannot obtain a real bool* via &v[i], and generic code assuming a normal container breaks. Fix: use std::bitset for a fixed-size boolean sequence, or a type with normal element semantics like std::vector<std::uint8_t> (or char) for a dynamic one.
A18-1-3Required · Automated
std::auto_ptr 를 사용하지 않는다The std::auto_ptr type shall not be used
❌ 위반 예시Non-compliant example
#include <memory> // std::auto_ptr 은 C++11 에서 폐기, C++17 에서 제거됨(현 표준에선 컴파일조차 안 됨) std::auto_ptr<int> p(new int(1)); std::auto_ptr<int> q = p; // 복사처럼 보이지만 소유권을 몰래 이전 — p 는 널이 됨
✅ 준수 예시Compliant example
#include <memory> auto p = std::make_unique<int>(1); std::unique_ptr<int> q = std::move(p); // 소유권 이전이 std::move 로 명시됨 // (단독 소유는 unique_ptr, 이전은 항상 std::move 로 표현)
⚠️ 근거: std::auto_ptr 은 복사 생성·복사 대입이 사실상 소유권을 이전(원본을 널로)하는 위험한 의미를 가져, 복사처럼 보이는 연산이 원본을 조용히 무력화한다. 영향: auto_ptr 을 값으로 컨테이너에 넣거나 복사하면 원본 포인터가 널이 되어 예기치 않은 널 역참조·이중 관리가 발생하며, 이 때문에 C++11 에서 폐기되고 C++17 에서 표준에서 제거되었다(현 표준 빌드에서는 컴파일 자체가 실패한다). 대응: 단독 소유는 std::unique_ptr 로 표현하고 소유권 이전은 std::move 로 명시한다.Rationale: std::auto_ptr has dangerous semantics where copy construction and copy assignment actually transfer ownership (nulling the source), so an operation that looks like a copy silently disables the original. Impact: putting an auto_ptr by value into a container or copying it nulls the source pointer, causing unexpected null dereferences and double management, which is why it was deprecated in C++11 and removed from the standard in C++17 (it no longer even compiles under the current standard). Fix: express single ownership with std::unique_ptr and make ownership transfer explicit with std::move.
A18-5-1Required · Automated✓ compilable
malloc/calloc/realloc/free 를 사용하지 않는다Functions malloc, calloc, realloc and free shall not be used
❌ 위반 예시Non-compliant example
#include <cstdlib>
#include <iostream>
#include <string>
int main() {
// malloc 은 생성자를 호출하지 않음 → std::string 의 불변식이 성립하지 않은 메모리
auto* s = static_cast<std::string*>(std::malloc(sizeof(std::string)));
// s->size(); // 생성자 미호출 객체 사용 — 미정의 동작
std::free(s); // 소멸자도 미호출
std::cout << "raw malloc/free used\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
#include <string>
int main() {
auto s = std::make_unique<std::string>("hi"); // 생성자 호출·소멸 자동
std::cout << *s << '\n';
}⚠️ 근거: malloc/calloc/realloc/free 는 메모리 블록만 다룰 뿐 C++ 객체의 생성자·소멸자를 호출하지 않아, 비trivial 타입에 쓰면 객체가 초기화되지 않고 정리되지도 않는다. 영향: 생성자가 불려야 성립하는 불변식(std::string 의 내부 포인터 등)이 깨진 채 사용되어 미정의 동작이 되고, 소멸자 누락으로 자원이 누수되며, realloc 은 객체 이동 의미를 무시해 손상시킨다. 대응: 동적 객체는 new/delete 또는 스마트 포인터(make_unique/make_shared)로 관리해 생성·소멸이 자동으로 일어나게 한다.Rationale: malloc/calloc/realloc/free only manage memory blocks and do not call C++ constructors or destructors, so using them with non-trivial types leaves objects neither initialized nor cleaned up. Impact: invariants that require a constructor (such as the internal pointer of std::string) are used while broken — undefined behaviour — resources leak from missed destructors, and realloc corrupts objects by ignoring move semantics. Fix: manage dynamic objects with new/delete or smart pointers (make_unique/make_shared) so construction and destruction happen automatically.
A18-5-2Required · Automated✓ compilable
raw new/delete 를 직접 쓰지 않는다(make_unique/make_shared 사용)Non-placement new and delete expressions shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
struct Widget { int v = 7; };
static void risky(int argc) { if (argc >= 0) throw std::runtime_error("fail"); }
static void use(int argc) {
Widget* w = new Widget(); // raw new
risky(argc); // 예외 시 아래 delete 를 건너뜀 → 누수
delete w;
}
int main(int argc, char**) { try { use(argc); } catch (...) { std::cout << "leaked w\n"; } }✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
#include <stdexcept>
struct Widget { int v = 7; };
static void risky() { throw std::runtime_error("fail"); }
static void use() {
auto w = std::make_unique<Widget>(); // 예외에도 자동 해제
risky();
}
int main() { try { use(); } catch (...) { std::cout << "no leak (RAII)\n"; } }⚠️ 근거: 명시적 new 로 얻은 raw 포인터는 짝이 되는 delete 를 모든 실행 경로에서 사람이 직접 보장해야 하는데, 그 사이 코드가 예외를 던지면 delete 가 실행되지 않는다. 영향: 예외 경로에서 누수가 발생하고, 소유권이 여러 곳으로 흩어지면 이중 해제·use-after-free 같은 결함이 추가된다. 대응: new/delete 를 직접 쓰지 말고 make_unique/make_shared 로 소유권을 스마트 포인터에 맡겨 예외에도 수명이 자동 관리되게 한다.Rationale: a raw pointer from an explicit new requires a human to guarantee the matching delete on every execution path, but if code in between throws, the delete never runs. Impact: leaks occur on exception paths, and when ownership is scattered, defects like double free and use-after-free are added. Fix: instead of raw new/delete, give ownership to smart pointers via make_unique/make_shared so lifetime is managed automatically even under exceptions.
A18-5-3Required · Automated✓ compilable
delete 의 형태는 new 의 형태와 일치시킨다The form of delete shall match the form of the new expression used
❌ 위반 예시Non-compliant example
#include <iostream>
int main() {
int* a = new int[10]; // 배열 형태로 할당
a[0] = 1;
delete a; // new[] 를 delete 로 해제 — 형태 불일치, 미정의 동작
std::cout << "mismatched delete\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
int main() {
auto a = std::make_unique<int[]>(10); // 컨테이너/스마트포인터가 올바른 해제 보장
a[0] = 1;
std::cout << a[0] << '\n';
}⚠️ 근거: new 와 new[] 는 서로 다른 할당 경로를 사용하므로 표준은 new 는 delete 로, new[] 는 delete[] 로만 해제하도록 요구한다. 영향: 형태가 어긋나면 배열 원소의 소멸자가 호출되지 않거나 잘못된 크기로 메모리가 반환되어 힙이 손상되는 미정의 동작이 되며, 진단 없이 통과하기 쉽다. 대응: 직접 new[]/delete[] 를 쓰는 대신 std::vector 나 std::make_unique<T[]> 로 할당·해제를 자동화해 형태 불일치를 원천 차단한다.Rationale: new and new[] use different allocation paths, so the standard requires new to be released with delete and new[] with delete[]. Impact: a mismatched form skips array element destructors or frees with the wrong size, corrupting the heap — undefined behaviour that often passes with no diagnostic. Fix: instead of raw new[]/delete[], automate allocation and deallocation with std::vector or std::make_unique<T[]> to eliminate form mismatch.
A18-9-1Required · Automated✓ compilable
std::bind 를 사용하지 않는다(람다 사용)The std::bind shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <functional>
static int calc(int x, int factor) { return x * factor; }
int main() {
using namespace std::placeholders;
auto f = std::bind(calc, _1, 10); // 자리표시자 — 가독성 낮고 오버로드에 취약
std::cout << f(5) << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
static int calc(int x, int factor) { return x * factor; }
int main() {
auto f = [](int x){ return calc(x, 10); }; // 의도가 명확한 람다
std::cout << f(5) << '\n';
}⚠️ 근거: std::bind 는 _1, _2 같은 자리표시자로 인자를 재배치하는데, 이 표기는 호출 시 인자가 어디로 가는지 한눈에 드러나지 않고 오버로드된 함수나 완벽 전달과 결합할 때 모호성·오류가 생기기 쉽다. 영향: bind 표현식은 읽기 어려워 유지보수자가 동작을 오해하고, 인자 복사·참조 정책이 암묵적이라 의도치 않은 복사나 댕글링이 숨는다. 대응: 부분 적용·인자 재배치가 필요하면 의도가 코드에 그대로 드러나는 람다로 대체한다.Rationale: std::bind rearranges arguments with placeholders like _1, _2, but this notation does not make clear at a glance where call arguments go, and combining it with overloaded functions or perfect forwarding easily creates ambiguity and errors. Impact: bind expressions are hard to read so maintainers misunderstand the behaviour, and the implicit argument copy/reference policy hides unintended copies or dangling. Fix: replace partial application and argument rearrangement with a lambda whose intent is plainly visible in the code.
A18-9-2Required · Automated✓ compilable
rvalue 는 std::move, 전달 참조는 std::forward 로 전달한다Forwarding values to other functions shall be done via std::move or std::forward
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
#include <utility>
static void sink(std::string s) { std::cout << "sink: " << s << '\n'; }
template <typename T>
static void wrap(T&& x) { sink(std::move(x)); } // 전달 참조에 무조건 move
int main() {
std::string a = "keep me";
wrap(a); // a 는 lvalue 인데 move 됨 → a 가 비워짐
std::cout << "a after = '" << a << "'\n"; // '' — 호출자 객체 훼손
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
#include <utility>
static void sink(std::string s) { std::cout << "sink: " << s << '\n'; }
template <typename T>
static void wrap(T&& x) { sink(std::forward<T>(x)); } // 값 범주 보존
int main() {
std::string a = "keep me";
wrap(a); // lvalue → 복사로 전달, a 보존
std::cout << "a after = '" << a << "'\n"; // 'keep me'
}⚠️ 근거: 템플릿의 T&& 는 전달 참조(forwarding reference)로 lvalue 와 rvalue 를 모두 받는데, 여기에 std::move 를 무조건 적용하면 lvalue 로 넘긴 호출자 객체까지 이동 대상으로 만들어 버린다. 영향: 호출자가 계속 쓰려던 변수가 이동되어 비워지면(예제의 a), 그 객체에 의존하는 이후 코드가 빈 값·미지정 상태를 만나 조용한 버그가 된다. 대응: 전달 참조는 std::forward<T> 로 전달해 원래의 값 범주(lvalue 는 복사, rvalue 는 이동)를 보존하고, 확실한 rvalue 만 std::move 한다.Rationale: a template T&& is a forwarding reference that accepts both lvalues and rvalues, and applying std::move unconditionally makes even a caller object passed as an lvalue a move target. Impact: a variable the caller intended to keep using is moved-from and emptied (a in the example), so later code depending on it meets an empty or unspecified value — a silent bug. Fix: forward a forwarding reference with std::forward<T> to preserve the original value category (copy for lvalues, move for rvalues), and use std::move only on definite rvalues.
A18-9-3Required · Automated✓ compilable
const 객체에 std::move 를 적용하지 않는다The std::move shall not be used on const objects
❌ 위반 예시Non-compliant example
#include <iostream>
#include <string>
#include <utility>
int main() {
const std::string s = "payload";
std::string t = std::move(s); // s 가 const → 이동 불가, 조용히 복사로 폴백
std::cout << "s='" << s << "' t='" << t << "'\n"; // s 그대로 — move 의 의미 없음
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
#include <utility>
int main() {
std::string s = "payload"; // 이동할 대상은 비-const
std::string t = std::move(s); // 실제 이동 — s 의 버퍼를 t 가 가져감
std::cout << "moved; t='" << t << "'\n";
}⚠️ 근거: std::move 는 인자를 rvalue 로 캐스트할 뿐이고, 대상이 const 이면 const rvalue 가 되어 이동 생성자(비-const rvalue 참조를 받음)가 아니라 복사 생성자가 선택된다. 영향: const 객체에 std::move 를 쓰면 코드 작성자는 이동(저렴)을 기대하지만 실제로는 조용히 복사(비쌈)가 일어나, 의도한 성능 이점이 사라지고 잘못된 기대가 코드에 남는다. 대응: 이동하려는 객체는 비-const 로 선언하고, 정말 복사가 필요하면 std::move 없이 그대로 대입해 의도를 분명히 한다.Rationale: std::move only casts its argument to an rvalue, and if the target is const it becomes a const rvalue, so the copy constructor — not the move constructor (which takes a non-const rvalue reference) — is selected. Impact: using std::move on a const object makes the author expect a cheap move but silently performs an expensive copy, losing the intended performance benefit and leaving a wrong expectation in the code. Fix: declare objects to be moved as non-const, and when a copy is genuinely needed, assign directly without std::move to make the intent clear.
A18-0-1Required · Automated✓ compilable📄 공식 예제Official example
The C library facilities shall only be accessed through C++ library headers.The C library facilities shall only be accessed through C++ library headers.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A18-0-1: The C library facilities shall only be accessed through C++ library headers. // No code example provided in the official guideline PDF.
⚠️ C libraries (e.g. <stdio.h>) also have corresponding C++ libraries (e.g. <cstdio>). This
rule requires that the C++ version is used.
See also:
• MISRA C++ 2008 [7]: Rule 18-0-1 (Required) The C library shall not be used.
• HIC++ v4.0 [9]: 1.3.3 Do not use the C Standard Library .h headers.C libraries (e.g. <stdio.h>) also have corresponding C++ libraries (e.g. <cstdio>). This
rule requires that the C++ version is used.
See also:
• MISRA C++ 2008 [7]: Rule 18-0-1 (Required) The C library shall not be used.
• HIC++ v4.0 [9]: 1.3.3 Do not use the C Standard Library .h headers.
A18-0-3Required · Automated✓ compilable📄 공식 예제Official example
The library <clocale> (locale.h) and the setlocale function shall not be used.The library <clocale> (locale.h) and the setlocale function shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A18-0-3: The library <clocale> (locale.h) and the setlocale function shall not be used. // No code example provided in the official guideline PDF.
⚠️ A call to the setlocale function introduces a data race with other calls to setlocale
function.
It may also introduce a data race with calls to functions that are affected by the current
locale settings: fprintf, isprint, iswdigit, localeconv, tolower, fscanf, ispunct, iswgraph,
mblen, toupper, isalnum, isspace, iswlower, mbstowcs, towlower, isalpha, isupper,
iswprint, mbtowc, towupper, isblank, iswalnum, iswpunct, setlocale, wcscoll, iscntrl,
iswalpha, iswspace, strcoll, wcstod, isdigit, iswblank, iswupper, strerror, wcstombs,
isgraph, iswcntrl, iswxdigit, strtod, wcsxfrm, islower, iswctype, isxdigit, strxfrm, wctomb.
See also:
• JSF December 2005 [8]: AV Rule 19 <locale.h> and the setlocale function shall
not be used.
6.18.1 TypesA call to the setlocale function introduces a data race with other calls to setlocale
function.
It may also introduce a data race with calls to functions that are affected by the current
locale settings: fprintf, isprint, iswdigit, localeconv, tolower, fscanf, ispunct, iswgraph,
mblen, toupper, isalnum, isspace, iswlower, mbstowcs, towlower, isalpha, isupper,
iswprint, mbtowc, towupper, isblank, iswalnum, iswpunct, setlocale, wcscoll, iscntrl,
iswalpha, iswspace, strcoll, wcstod, isdigit, iswblank, iswupper, strerror, wcstombs,
isgraph, iswcntrl, iswxdigit, strtod, wcsxfrm, islower, iswctype, isxdigit, strxfrm, wctomb.
See also:
• JSF December 2005 [8]: AV Rule 19 <locale.h> and the setlocale function shall
not be used.
6.18.1 Types
A18-1-4Required · Automated✓ compilable📄 공식 예제Official example
A pointer pointing to an element of an array of objects shall not be passed to a smart pointer of single object type.A pointer pointing to an element of an array of objects shall not be passed to a smart pointer of single object type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <utility>
// $Id: A18-1-4.cpp 313638 2018-03-26 15:34:51Z jan.babst $
#include <memory>
class A
{
};
void F1()
{
// Create a dynamically allocated array of 10 objects of type A.
auto up1 = std::make_unique<A[]>(10); // Compliant
std::unique_ptr<A> up2{up1.release()}; // Non-compliant
}
void F2()
{
auto up1 = std::make_unique<A[]>(10); // Compliant
std::unique_ptr<A> up2;
up2.reset(up1.release()); // Non-compliant
}
void F3()
{
auto up = std::make_unique<A[]>(10); // Compliant
#if 0
std::shared_ptr<A> sp{up.release()};
#endif // Non-compliant
}
void F4()
{
auto up = std::make_unique<A[]>(10); // Compliant
std::shared_ptr<A> sp;
#if 0
sp.reset(up.release());
#endif // Non-compliant
}
void F5()
{
auto up = std::make_unique<A[]>(10); // Compliant
// sp will obtain its deleter from up, so the array will be correctly
// deallocated. However, this is no longer allowed in C++17.
#if 0
std::shared_ptr<A> sp{std::move(up)};
#endif // Non-compliant
sp.reset(new A{}); // leads to undefined behavior
}
void F6()
{
auto up = std::make_unique<A[]>(10); // Compliant
// Well behaving, but error-prone
#if 0
std::shared_ptr<A> sp{up.release(),
std::default_delete<A[]>{}};
#endif // Non-compliant
sp.reset(new A{}); // leads to undefined behavior
}⚠️ A dynamically allocated array of objects needs a corresponding deallocation function,
e.g. allocation by new[] requires deallocation by delete[], see also rule A18-5-3
in section 6.18.5. Smart pointers of a single object type, e.g. std::unique_ptr
<T> and std::shared_ptr<T>, by default have a deleter associated with them
which is only capable of deleting a single object. Therefore, it is undefined behavior
if a pointer pointing to an element of an array of objects is passed to such a
smart pointer. With the standard library smart pointer templates std::unique_ptr
and std::shared_ptr, this is possible when calling the constructor or the reset
function.
Note that the standard library provides a specialization of the std::unique_ptr
template for array types, std::unique_ptr<T[]>, and corresponding overloads for
std::make_unique. Usage of these features is conforming to this rule.
Note that corresponding features for std::shared_ptr are only available in C++17
(usage of std::shared_ptr<T[]> with C++11 and C++14 will lead to compilation
errors). The overloads for std::make_shared will only be available in C++20.
Furthermore, note that it is possible to create a smart pointer of single object type with
a custom deleter handling an array of objects. This is well behaving as long as this
smart pointer is actually managing an array of objects. However, such a use is error-
prone, since the smart pointer can be assigned a single object again in the reset
function; it may no longer be possible in C++17 (moving a std::unique_ptr<T[]>
into a std::shared_ptr<T> is no longer allowed); and it is superseded by better
alternatives in C++17 (availability of std:shared_ptr<T[]>). Therefore such usage
is considered not compliant to this rule.
In many cases, using a container such as std::array or std::vector or a smart
pointer to a container, e.g. std::shared_ptr<std::vector<T>>, is a better
alternative than a smart pointer to an array of objects.
See also:
• HIC++ v4.0 [9]: 17.3.4: Do not create smart pointers of array type.
• ISO/IEC 14882:2014 [3]: 20.8 Smart pointers: [smartptr]
• Rule A18-5-3 in section 6.18.5A dynamically allocated array of objects needs a corresponding deallocation function,
e.g. allocation by new[] requires deallocation by delete[], see also rule A18-5-3
in section 6.18.5. Smart pointers of a single object type, e.g. std::unique_ptr
<T> and std::shared_ptr<T>, by default have a deleter associated with them
which is only capable of deleting a single object. Therefore, it is undefined behavior
if a pointer pointing to an element of an array of objects is passed to such a
smart pointer. With the standard library smart pointer templates std::unique_ptr
and std::shared_ptr, this is possible when calling the constructor or the reset
function.
Note that the standard library provides a specialization of the std::unique_ptr
template for array types, std::unique_ptr<T[]>, and corresponding overloads for
std::make_unique. Usage of these features is conforming to this rule.
Note that corresponding features for std::shared_ptr are only available in C++17
(usage of std::shared_ptr<T[]> with C++11 and C++14 will lead to compilation
errors). The overloads for std::make_shared will only be available in C++20.
Furthermore, note that it is possible to create a smart pointer of single object type with
a custom deleter handling an array of objects. This is well behaving as long as this
smart pointer is actually managing an array of objects. However, such a use is error-
prone, since the smart pointer can be assigned a single object again in the reset
function; it may no longer be possible in C++17 (moving a std::unique_ptr<T[]>
into a std::shared_ptr<T> is no longer allowed); and it is superseded by better
alternatives in C++17 (availability of std:shared_ptr<T[]>). Therefore such usage
is considered not compliant to this rule.
In many cases, using a container such as std::array or std::vector or a smart
pointer to a container, e.g. std::shared_ptr<std::vector<T>>, is a better
alternative than a smart pointer to an array of objects.
See also:
• HIC++ v4.0 [9]: 17.3.4: Do not create smart pointers of array type.
• ISO/IEC 14882:2014 [3]: 20.8 Smart pointers: [smartptr]
• Rule A18-5-3 in section 6.18.5
A18-1-6Required · Automated✓ compilable📄 공식 예제Official example
All std::hash specializations for user-defined types shall have a noexcept function call operator.All std::hash specializations for user-defined types shall have a noexcept function call operator.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef>
#include <map>
// $Id: A18-1-6.cpp 311792 2018-03-15 04:15:08Z christof.meerwald $
#include <cstdint>
#include <functional>
#include <string>
#include <unordered_map>
class A
{
public:
A(uint32_t x, uint32_t y) noexcept : x(x), y(y) {}
uint32_t GetX() const noexcept { return x; }
uint32_t GetY() const noexcept { return y; }
friend bool operator == (const A &lhs, const A &rhs) noexcept
{ return lhs.x == rhs.x && lhs.y == rhs.y; }
private:
uint32_t x;
uint32_t y;
};
class B
{
public:
B(uint32_t x, uint32_t y) noexcept : x(x), y(y) {}
uint32_t GetX() const noexcept { return x; }
uint32_t GetY() const noexcept { return y; }
friend bool operator == (const B &lhs, const B &rhs) noexcept
{ return lhs.x == rhs.x && lhs.y == rhs.y; }
private:
uint32_t x;
uint32_t y;
};
namespace std
{
// Compliant
template <>
struct hash<A>
{
std::size_t operator()(const A& a) const noexcept
{
auto h1 = std::hash<decltype(a.GetX())>{}(a.GetX());
std::size_t seed { h1 + 0x9e3779b9 };
auto h2 = std::hash<decltype(a.GetY())>{}(a.GetY());
seed ^= h2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
};
// Non-compliant: string concatenation can potentially throw
template <>
struct hash<B>
{
std::size_t operator()(const B& b) const
{
std::string s{std::to_string(b.GetX()) + ',' + std::to_string(b.GetY())};
return std::hash<std::string>{}(s);
}
};
}
int main()
{
std::unordered_map<A, bool> m1 { { A{5, 7}, true } };
if (m1.count(A{4, 3}) != 0)
{
// ....
}
std::unordered_map<B, bool> m2 { { B{5, 7}, true } };
// Lookup can potentially throw if hash function throws
if (m2.count(B{4, 3}) != 0)
{
// ....
}
}⚠️ Some of standard library containers use std::hash indirectly . Function call operator
should be defined as noexcept to prevent container simple access from throwing an
exception.
Note: Consider own hash specializations to use standard library specializations
combined with XOR (ˆ) operation as implemented by boost::hash_combine:
seed ^= std::hash< decltype (v)>{}(v) + 0x9e3779b9 + (seed << 6) + ( seed >> 2);
See also:
• C++ Core Guidelines [11]: C.89: Make a hash noexcept.
6.18.2 Implementation propertiesSome of standard library containers use std::hash indirectly . Function call operator
should be defined as noexcept to prevent container simple access from throwing an
exception.
Note: Consider own hash specializations to use standard library specializations
combined with XOR (ˆ) operation as implemented by boost::hash_combine:
seed ^= std::hash< decltype (v)>{}(v) + 0x9e3779b9 + (seed << 6) + ( seed >> 2);
See also:
• C++ Core Guidelines [11]: C.89: Make a hash noexcept.
6.18.2 Implementation properties
A18-5-10Required · Automated✓ compilable📄 공식 예제Official example
Placement new shall be used only with properly aligned pointers to sufficient storage capacity.Placement new shall be used only with properly aligned pointers to sufficient storage capacity.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A18-5-10.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
#include <new>
#include <cstdint>
void Foo()
{
uint8_t c;
uint64_t* ptr = ::new (&c) uint64_t;
//non-compliant, insufficient storage
}
void Bar()
{
uint8_t c; // Used elsewhere in the function
uint8_t buf[sizeof(uint64_t)];
uint64_t* ptr = ::new (buf) uint64_t;
//non-compliant, storage not properly aligned
}⚠️ Placement new can be useful for cases in which allocation is required separately
from type initialization, e.g. memory allocators, generic containers. Correct usage
of placement new requires passing a pointer that:
• is suitably aligned
• provides sufficient storage memory
Violating above constrains will result in an object constructed at a misaligned location
or memory initialization outside of the allocated bounds, which leads to undefined
behaviour. An initial memory pointer used for placement new shall not be used after
the call.
See also:
• SEI CERT C++ Coding Standard [10]: MEM54-CPP: Provide placement new with
properly aligned pointers to sufficient storage capacityPlacement new can be useful for cases in which allocation is required separately
from type initialization, e.g. memory allocators, generic containers. Correct usage
of placement new requires passing a pointer that:
• is suitably aligned
• provides sufficient storage memory
Violating above constrains will result in an object constructed at a misaligned location
or memory initialization outside of the allocated bounds, which leads to undefined
behaviour. An initial memory pointer used for placement new shall not be used after
the call.
See also:
• SEI CERT C++ Coding Standard [10]: MEM54-CPP: Provide placement new with
properly aligned pointers to sufficient storage capacity
A18-5-11Required · Automated✓ compilable📄 공식 예제Official example
“operator new” and “operator delete” shall be defined together.“operator new” and “operator delete” shall be defined together.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef>
//% $Id: A18-5-11.cpp 316977 2018-04-20 12:37:31Z christof.meerwald $
#include <cstdlib>
class A {
public:
static void * operator new(std::size_t s); // Compliant: operator new
static void operator delete(void *ptr); // defined together with
// operator delete
};
class B {
public:
static void * operator new(std::size_t s); // Non-compliant: operator
static void * operator new [](std::size_t s); // new defined without
// corresponding operator
// delete
};⚠️ Providing a custom allocation function ( operator new ) for a class or program implies
the use of a custom memory management scheme different to the default one. It is
therefore unlikely that memory allocated using a custom allocation function can be
deallocated by the default deallocation function ( operator delete ).
See also:
• HIC++ v4.0 [9]: 12.3.1: Correctly declare overloads for operator new and delete
6.18.9 Other runtime supportProviding a custom allocation function ( operator new ) for a class or program implies
the use of a custom memory management scheme different to the default one. It is
therefore unlikely that memory allocated using a custom allocation function can be
deallocated by the default deallocation function ( operator delete ).
See also:
• HIC++ v4.0 [9]: 12.3.1: Correctly declare overloads for operator new and delete
6.18.9 Other runtime support
A18-5-4Required · Automated✓ compilable📄 공식 예제Official example
If a project has sized or unsized version of operator “delete” globally defined, then both sized and unsized versions shall be defined.If a project has sized or unsized version of operator “delete” globally defined, then both sized and unsized versions shall be defined.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef> //% $Id: A18-5-4.cpp 289415 2017-10-04 09:10:20Z piotr.serwa $ #include <cstdlib> void operator delete( void* ptr) noexcept // Compliant - sized version is defined { std::free(ptr); } void operator delete( void* ptr, std::size_t size) noexcept // Compliant - unsized version is defined { std::free(ptr); }
⚠️ Since C++14 Language Standard it is allowed to overload both sized and unsized
versions of the “delete” operator. Sized version provides more efficient way of memory
deallocation than the unsized one, especially when the allocator allocates in size
categories instead of storing the size nearby the object.
See also:
• noneSince C++14 Language Standard it is allowed to overload both sized and unsized
versions of the “delete” operator. Sized version provides more efficient way of memory
deallocation than the unsized one, especially when the allocator allocates in size
categories instead of storing the size nearby the object.
See also:
• none
A18-5-5Required · Partially automated✓ compilable📄 공식 예제Official example
Memory management functions shall ensure the following: (a) deterministic behavior resulting with the existence of worst-case execution time, (b) avoiding memory fragmentation, (c) avoid running out of memory, (d) --- PAGE 350 --- avoiding mismatched allocations or deallocations, (e) no dependence on non-deterministic calls to kernel.Memory management functions shall ensure the following: (a) deterministic behavior resulting with the existence of worst-case execution time, (b) avoiding memory fragmentation, (c) avoid running out of memory, (d) --- PAGE 350 --- avoiding mismatched allocations or deallocations, (e) no dependence on non-deterministic calls to kernel.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A18-5-5.cpp 289815 2017-10-06 11:19:11Z michal.szczepankiewicz $ #define __GNU_SOURCE #include <dlfcn.h> #include <cstddef> void* MallocBad(size_t size) // Non-compliant, malloc from libc does not // guarantee deterministic execution time { void* (*libcMalloc)(size_t) = (void * (*)(size_t))dlsym(RTLD_NEXT, "malloc"); return libcMalloc(size); } void FreeBad(void * ptr) // Non-compliant, malloc from libc does not guarantee // deterministic execution time { void ( *libcFree)(void*) = (void ( *)(void*))dlsym(RTLD_NEXT, "free"); libcFree(ptr); } void* MallocGood(size_t size) // Compliant - custom malloc implementation that // will guarantee deterministic execution time { // Custom implementation that provides deterministic worst-case execution // time } void FreeGood(void * ptr) // Compliant - custom malloc implementation that will // guarantee deterministic execution time { // Custom implementation that provides deterministic worst-case execution // time }
⚠️ Memory management errors occur commonly and they can affect application stability
and correctness. The main problems of dynamic memory management are as
following:
• Non deterministic worst-case execution time of allocation and deallocation
• Invalid memory access
• Mismatched allocations and deallocations
• Memory fragmentation
• Running out of memory
Custom memory management functions (custom allocators) need to address all of this
problems for the project and all libraries used in the project.
T o ensure the worst-case execution time, the memory management functions need to
be executed without context switch and without syscalls.
T o prevent running out of memory , an executable is supposed to define its maximal
memory needs, which are pre-allocated for this executable during its startup.
Memory management functions include operators new and delete, as well as low-
level functions malloc and free. Nevertheless code written in C++ language uses
new and delete operators, and direct use of malloc and free operations do not occur,
some libraries, e.g. exception handling mechanism routines of libgcc uses malloc and
free functions directly and omits new and delete operators usage. Custom memory
management functionality needs to provide custom implementation of C++ new and
delete operators, as well as implementation of malloc and free operations to hide
incorrect dynamic memory allocation/deallocation in linked libraries.
Note: If custom memory management requires to use custom std::new_handler, its
implementation shall perform one of the following:
• make more storage available for allocation and then return
• throw an exception of type bad_alloc or a class derived from bad_alloc
• terminate execution of the program without returning to the caller
See also:
• noneMemory management errors occur commonly and they can affect application stability
and correctness. The main problems of dynamic memory management are as
following:
• Non deterministic worst-case execution time of allocation and deallocation
• Invalid memory access
• Mismatched allocations and deallocations
• Memory fragmentation
• Running out of memory
Custom memory management functions (custom allocators) need to address all of this
problems for the project and all libraries used in the project.
T o ensure the worst-case execution time, the memory management functions need to
be executed without context switch and without syscalls.
T o prevent running out of memory , an executable is supposed to define its maximal
memory needs, which are pre-allocated for this executable during its startup.
Memory management functions include operators new and delete, as well as low-
level functions malloc and free. Nevertheless code written in C++ language uses
new and delete operators, and direct use of malloc and free operations do not occur,
some libraries, e.g. exception handling mechanism routines of libgcc uses malloc and
free functions directly and omits new and delete operators usage. Custom memory
management functionality needs to provide custom implementation of C++ new and
delete operators, as well as implementation of malloc and free operations to hide
incorrect dynamic memory allocation/deallocation in linked libraries.
Note: If custom memory management requires to use custom std::new_handler, its
implementation shall perform one of the following:
• make more storage available for allocation and then return
• throw an exception of type bad_alloc or a class derived from bad_alloc
• terminate execution of the program without returning to the caller
See also:
• none
A18-5-6Required · Non-automated✓ compilable📄 공식 예제Official example
An analysis shall be performed to analyze the failure modes of dynamic memory management. In particular, the following failure modes shall be analyzed: (a) non-deterministic behavior resulting with nonexistence of worst-case execution time, (b) memory fragmentation, (c) running out of memory, (d) mismatched allocations and deallocations, (e) dependence on non-deterministic calls to kernel.An analysis shall be performed to analyze the failure modes of dynamic memory management. In particular, the following failure modes shall be analyzed: (a) non-deterministic behavior resulting with nonexistence of worst-case execution time, (b) memory fragmentation, (c) running out of memory, (d) mismatched allocations and deallocations, (e) dependence on non-deterministic calls to kernel.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A18-5-6: An analysis shall be performed to analyze the failure modes of dynamic memory management. In particular, the following failure modes shall be analyzed: (a) non-deterministic behavior resulting with nonexistence of worst-case execution time, (b) memory fragmentation, (c) running out of memory, (d) mismatched allocations and deallocations, (e) dependence on non-deterministic calls to kernel. // No code example provided in the official guideline PDF.
⚠️ The worst-case execution time and behavior of memory management functions are
specific to each implementation. In order to use dynamic memory in the project, an
analysis needs to be done to determine possible errors and worst-case execution time
of allocation and deallocation functions.
Note that standard C++ implementation violates some of this requirements. However,
listed problems can be addressed by implementing or using a custom memory
allocator.
See also:
• noneThe worst-case execution time and behavior of memory management functions are
specific to each implementation. In order to use dynamic memory in the project, an
analysis needs to be done to determine possible errors and worst-case execution time
of allocation and deallocation functions.
Note that standard C++ implementation violates some of this requirements. However,
listed problems can be addressed by implementing or using a custom memory
allocator.
See also:
• none
A18-5-7Required · Non-automated✓ compilable📄 공식 예제Official example
If non-realtime implementation of dynamic memory management functions is used in the project, then memory shall only be allocated and deallocated during non-realtime program phases.If non-realtime implementation of dynamic memory management functions is used in the project, then memory shall only be allocated and deallocated during non-realtime program phases.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A18-5-7.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <memory>
#include <vector>
std::int8_t AppMainLoop() noexcept
{
std::int8_t retCode = 0;
std::int32_t* arr[10];
while (true)
{
for (std::int8_t i = 0; i < 10; ++i)
{
arr[i] = new std::int32_t{
i}; // Non-compliant - allocation in a phase that
// requires real-time
}
// Implementation
for (auto& i : arr)
{
delete i; // Non-compliant - deallocation in a phase that requires
// real-time
}
}
return retCode;
}
static std::int32_t * object =
new std::int32_t{0}; // Compliant- allocating in start-up phase
int main(int, char **)
{
std::unique_ptr<std::int32_t> ptr =
std::make_unique<std::int32_t>(0); // Compliant
std::vector<std::int32_t> vec; // Compliant
vec.reserve(10); // Compliant
std::int8_t code = AppMainLoop();
return code;
}⚠️ If worst-case execution time of memory management functions can not be determined,
then dynamic memory usage is prohibited during realtime program phase, but it can
be used e.g. during initialization or non-realtime state transitions.
See: Real-time.
See also:
• noneIf worst-case execution time of memory management functions can not be determined,
then dynamic memory usage is prohibited during realtime program phase, but it can
be used e.g. during initialization or non-realtime state transitions.
See: Real-time.
See also:
• none
A18-5-8Required · Partially automated✓ compilable📄 공식 예제Official example
Objects that do not outlive a function shall have automatic storage duration.Objects that do not outlive a function shall have automatic storage duration.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <string>
#include <cstddef>
#include <utility>
//% $Id: A18-5-8.cpp 311792 2018-03-15 04:15:08Z christof.meerwald $
#include <cstdint>
#include <memory>
#include <vector>
class StackBitmap
{
public:
constexpr static size_t maxSize = 65535;
using BitmapRawType = std::array<uint8_t, maxSize>;
StackBitmap(const std::string& path, uint32_t bitmapSize)
{
// read bitmapSize bytes from the file path
}
const BitmapRawType& GetBitmap() const noexcept { return bmp; }
private:
BitmapRawType bmp;
};
void AddWidgetToLayout(int32_t row, int32_t col)
{
auto idx = std::make_pair(row, col); // Compliant
auto spIdx = std::make_shared<std::pair<int32_t, int32_t>>(
row, col); // Non-compliant
// addWidget to index idx
}
uint8_t CalcAverageBitmapColor(const std::string& path, uint32_t bitmapSize)
{
std::vector<uint8_t> bmp1(bitmapSize); // Compliant
// read bitmap from path
StackBitmap bmp2(path, bitmapSize); // Non-compliant
bmp2.GetBitmap();
}
int main(int, char **)
{
AddWidgetToLayout(5, 8);
CalcAverageBitmapColor("path/to/bitmap.bmp", 32000);
}⚠️ Creating objects with automatic storage duration implies that there is no additional
allocation and deallocation cost, which would occur when using dynamic storage.
Note: This rule applies only to objects created in a function scope, it does not forbid
the object to internally allocate additional memory on heap.
Exception:
Objects causing high memory utilization may be allocated on heap using memory
managing objects.
See also:
• C++ Core Guidelines [11]: R.5: Prefer scoped objects, don’t heap-allocate
unnecessarily .Creating objects with automatic storage duration implies that there is no additional
allocation and deallocation cost, which would occur when using dynamic storage.
Note: This rule applies only to objects created in a function scope, it does not forbid
the object to internally allocate additional memory on heap.
Exception:
Objects causing high memory utilization may be allocated on heap using memory
managing objects.
See also:
• C++ Core Guidelines [11]: R.5: Prefer scoped objects, don’t heap-allocate
unnecessarily .
A18-5-9Required · Automated✓ compilable📄 공식 예제Official example
Custom implementations of dynamic memory allocation and deallocation functions shall meet the semantic requirements specified in the corresponding “Required behaviour” clause from the C++ Standard.Custom implementations of dynamic memory allocation and deallocation functions shall meet the semantic requirements specified in the corresponding “Required behaviour” clause from the C++ Standard.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef>
//% $Id: A18-5-9.cpp 305629 2018-01-29 13:29:25Z piotr.serwa $
#include <new>
void* operator new(std::size_t count, const std::nothrow_t& tag)
{
extern void * custom_alloc(std::size_t); // Implemented elsewhere; may return
nullptr
if (void *ret = custom_alloc(count))
{
return ret;
}
throw std::bad_alloc(); //non-compliant, this version of new method shall not
throw exceptions
}⚠️ It is possible to provide custom implementations of global dynamic memory
allocation/deallocation functions. Requirements for custom implementations for each
function declaration are specified in the C++ Standard in the section “Required
behaviour”. If the provided function do not implement the required semantics, it can
lead to undefined behaviour.
See also:
• SEI CERT C++ Coding Standard [10]: MEM55-CPP: Honor replacement dynamic
storage management requirementsIt is possible to provide custom implementations of global dynamic memory
allocation/deallocation functions. Requirements for custom implementations for each
function declaration are specified in the C++ Standard in the section “Required
behaviour”. If the provided function do not implement the required semantics, it can
lead to undefined behaviour.
See also:
• SEI CERT C++ Coding Standard [10]: MEM55-CPP: Honor replacement dynamic
storage management requirements
A18-9-4Required · Automated✓ compilable📄 공식 예제Official example
An argument to std::forward shall not be subsequently used.An argument to std::forward shall not be subsequently used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A18-9-4.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <iostream>
#include <utility>
template <typename T1, typename T2>
void F1(T1 const& t1, T2& t2){
// ...
};
template <typename T1, typename T2>
void F2(T1&& t1, T2&& t2)
{
f1(std::forward<T1>(t1), std::forward<T2>(t2));
++t2; // Non-compliant
};⚠️ Depending on the value category of parameters used in the call, std::forward may
result in a move of the parameter. When the value is an lvalue, modifications to the
parameter will affect the argument of the caller. If the value is an rvalue, the value may
be in indeterminate state after the call to std::forward.
See also:
• HIC++ v4.0 [9]: 17.3.3 Do not subsequently use the argument to std::forward.
6.19 Diagnostics library - partial
6.19.4 Error numbersDepending on the value category of parameters used in the call, std::forward may
result in a move of the parameter. When the value is an lvalue, modifications to the
parameter will affect the argument of the caller. If the value is an rvalue, the value may
be in indeterminate state after the call to std::forward.
See also:
• HIC++ v4.0 [9]: 17.3.3 Do not subsequently use the argument to std::forward.
6.19 Diagnostics library - partial
6.19.4 Error numbers
A20A20 (AUTOSAR)A20 (AUTOSAR-original)
A20-8-1Required · Automated✓ compilable
소유 포인터(owning pointer)는 스마트 포인터로 표현한다A std::unique_ptr shall be used to represent exclusive ownership
❌ 위반 예시Non-compliant example
#include <iostream>
struct Widget { int v = 7; };
static Widget* create() { return new Widget(); } // 소유권이 모호한 raw 반환
int main() {
Widget* w = create(); // 호출자가 delete 해야 하는지 인터페이스만 봐선 모름
std::cout << w->v << '\n';
delete w; // 깜빡하면 누수, 두 번 하면 이중 해제
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
struct Widget { int v = 7; };
static std::unique_ptr<Widget> create() { return std::make_unique<Widget>(); }
int main() {
auto w = create(); // 반환 타입이 단독 소유권을 명시 — 해제는 자동
std::cout << w->v << '\n';
}⚠️ 근거: raw 포인터는 그것이 단지 가리키기만 하는지(비소유) 아니면 해제 책임까지 넘기는지(소유) 타입만으로는 구분되지 않아, 소유권 계약이 인터페이스에 드러나지 않는다. 영향: 함수가 new 한 raw 포인터를 반환하면 호출자가 delete 책임을 모르거나 잘못 알아 누수·이중 해제가 발생하고, 예외 경로에서 특히 취약하다. 대응: 단독 소유는 std::unique_ptr, 공유 소유는 std::shared_ptr 로 반환·전달해 소유권과 해제 책임을 타입으로 명시한다.Rationale: a raw pointer does not distinguish by type alone whether it merely points (non-owning) or transfers the responsibility to release (owning), so the ownership contract is not expressed in the interface. Impact: a function returning a new-ed raw pointer leaves the caller unaware or mistaken about the delete responsibility, causing leaks or double frees, and is especially fragile on exception paths. Fix: return and pass std::unique_ptr for exclusive ownership and std::shared_ptr for shared ownership to make ownership and release responsibility explicit in the type.
A20-8-4Required · Automated✓ compilable
공유가 필요 없으면 shared_ptr 대신 unique_ptr 를 쓴다A std::unique_ptr shall be used over std::shared_ptr if ownership is not shared
❌ 위반 예시Non-compliant example
#include <iostream>
#include <memory>
struct Widget { int v = 7; };
int main() {
std::shared_ptr<Widget> w = std::make_shared<Widget>(); // 단독 소유에 shared
std::cout << w->v << " use_count=" << w.use_count() << '\n'; // 원자적 카운트 비용
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
struct Widget { int v = 7; };
int main() {
auto w = std::make_unique<Widget>(); // 단독 소유 — 오버헤드 없음
std::cout << w->v << '\n';
}⚠️ 근거: shared_ptr 는 여러 소유자가 수명을 공유하기 위해 제어 블록과 원자적(스레드 안전) 참조 카운트를 유지하는데, 소유자가 하나뿐이면 이 비용이 순수한 낭비다. 영향: 단독 소유에 shared_ptr 를 쓰면 매 복사·소멸마다 원자적 증감 비용이 들고, 메모리(제어 블록)도 더 쓰며, 의도(이 자원은 한 소유자)가 코드에 잘못 전달된다. 대응: 소유권을 실제로 공유해야 할 때만 shared_ptr 를 쓰고, 그 외에는 더 가볍고 의도가 분명한 unique_ptr 를 사용한다.Rationale: shared_ptr maintains a control block and an atomic (thread-safe) reference count so multiple owners can share a lifetime, but when there is only one owner this cost is pure waste. Impact: using shared_ptr for sole ownership pays an atomic increment/decrement on every copy and destruction, uses extra memory for the control block, and miscommunicates the intent (this resource has one owner). Fix: use shared_ptr only when ownership is genuinely shared, and otherwise use the lighter, clearer unique_ptr.
A20-8-5Required · Automated✓ compilable
unique_ptr 는 std::make_unique 로 생성한다std::make_unique shall be used to construct objects owned by std::unique_ptr
❌ 위반 예시Non-compliant example
#include <iostream>
#include <memory>
struct Widget { int v = 7; };
int main() {
std::unique_ptr<Widget> w(new Widget()); // 타입 중복 표기, 예외 안전성 약함
std::cout << w->v << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
struct Widget { int v = 7; };
int main() {
auto w = std::make_unique<Widget>(); // 타입 한 번, 예외 안전
std::cout << w->v << '\n';
}⚠️ 근거: make_unique 는 객체 생성과 unique_ptr 소유를 한 표현식으로 묶어, 타입 이름을 한 번만 쓰고 raw new 포인터가 잠시라도 소유자 없이 노출되는 구간을 없앤다. 영향: 직접 new 로 unique_ptr 를 만들면 타입을 두 번 적어 불일치 위험이 생기고, 함수 인자로 여러 new 를 평가하는 옛 문맥에서는 예외 시 누수가 날 수 있으며 코드가 장황해진다. 대응: unique_ptr 생성은 일관되게 make_unique 로 하고, 사용자 deleter 같은 특수한 경우에만 예외적으로 직접 생성한다.Rationale: make_unique binds object creation and unique_ptr ownership into one expression, writing the type name once and eliminating any window where a raw new pointer is exposed without an owner. Impact: constructing a unique_ptr directly with new repeats the type (risking mismatch), can leak on exceptions in older contexts that evaluate multiple news as arguments, and is more verbose. Fix: construct unique_ptr consistently with make_unique, using direct construction only for special cases like a custom deleter.
A20-8-6Required · Automated✓ compilable
shared_ptr 는 std::make_shared 로 생성한다std::make_shared shall be used to construct objects owned by std::shared_ptr
❌ 위반 예시Non-compliant example
#include <iostream>
#include <memory>
struct Widget { int v = 7; };
int main() {
std::shared_ptr<Widget> w(new Widget()); // 객체와 제어블록을 별도로 두 번 할당
std::cout << w->v << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
struct Widget { int v = 7; };
int main() {
auto w = std::make_shared<Widget>(); // 객체+제어블록을 한 번에 할당
std::cout << w->v << '\n';
}⚠️ 근거: make_shared 는 관리 대상 객체와 참조 카운트를 담는 제어 블록을 한 번의 할당으로 함께 배치해, 메모리 할당 횟수와 캐시 미스를 줄이고 예외 안전성을 높인다. 영향: shared_ptr<T>(new T) 형태는 객체와 제어 블록을 두 번 할당해 비효율적이고, new 와 shared_ptr 생성 사이 예외 시 누수 위험이 있다. 대응: shared_ptr 생성은 make_shared 로 한다(단, 객체와 제어 블록 수명을 분리하고 싶거나 weak_ptr 로 큰 객체 메모리를 오래 붙잡고 싶지 않은 특수 경우는 예외).Rationale: make_shared places the managed object and the control block holding the reference count together in a single allocation, reducing allocation count and cache misses and improving exception safety. Impact: the shared_ptr<T>(new T) form allocates the object and control block twice (inefficient) and risks a leak on an exception between the new and the shared_ptr construction. Fix: construct shared_ptr with make_shared (except in special cases where you want the object and control-block lifetimes separated, or to avoid a weak_ptr keeping a large object memory alive).
A20-8-7Advisory · Automated✓ compilable
순환 참조를 끊기 위해 weak_ptr 를 사용한다A std::weak_ptr shall be used to represent temporary shared ownership
❌ 위반 예시Non-compliant example
#include <iostream>
#include <memory>
struct Node {
std::shared_ptr<Node> next;
std::shared_ptr<Node> prev; // 서로를 shared 로 가리킴 → 순환 참조
~Node() { std::cout << "~Node\n"; }
};
int main() {
auto a = std::make_shared<Node>();
auto b = std::make_shared<Node>();
a->next = b; b->prev = a; // a,b 의 카운트가 0 으로 못 내려감 → 소멸자 미호출, 누수
std::cout << "use_count a=" << a.use_count() << '\n'; // 2
}✅ 준수 예시Compliant example
#include <iostream>
#include <memory>
struct Node {
std::shared_ptr<Node> next;
std::weak_ptr<Node> prev; // 역방향(비소유) 링크는 weak_ptr
~Node() { std::cout << "~Node\n"; }
};
int main() {
auto a = std::make_shared<Node>();
auto b = std::make_shared<Node>();
a->next = b; b->prev = a; // weak 는 카운트를 올리지 않음 → 정상 소멸
std::cout << "use_count a=" << a.use_count() << '\n'; // 1
}⚠️ 근거: 두 객체가 서로를 shared_ptr 로 가리키면 각자의 참조 카운트가 상대 때문에 0 으로 내려가지 못해, 외부 참조가 모두 사라져도 둘 다 해제되지 않는다. 영향: 이런 순환 참조는 소멸자가 호출되지 않는 메모리 누수를 만들고, 누수가 쌓이면 장시간 구동 시스템의 메모리가 고갈된다. 대응: 소유 관계의 한 방향(부모→자식 등)만 shared_ptr 로 두고, 역방향이나 비소유 관찰 링크는 카운트를 올리지 않는 weak_ptr 로 두어 순환을 끊는다.Rationale: when two objects point at each other with shared_ptr, neither reference count can reach zero because of the other, so even after all external references are gone neither is released. Impact: such a reference cycle creates a memory leak where destructors are never called, and accumulated leaks exhaust memory in long-running systems. Fix: keep only one direction of an ownership relationship (parent to child) as shared_ptr and make the reverse or non-owning observing link a weak_ptr, which does not raise the count, breaking the cycle.
A20-8-2Required · Automated✓ compilable📄 공식 예제Official example
A std::unique_ptr shall be used to represent exclusive ownership.A std::unique_ptr shall be used to represent exclusive ownership.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstdint>
#include <utility>
// $Id: A20-8-2.cpp 308981 2018-02-26 08:11:52Z michal.szczepankiewicz $
#include <thread>
#include <memory>
struct A
{
A(std::uint8_t xx, std::uint8_t yy) : x(xx), y(yy) {}
std::uint8_t x;
std::uint8_t y;
};
//consumes object obj or just uses it
void Foo(A * obj) { }
void Bar(std::unique_ptr<A> obj) { }
int main(void)
{
A* a = new A(3,5); //non-compliant with A18-5-2
std::unique_ptr<A> spA = std::make_unique<A>(3,5);
//non-compliant, not clear if function assumes
//ownership of the object
std::thread th1{&Foo, a};
std::thread th2{&Foo, a};
//compliant, it is clear that function Bar
//assumes ownership
std::thread th3{&Bar, std::move(spA)};
th1.join();
th2.join();
th3.join();
return 0;
}⚠️ std::unique_ptr is a smart pointer that owns and manages another object and removes
it when it goes out of scope. It has almost no overhead over a raw pointer and clearly
states developers intentions and ownership status of the object.
Note: Further usage of the instance of std::unique_ptr in another scope requires
transferring ownership using move semantics.
See also:
• JSF December 2005 [8]: AV Rule 112: Function return values should not obscure
resource ownership.
• C++ Core Guidelines [11]: F .26: Use a unique_ptr<T> to transfer ownership
where a pointer is needed
• C++ Core Guidelines [11]: R.20: Use unique_ptr or shared_ptr to represent
ownershipstd::unique_ptr is a smart pointer that owns and manages another object and removes
it when it goes out of scope. It has almost no overhead over a raw pointer and clearly
states developers intentions and ownership status of the object.
Note: Further usage of the instance of std::unique_ptr in another scope requires
transferring ownership using move semantics.
See also:
• JSF December 2005 [8]: AV Rule 112: Function return values should not obscure
resource ownership.
• C++ Core Guidelines [11]: F .26: Use a unique_ptr<T> to transfer ownership
where a pointer is needed
• C++ Core Guidelines [11]: R.20: Use unique_ptr or shared_ptr to represent
ownership
A20-8-3Required · Automated✓ compilable📄 공식 예제Official example
A std::shared_ptr shall be used to represent shared ownership. --- PAGE 363 ---A std::shared_ptr shall be used to represent shared ownership. --- PAGE 363 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A20-8-3.cpp 308507 2018-02-21 13:23:57Z michal.szczepankiewicz $
#include <memory>
#include <cstdint>
#include <thread>
struct A
{
A(std::uint8_t xx, std::uint8_t yy) : x(xx), y(yy) {}
std::uint8_t x;
std::uint8_t y;
};
void Foo(A * obj) { }
void Bar(A * obj) { }
void Foo2(std::shared_ptr<A> obj) { }
void Bar2(std::shared_ptr<A> obj) { }
int main(void)
{
A* a = new A(3,5); //non-compliant with A18-5-2
std::shared_ptr<A> spA = std::make_shared<A>(3,5);
//non-compliant, not clear who is responsible
//for deleting object a
std::thread th1{&Foo, a};
std::thread th2{&Bar, a};
//compliant, object spA gets deleted
//when last shared_ptr gets destructed
std::thread th3{&Foo2, spA};
std::thread th4{&Bar2, spA};
th1.join();
th2.join();
th3.join();
th4.join();
return 0;
}⚠️ std::shared_ptr allows to retain shared ownership by keeping multiple std::shared_ptr
instances pointing at the same object. The object is removed when the last std
::shared_ptr instance goes out of scope. Although reference counting mechanism
included brings some overhead over a raw pointer, it clearly states ownership status of
the object and effectively prevents from possible memory leaks.
See also:
• JSF December 2005 [8]: AV Rule 112: Function return values should not obscure
resource ownership.
• C++ Core Guidelines [11]: F .27: Use a shared_ptr<T> to share ownership
• C++ Core Guidelines [11]: R.20: Use unique_ptr or shared_ptr to represent
ownershipstd::shared_ptr allows to retain shared ownership by keeping multiple std::shared_ptr
instances pointing at the same object. The object is removed when the last std
::shared_ptr instance goes out of scope. Although reference counting mechanism
included brings some overhead over a raw pointer, it clearly states ownership status of
the object and effectively prevents from possible memory leaks.
See also:
• JSF December 2005 [8]: AV Rule 112: Function return values should not obscure
resource ownership.
• C++ Core Guidelines [11]: F .27: Use a shared_ptr<T> to share ownership
• C++ Core Guidelines [11]: R.20: Use unique_ptr or shared_ptr to represent
ownership
A21A21 (AUTOSAR)A21 (AUTOSAR-original)
A21-8-1Required · Automated✓ compilable
문자 분류/변환 함수 인자는 unsigned char 로 표현 가능해야 한다Arguments to character-handling functions shall be representable as an unsigned char
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cctype>
static bool is_letter(char c) {
return std::isalpha(c); // char 가 음수(서명 char에서 0x80 이상)면 EOF 외 음수 → 미정의
}
int main() {
char c = static_cast<char>(0xE9); // 'é' 등 — 서명 char 에서 음수
std::cout << is_letter(c) << '\n'; // 미정의 동작(구현에 따라 크래시/오답)
}✅ 준수 예시Compliant example
#include <iostream>
#include <cctype>
static bool is_letter(char c) {
return std::isalpha(static_cast<unsigned char>(c)); // 유효 범위 보장
}
int main() {
char c = static_cast<char>(0xE9);
std::cout << is_letter(c) << '\n';
}⚠️ 근거: <cctype> 의 isalpha·toupper 등은 인자가 unsigned char 로 표현 가능한 값이거나 EOF 여야 한다고 규정한다. 영향: char 가 서명 타입인 구현에서 0x80 이상의 바이트(확장 ASCII·UTF-8 바이트)는 음수가 되어 EOF 가 아닌 음수로 전달되면 미정의 동작이 되며, 일부 구현은 내부 룩업 테이블을 음수 인덱스로 접근해 크래시한다. 대응: 이들 함수에 char 를 넘기기 전에 static_cast<unsigned char> 로 변환해 항상 유효한 범위의 값을 전달한다.Rationale: functions in <cctype> like isalpha and toupper require their argument to be a value representable as unsigned char or EOF. Impact: on implementations where char is signed, bytes at or above 0x80 (extended ASCII or UTF-8 bytes) become negative, and passing a negative value that is not EOF is undefined behaviour — some implementations index an internal lookup table with a negative index and crash. Fix: convert char with static_cast<unsigned char> before passing it to these functions so the value is always in the valid range.
A23A23 (AUTOSAR)A23 (AUTOSAR-original)
A23-0-1Required · Automated✓ compilable
무효화된(invalidated) 반복자를 사용하지 않는다An iterator that is invalidated shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1, 0, 2, 0, 3};
for (auto it = v.begin(); it != v.end(); ++it) {
if (*it == 0) v.erase(it); // erase 가 it 을 무효화 → 이후 ++it/역참조는 미정의
}
for (int x : v) std::cout << x << ' ';
std::cout << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1, 0, 2, 0, 3};
for (auto it = v.begin(); it != v.end(); ) {
if (*it == 0) it = v.erase(it); // erase 가 돌려준 유효한 다음 반복자로 갱신
else ++it;
}
for (int x : v) std::cout << x << ' ';
std::cout << '\n'; // 1 2 3
}⚠️ 근거: 컨테이너의 erase·insert 나 재할당을 유발하는 연산은 그 위치(또는 이후, 때로 전체)의 반복자·참조·포인터를 무효화하며, 무효화된 반복자를 증가·역참조·비교하는 것은 미정의 동작이다. 영향: 반복 중 erase 후 같은 it 을 계속 쓰면 해제된 위치를 가리켜 원소를 건너뛰거나, 쓰레기를 읽거나, 크래시하는 미묘한 버그가 된다. 대응: 변경 연산이 반환하는 유효한 반복자(it = v.erase(it))로 갱신하거나, 표준 알고리즘(std::remove_if + erase 관용구)을 사용한다.Rationale: a container erase, insert, or a reallocating operation invalidates iterators, references, and pointers at (or after, sometimes all of) that position, and incrementing, dereferencing, or comparing an invalidated iterator is undefined behaviour. Impact: continuing to use the same it after erase during iteration points at a freed position, skipping elements, reading garbage, or crashing — a subtle bug. Fix: update with the valid iterator returned by the modifying operation (it = v.erase(it)) or use standard algorithms (the std::remove_if + erase idiom).
A23-0-2Required · Automated✓ compilable📄 공식 예제Official example
Elements of a container shall only be accessed via valid references, iterators, and pointers.Elements of a container shall only be accessed via valid references, iterators, and pointers.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A23-0-2.cpp 309868 2018-03-02 10:47:23Z jan.babst $
#include <algorithm>
#include <cstdint>
#include <list>
#include <vector>
void f()
{
std::vector<int32_t> v{0, 1, 2, 3, 4, 5, 6, 7};
auto it = std::find(v.begin(), v.end(), 5); // *it is 5
// These calls may lead to a reallocation of the vector storage
// and thus may invalidate the iterator it.
v.push_back(8);
v.push_back(9);
*it = 42; // Non-compliant
}
void g()
{
std::list<int32_t> l{0, 1, 2, 3, 4, 5, 6, 7};
auto it = std::find(l.begin(), l.end(), 5); // *it is 5
l.remove(7);
l.push_back(9);
*it = 42; // Compliant - previous operations do not invalidate iterators
// l is now {0, 1, 2, 3, 4, 42, 6, 9 }
}⚠️ Some operations on standard library containers invalidate references, iterators, and
pointers to container elements which were previously stored.
The behavior of the standard library containers and their operations with respect to the
invalidation of references, iterators, and pointers is well documented, e.g. in [16].
See also:
• SEI CERT C++ Coding Standard [10]: CTR51-CPP: Use valid references,
pointers, and iterators to reference elements of a container.
• SEI CERT C++ Coding Standard [10]: STR52-CPP: Use valid references,
pointers, and iterators to reference elements of a basic_string.
• cppreference.com [16]: Containers library . Iterator invalidation.
6.25 Algorithms library
6.25.1 GeneralSome operations on standard library containers invalidate references, iterators, and
pointers to container elements which were previously stored.
The behavior of the standard library containers and their operations with respect to the
invalidation of references, iterators, and pointers is well documented, e.g. in [16].
See also:
• SEI CERT C++ Coding Standard [10]: CTR51-CPP: Use valid references,
pointers, and iterators to reference elements of a container.
• SEI CERT C++ Coding Standard [10]: STR52-CPP: Use valid references,
pointers, and iterators to reference elements of a basic_string.
• cppreference.com [16]: Containers library . Iterator invalidation.
6.25 Algorithms library
6.25.1 General
A25A25 (AUTOSAR)A25 (AUTOSAR-original)
A25-4-1Required · Automated✓ compilable
정렬/연관 컨테이너의 비교 술어는 엄격 약순서를 만족해야 한다Ordering predicates used with associative containers and sorting algorithms shall adhere to a strict weak ordering relation
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
#include <algorithm>
struct Item { int x; };
int main() {
std::vector<Item> v{{5},{2},{8},{2},{1}};
std::sort(v.begin(), v.end(),
[](const Item& a, const Item& b){ return a.x <= b.x; }); // <= 위반
for (auto& i : v) std::cout << i.x << ' ';
std::cout << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <algorithm>
struct Item { int x; };
int main() {
std::vector<Item> v{{5},{2},{8},{2},{1}};
std::sort(v.begin(), v.end(),
[](const Item& a, const Item& b){ return a.x < b.x; }); // 엄격 약순서
for (auto& i : v) std::cout << i.x << ' ';
std::cout << '\n';
}⚠️ 근거: std::sort 와 std::map·std::set 은 비교 술어가 엄격 약순서(strict weak ordering)를 만족한다고 가정하며, 그 핵심은 같은 값에 대해 comp(a, a) 가 false 여야 한다는 비반사성이다. 영향: a.x <= b.x 처럼 동치에 true 를 주는 술어는 두 동일 원소에서 a < b 와 b < a 가 동시에 참인 모순을 만들어, 정렬이 범위를 넘어 메모리를 침범하거나(미정의 동작) 연관 컨테이너의 트리 불변식이 깨진다. 대응: 동치에 false 를 돌려주는 < 형태의 술어를 사용하고, 복합 키는 모든 필드에 대해 일관된 약순서를 구성한다.Rationale: std::sort and std::map/std::set assume the comparison predicate satisfies a strict weak ordering, whose core is irreflexivity — comp(a, a) must be false for equal values. Impact: a predicate like a.x <= b.x that returns true for equal values makes both a < b and b < a true for two identical elements, so sorting can run past the range and corrupt memory (undefined behaviour) or break the tree invariant of an associative container. Fix: use a < form predicate that returns false for equal values, and compose a consistent weak ordering over all fields for composite keys.
A25-1-1Required · Automated✓ compilable📄 공식 예제Official example
Non-static data members or captured values of predicate function objects that are state related to this object’s identity shall not be copied.Non-static data members or captured values of predicate function objects that are state related to this object’s identity shall not be copied.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
#include <cstddef>
//% $Id: A25-1-1.cpp 309784 2018-03-01 20:18:29Z michal.szczepankiewicz $
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
class ThirdElemPred : public std::unary_function<int, bool>
{
public:
ThirdElemPred() : timesCalled(0) {}
bool operator()(const int &) { return (++timesCalled) == 3; }
//non-compliant, non-const call operator that
//modifies the predicate object field
private:
size_t timesCalled;
};
class ThirdElemPred2 : public std::unary_function<int, bool>
{
public:
ThirdElemPred2() : timesCalled(0) {}
bool operator()(const int &) const { return (++timesCalled) == 3; }
//non-compliant, const call operator that
//modifies the mutable predicate object field
private:
mutable size_t timesCalled;
};
class ValueFivePred: public std::unary_function<int, bool>
{
public:
bool operator()(const int& v) const { return v == 5; }
//compliant, const call operator that does not
//modify the predicate object state
};
void F1(std::vector<int> v)
{
//non-compliant, predicate object state modified
int timesCalled = 0;
//display values that are NOT to be removed
std::copy(v.begin(), std::remove_if(v.begin(), v.end(), [timesCalled](const
int &) mutable { return (++timesCalled) == 3; }), std::ostream_iterator<std::
vector<int>::value_type>(std::cout, " ") );
std::cout << std::endl;
}
void F2(std::vector<int> v)
{
//non-compliant, predicate object state modified
std::copy(v.begin(), std::remove_if(v.begin(), v.end(), ThirdElemPred()), std
::ostream_iterator<std::vector<int>::value_type>(std::cout, " ") );
std::cout << std::endl;
}
void F22(std::vector<int> v)
{
//non-compliant, predicate object state modified
std::copy(v.begin(), std::remove_if(v.begin(), v.end(), ThirdElemPred2()),
std::ostream_iterator<std::vector<int>::value_type>(std::cout, " ") );
std::cout << std::endl;
}
void F3(std::vector<int> v)
{
//compliant, predicate object that has its state
//modified is passed as a std::reference_wrapper
ThirdElemPred pred;
std::copy(v.begin(), std::remove_if(v.begin(), v.end(), std::ref(pred)), std
::ostream_iterator<std::vector<int>::value_type>(std::cout, " ") );
std::cout << std::endl;
}
int main(void)
{
std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
F1(v);
F2(v);
F22(v);
F3(v);
//output for g++-5.5, correct result only for F3
//F1 0 1 3 4 6 7 8 9
//F2 0 1 3 4 6 7 8 9
//F22 0 1 3 4 6 7 8 9
//F3 0 1 3 4 5 6 7 8 9
return 0;
}⚠️ Generic algorithms available in the C++ Standard Library accept a predicate
function object. The ISO/IEC 14882:2014 C++ Language Standard states that it is
implementation-defined whether predicate function objects can be copied by the STL
algorithms.
T o prevent from unexpected results while using predicate function objects, any such
object shall either:
• be passed to an STL algorithm wrapped as a std::reference_wrapper.
• implement a function call operator that is const and does not modify any data
members or captured values that have a mutable specifier.
See also:
• SEI CERT C++ Coding Standard [10]: CTR58-CPP: Predicate function objects
should not be mutable
• cppreference.com [16]: C++ concepts: Predicate
6.25.4 Sorting and related operationsGeneric algorithms available in the C++ Standard Library accept a predicate
function object. The ISO/IEC 14882:2014 C++ Language Standard states that it is
implementation-defined whether predicate function objects can be copied by the STL
algorithms.
T o prevent from unexpected results while using predicate function objects, any such
object shall either:
• be passed to an STL algorithm wrapped as a std::reference_wrapper.
• implement a function call operator that is const and does not modify any data
members or captured values that have a mutable specifier.
See also:
• SEI CERT C++ Coding Standard [10]: CTR58-CPP: Predicate function objects
should not be mutable
• cppreference.com [16]: C++ concepts: Predicate
6.25.4 Sorting and related operations
A26A26 (AUTOSAR)A26 (AUTOSAR-original)
A26-5-1Required · Automated✓ compilable
의사난수는 std::rand 가 아닌 <random> 엔진으로 생성한다Pseudorandom numbers shall not be generated using std::rand()
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstdlib>
int main() {
int r = std::rand() % 100; // % 로 인한 분포 편향 + 낮은 품질
std::cout << r << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(0, 99); // 균등 분포 보장
std::cout << dist(gen) << '\n';
}⚠️ 근거: std::rand 는 구현마다 품질·주기가 천차만별이고, rand() % N 방식은 RAND_MAX 가 N 의 배수가 아닐 때 작은 값에 더 높은 확률을 주는 모듈로 편향(modulo bias)을 만든다. 영향: 분포가 균등하지 않으면 시뮬레이션·샘플링 결과가 왜곡되고, 보안 문맥에서는 낮은 엔트로피와 예측 가능성 때문에 토큰·논스가 추측 가능해진다. 대응: <random> 의 엔진(mt19937 등)과 분포(uniform_int_distribution)를 조합해 균등성을 보장하고, 보안 용도는 암호학적 CSPRNG 를 사용한다.Rationale: std::rand varies widely in quality and period across implementations, and the rand() % N approach creates modulo bias — giving small values higher probability when RAND_MAX is not a multiple of N. Impact: a non-uniform distribution skews simulation and sampling results, and in a security context low entropy and predictability make tokens and nonces guessable. Fix: combine a <random> engine (such as mt19937) with a distribution (uniform_int_distribution) to guarantee uniformity, and use a cryptographic CSPRNG for security purposes.
A26-5-2Required · Automated✓ compilable📄 공식 예제Official example
Random number engines shall not be default-initialized.Random number engines shall not be default-initialized.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A26-5-2.cpp 311495 2018-03-13 13:02:54Z michal.szczepankiewicz $
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::default_random_engine eng{rd()}; //compliant
std::uniform_int_distribution<int> ud{0, 100};
int r1 = ud(eng);
std::cout << "Random value using std::random_device: " << r1 << std::endl;
std::default_random_engine eng2{}; //non-compliant
std::uniform_int_distribution<int> ud2{0, 100};
int r2 = ud2(eng);
std::cout << "Random value using std::random_device: " << r2 << std::endl;
return 0;
}⚠️ Using a pseudo-random number generator gives different results that depend on a
used seed value. Initializing random number engines by default initializes pseudo-
random generator with a default_seed constant value. However, this can be not
obvious for a developer and can lead to unexpected program behaviour (generating
the same random sequences among different program executions).
Exception:
For consistent testing purposes it can be convenient to seed the random number
engine with a fixed value to get a deterministic sequence, but never within production
code where real randomness is required, e.g. for security reasons.
See also:
• SEI CERT C++ Coding Standard [10]: MSC51-CPP: Ensure your random number
generator is properly seeded.
6.27 Input/output library - partial
6.27.1 GeneralUsing a pseudo-random number generator gives different results that depend on a
used seed value. Initializing random number engines by default initializes pseudo-
random generator with a default_seed constant value. However, this can be not
obvious for a developer and can lead to unexpected program behaviour (generating
the same random sequences among different program executions).
Exception:
For consistent testing purposes it can be convenient to seed the random number
engine with a fixed value to get a deterministic sequence, but never within production
code where real randomness is required, e.g. for security reasons.
See also:
• SEI CERT C++ Coding Standard [10]: MSC51-CPP: Ensure your random number
generator is properly seeded.
6.27 Input/output library - partial
6.27.1 General
A27A27 (AUTOSAR)A27 (AUTOSAR-original)
A27-0-1Required · Non-automated✓ compilable
독립 컴포넌트(네트워크·파일 등)로부터의 입력은 검증한다Inputs from independent components shall be validated
❌ 위반 예시Non-compliant example
#include <iostream>
#include <vector>
#include <cstddef>
static std::size_t read_size_from_network() { return 1000000000; } // 외부가 준 거대 값
int main() {
std::size_t n = read_size_from_network();
std::vector<int> buf;
buf.resize(n); // 외부 크기를 검증 없이 그대로 사용 — 자원 고갈/예외
std::cout << buf.size() << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <vector>
#include <cstddef>
static std::size_t read_size_from_network() { return 1000000000; }
int main() {
constexpr std::size_t kMaxBuf = 4096;
std::size_t n = read_size_from_network();
if (n > kMaxBuf) { std::cout << "rejected oversized input\n"; return 1; } // 경계 검증
std::vector<int> buf(n);
std::cout << buf.size() << '\n';
}⚠️ 근거: 네트워크·파일·IPC·사용자 입력 등 신뢰할 수 없는 출처의 값은 공격자나 손상된 컴포넌트가 임의로 조작할 수 있으므로, 사용 전에 유효 범위·형식을 검증해야 한다. 영향: 외부가 준 크기를 검증 없이 할당·인덱스로 쓰면 거대한 값으로 메모리를 고갈시키는 서비스 거부나, 음수·과대 값으로 경계를 넘는 접근이 발생한다. 대응: 신뢰 경계에서 입력의 범위·길이·형식을 명시적으로 검증하고, 한도를 벗어나면 안전하게 거부한다.Rationale: values from untrusted sources such as network, file, IPC, or user input can be arbitrarily manipulated by an attacker or a compromised component, so they must be validated for valid range and format before use. Impact: using an externally supplied size for allocation or indexing without validation enables denial of service by exhausting memory with a huge value, or out-of-bounds access from a negative or oversized value. Fix: explicitly validate the range, length, and format of input at the trust boundary and safely reject anything outside the limits.
A27-0-4Required · Automated✓ compilable
C 스타일 문자열을 사용하지 않는다C-style strings shall not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#include <cstring>
int main() {
const char* input = "user-provided";
char name[8]; // 고정 버퍼
std::strcpy(name, input); // 경계 미검사 — input 이 8바이트 넘으면 오버플로우
std::cout << name << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <string>
int main() {
std::string input = "user-provided";
std::string name = input; // 길이에 맞춰 동적 관리 — 오버플로우 불가
std::cout << name << '\n';
}⚠️ 근거: C 스타일 문자열(char 배열 + 널 종료)은 길이를 별도로 추적하지 않아, 복사·연결 시 대상 버퍼 크기를 사람이 직접 맞춰야 하고 널 종료를 깜빡하면 읽기가 버퍼를 넘어간다. 영향: strcpy·strcat 같은 경계 없는 연산은 입력이 버퍼보다 길면 인접 메모리를 덮어쓰는 버퍼 오버플로우를 일으켜, 크래시와 코드 실행 공격의 통로가 된다. 대응: 문자열은 길이를 스스로 관리하고 경계를 넘지 않는 std::string·std::string_view 로 다룬다.Rationale: a C-style string (char array plus null terminator) does not track its length separately, so on copy or concatenation a human must match the destination buffer size, and forgetting the null terminator makes reads run past the buffer. Impact: unbounded operations like strcpy and strcat overwrite adjacent memory when input exceeds the buffer — a buffer overflow that opens a path to crashes and code-execution attacks. Fix: handle strings with std::string and std::string_view, which manage length themselves and do not run past bounds.
A27-0-2Advisory · Automated✓ compilable📄 공식 예제Official example
A C-style string shall guarantee sufficient space for data and the null terminator.A C-style string shall guarantee sufficient space for data and the null terminator.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A27-0-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <iostream>
#include <string>
void F1() noexcept
{
char buffer[10];
std::cin >> buffer; // Non-compliant - this could lead to a buffer overflow
}
void F2() noexcept
{
std::string string1;
std::string string2;
std::cin >> string1 >> string2; // Compliant - no buffer overflows
}
void F3(std::istream& in) noexcept
{
char buffer[32];
try
{
in.read(buffer, sizeof(buffer));
}
catch (std::ios_base::failure&)
{
// Handle an error
}
std::string str(buffer); // Non-compliant - if 'buffer' is not null
// terminated, then constructing std::string leads
// to undefined behavior.
}
void F4(std::istream& in) noexcept
{
char buffer[32];
try
{
in.read(buffer, sizeof(buffer));
}
catch (std::ios_base::failure&)
{
// Handle an error
}
std::string str(buffer, in.gcount()); // Compliant
}⚠️ T o prevent buffer overflows, it needs to be ensured that the destination is of sufficient
size to hold the character data to be copied and the null terminator.
Note that C-style string requires additional space for null character to indicate the end
of the string, while the C++ std::basic_string does that implicitly .
Note: This rule is deliberately redundant, in case the rule A27-0-4 is disabled in a
project.
See also:
• SEI CERT C++ [10]: STR50-CPP . Guarantee that storage for strings has
sufficient space for character data and the null terminator.T o prevent buffer overflows, it needs to be ensured that the destination is of sufficient
size to hold the character data to be copied and the null terminator.
Note that C-style string requires additional space for null character to indicate the end
of the string, while the C++ std::basic_string does that implicitly .
Note: This rule is deliberately redundant, in case the rule A27-0-4 is disabled in a
project.
See also:
• SEI CERT C++ [10]: STR50-CPP . Guarantee that storage for strings has
sufficient space for character data and the null terminator.
A27-0-3Required · Automated✓ compilable📄 공식 예제Official example
Alternate input and output operations on a file stream shall not be used without an intervening flush or positioning call.Alternate input and output operations on a file stream shall not be used without an intervening flush or positioning call.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// $Id: A27-0-3.cpp 311495 2018-03-13 13:02:54Z michal.szczepankiewicz $
#include <fstream>
#include <string>
int main(void)
{
std::fstream f("testfile");
f << "Output";
std::string str1;
f >> str1; // non-compliant
f << "More output";
std::string str2;
f.seekg(0, std::ios::beg);
f >> str2; //compliant
return 0;
}⚠️ reformulated.
Example reworked.
12-1-3 (Required) All constructors that
are callable with a single argument
of fundamental type shall be declared
explicit.
2 - Small differences A12-1-4 Example reworked.
12-8-1 (Required) A copy constructor
shall only initialize its base classes and
the non-static members of the class of
which it is a member.
3 - Significant differences A12-8-1 Rule reformulated
to cover
move constructors,
too. Rationale
reformulated.
Example reworked.
12-
8-2 (Required) The copy assignment
operator shall be declared protected or
private in an abstract class.
3 - Significant differences A12-8-6 Rule reformulated
to cover move
assignment
operators and all
base
classes. Rationale
reformulated.
Example reworked.
12-
8-2 (Required) The copy assignment
operator shall be declared protected or
private in an abstract class.
3 - Significant differences A12-8-1 Rule reformulated
to cover
move constructors,
too. Rationale
reformulated.
Example reworked.
14-5-1 (Required) A non-
member generic function shall only be
declared in a namespace that is not an
associated namespace.
3 - Significant differences A14-5-3 Changed the
scope of the rule
from all generic
functions to
operators only , as
most problematic
case. Changed
severity to
Advisory .
14-5-2 (Required) A copy constructor
shall be declared when there is a
template constructor with a single
parameter that is a generic parameter.
3 - Significant differences A14-5-1 Avoids
the ambiguity by
requiring the
template
parameter to
be constrained to
never
match a copy/move
constructor.
14-5-3 (Required) A copy assignment
operator shall be declared when there
is a template assignment operator
with a parameter that is a generic
parameter.
1 - Identical M14-5-3 -
14-6-1 (Required) In a class template
with a dependent base, any name that
may be found in that dependent base
shall be referred to using a qualified-id
or this->.
1 - Identical M14-6-1 -
14-6-2 (Required) The function chosen
by overload resolution shall resolve to
a function declared previously in the
translation unit.
4 - Rejected - Usage of the
ADL functionality is
allowed. It is also
used in
STL for overloaded
operators lookup in
e.g. out streams,
STL containers.
14-7-1 (Required) All class templates,
function templates, class template
member functions and class template
static members shall be instantiated at
least once.
4 - Rejected - It is allowed to not
use all of the public
methods of a class.
14-7-2 (Required)
For any given template specialization,
an explicit instantiation of the template
with the template-arguments used in
the specialization shall not render the
program ill-formed.
3 - Significant differences A14-7-1 Rule reformulated
to explicitly state
what is required.
Example reworked.
14-7-3 (Required) All partial and
explicit specializations for a template
shall be declared in the same file as the
declaration of their primary template.
3 - Significant differences A14-7-2 Allowed to declare
in a header file
that declares user-
defined
type, for which the
specialization is
declared.
14-8-1 (Required) Overloaded function
templates shall not be explicitly
specialized.
3 - Significant differences A14-8-2 Function templates
specialization is
forbidden.
14-8-2 (Advisory) The viable function
set for a function call should either
contain no function specializations, or
only contain function specializations.
3 - Small differences A14-8-2 Function templates
specialization is
forbidden.
15-0-1 (Document) Exceptions shall
only be used for error handling.
3 - Significant differences A15-0-1 Rule reformulated,
example
significantly
extended.
15-0-2 (Advisory) An exception object
should not have pointer type.
3 - Significant differences A15-1-2 Obligation
level changed, rule
reformulated.
15-0-3 (Required) Control shall not be
transferred into a try or catch block
using a goto or a switch statement.
1 - Identical M15-0-3 -
15-1-1 (Required) The assignment-
expression of a throw statement shall
not itself cause an exception.
1 - Identical M15-1-1 -
15-1-2 (Required) NULL shall not be
thrown explicitly .
1 - Identical M15-1-2 -
15-1-3 (Required)
An empty throw (throw;) shall only be
used in the compound-statement of a
catch handler.
1 - Identical M15-1-3 -
15-3-1 (Required) Exceptions shall be
raised only after start-up and before
termination of the program.
1 - Identical M15-3-1 -
15-3-2 (Advisory) There should be at
least one exception handler to catch all
otherwise unhandled exceptions.
2 - Small differences A15-3-3 Obligation level
changed. Rule
extended to cover
multi-threading.
15-3-3 (Required) Handlers of
a function-try-block implementation of
a class constructor or destructor shall
not reference non-static members from
this class or its bases.
1 - Identical M15-3-3 -
15-3-4 (Required) Each exception
explicitly thrown in the code shall have
a handler of a compatible type in all call
paths that could lead to that point.
1 - Identical M15-3-4 -
15-
3-5 (Required) A class type exception
shall always be caught by reference.
2 - Small differences A15-3-5 Possibility to catch
by const reference
added
15-3-6 (Required) Where multiple
handlers are provided in a single try-
catch statement or function-try-block
for a derived class and some or all of
its bases, the handlers shall be ordered
most-derived to base class.
1 - Identical M15-3-6 -
15-3-7 (Required) Where multiple
handlers are provided in a single try-
catch statement or function-try-block,
any ellipsis (catch-all) handler shall
occur last.
1 - Identical M15-3-7 -
15-4-1 (Required) If a
function is declared with an exception-
specification, then all declarations of
the same function (in other translation
units) shall be declared with the same
set of type-ids.
3 - Significant differences A15-4-3 Dynamic exception
specification was
prohibited. Rule
was reformulated
in terms of the
noexcept
specification.
15-5-1 (Required) A class destructor
shall not exit with an exception.
3 - Significant differences A15-5-1 Rule significantly
extended
with other special
functions and
operators.
15-5-2 (Required) Where a function’s
declaration includes an exception-
specification, the function shall only be
capable of throwing exceptions of the
indicated type(s).
3 - Significant differences A15-4-2 Dynamic exception
specification was
prohibited. Rule
was reformulated
in terms of the
noexcept
specification.
15-5-3 (Required) The std::terminate()
function shall not be called implicitly .
2 - Small differences A15-5-3 Rationale and
example extended.
16-0-1 (Required) #include directives
in a file shall only be preceded by other
preprocessor directives or comments.
1 - Identical M16-0-1 -
16-0-2 (Required) Macros shall only
be #define’d or #undef’d in the global
namespace.
1 - Identical M16-0-2 -
16-0-3 (Required) #undef shall not be
used.
4 - Rejected - The
rule replaced with
global rule: A16-0-
1.
16-0-4 (Required) Function-like
macros shall not be defined.
4 - Rejected - The
rule replaced with
global rule: A16-0-
1.
16-0-5 (Required) Arguments to a
function-like macro shall not contain
tokens that look like preprocessing
directives.
1 - Identical M16-0-5 -
16-0-6 (Required) In the definition of
a function-like macro, each instance
of a parameter shall be enclosed in
parentheses, unless it is used as the
operand of # or ##.
1 - Identical M16-0-6 -
16-0-7 (Required) Undefined macro
identifiers shall not be used in #if or
#elif preprocessor directives, except as
operands to the defined operator.
1 - Identical M16-0-7 -
16-0-8 (Required) If the # token
appears as the first token on a line,
then it shall be immediately followed by
a pre-processing token.
1 - Identical M16-0-8 -
16-1-
1 (Required) The defined preprocessor
operator shall only be used in one of
the two standard forms.
1 - Identical M16-1-1 -
16-1-2 (Required) All #else, #elif and
#endif pre-processor directives shall
reside in the same file as the #if
or #ifdef directive to which they are
related.
1 - Identical M16-1-2 -
16-2-1 (Required) The pre-processor
shall only be used for file inclusion and
include guards.
4 - Rejected - The
rule replaced with
global rule: A16-0-
1.
16-2-2 (Required) C++ macros shall
only be used for include guards, type
qualifiers, or storage class specifiers.
4 - Rejected - The
rule replaced with
global rule: A16-0-
1.
16-2-3 (Required) Include guards shall
be provided
1 - Identical M16-2-3 -
16-2-4 (Required) The ’, ”, /* or //
characters shall not occur in a header
file name.
2 - Small differences A16-2-1 Merged with
MISRA Rule 16-2-
5.
16-2-5 (Advisory) The
character \should not occur in a header
file name.
2 - Small differences A16-2-1 Obligation
level changed to
“Required”.
Merged with
MISRA Rule 16-2-
4.
16-2-6 (Required) The #include
directive shall be followed by either a
<filename> or “filename” sequence.
4 - Rejected - These are the only
forms allowed by
the C++ Language
Standard; No need
for a new rule.
16-3-1 (Required) There shall be at
most one occurrence of the # or ##
operators in a single macro definition.
1 - Identical M16-3-1 -
16-3-2 (Advisory) The # and ##
operators should not be used.
1 - Identical M16-3-2 -
16-6-
1 (Required) All uses of the #pragma
directive shall be documented.
4 - Rejected - The #pragma
directive shall not
be used, see: A16-
7-1.
17-0-1 (Required) Reserved
identifiers, macros and functions in the
standard library shall not be defined,
redefined or undefined.
2 - Small differences A17-0-1 Example extended.
17-0-2 (Required) The names of
standard library macros and objects
shall not be reused.
1 - Identical M17-0-2 -
17-0-3 (Required) The names of
standard library functions shall not be
overridden.
1 - Identical M17-0-3 -
17-0-4 (Required) All library code shall
conform to MISRA C++.
4 - Rejected - The rule
replaced with A17-
0-2 saying that all
code shall conform
to
AUTOSAR C++14
Coding Guidelines.
17-0-5 (Required) The setjmp macro
and the longjmp function shall not be
used.
1 - Identical M17-0-5 -
18-0-1 (Required) The C library shall
not be used.
2 - Small differences A18-0-1 Rule reformulated.
18-0-2 (Required) The library functions
atof, atoi and atol from library <cstdlib>
shall not be used.
2 - Small differences A18-0-2
18-0-3 (Required) The library functions
abort, exit, getenv and system from
library <cstdlib> shall not be used.
1 - Identical M18-0-3 -
18-0-4 (Required) The time handling
functions of library <ctime> shall not be
used.
1 - Identical M18-0-4 -
18-0-5 (Required) The unbounded
functions of library <cstring> shall not
be used.
1 - Identical M18-0-5 -
18-2-1 (Required) The macro offsetof
shall not be used.
1 - Identical M18-2-1 -
18-4-1 (Required) Dynamic heap
memory allocation shall not be used.
4 - Rejected - Dynamic heap
memory allocation
usage is allowed
conditionally , see:
A18-5-1, A18-5-2,
A18-5-3.
18-7-1 (Required) The signal handling
facilities of <csignal> shall not be used.
1 - Identical M18-7-1 -
19-3-1 (Required) The error indicator
errno shall not be used.
1 - Identical M19-3-1 -
27-
0-1 (Required) The stream input/output
library <cstdio> shall not be used.
1 - Identical M27-0-1 -
Table B.1: MISRA C++
B.2 Traceability to HIC++ v4.0
The following table demonstrates the traceability to High Integrity C++ Coding Standard
Version 4.0 [9]. This is not considered as a reproduction, but a mean to compare the
two standards.
This document complies with the conditions of use of HIC++ v4.0, as any rule in this
document that is based on HIC++ v4.0 refers to the related HIC++ v4.0 rule.
HIC++ Rule: Relation type: Related
rule:
Comment:
1.1.1 Ensure that code complies with
the 2011 ISO C++ Language Standard.
2 - Small differences A1-1-1 Specified that the
code shall conform
to ISO/IEC
14882:2014
1.2.1 Ensure that all statements are
reachable.
2 - Small differences M0-1-1
1.2.2 Ensure that no expression or
sub-expression is redundant.
2 - Small differences M0-1-9
1.3.1 Do not use the increment
operator (++) on a variable of type bool
2 - Small differences M4-5-1
1.3.2 Do not use the register keyword. 2 - Small differences A7-1-4
1.3.3 Do not use the C Standard
Library .h headers
2 - Small differences A18-0-1
1.3.4 Do not use deprecated STL
library features
2 - Small differences A1-1-1, A18-
1-3, A18-9-1
1.3.5 Do not use throw exception
specifications.
2 - Small differences A15-4-1
2.1.1 Do not use tab characters in
source files.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
2.2.1 Do not use digraphs or trigraphs. 2 - Small differences A2-5-1, A2-
5-2
2.3.1 Do not use the C comment
delimiters /* ... */.
2 - Small differences M2-7-1
2.3.2 Do not comment out code. 2 - Small differences A2-7-2
2.4.1 Ensure that each identifier is
distinct from any other visible identifier.
2 - Small differences M2-10-1
2.5.1 Do not concatenate strings with
different encoding prefixes.
2 - Small differences A2-13-2
2.5.2 Do not use octal constants (other
than zero).
2 - Small differences M2-13-2
2.5.3 Use nullptr for the null pointer
constant.
2 - Small differences A4-10-1
3.1.1 Do not hide declarations. 2 - Small differences A2-10-1, A2-
10-6
3.2.1 Do not declare functions at block
scope.
2 - Small differences M3-1-2
3.3.1 Do not use variables with static
storage duration.
3 - Significant differences A3-3-2 Limited to
constant-initialized
objects only .
3.4.1 Do not return a reference or
a pointer to an automatic variable
defined within the function.
2 - Small differences M7-5-1
3.4.2 Do not assign the address of
a variable to a pointer with a greater
lifetime.
2 - Small differences M7-5-2
3.4.3 Use RAII for resources. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
rules for coding
patterns. Note that
usage of RAII is
recommended,
see: A15-1-4.
3.5.1 Do not make any assumptions
about the internal representation of a
value or object.
2 - Small differences A3-9-1,
M3-9-3, M5-
0-15, M5-0-
21, A9-5-1,
M18-2-1
4.1.1 Ensure that a function argument
does not undergo an array-to-pointer
conversion.
2 - Small differences M5-2-12
4.2.1 Ensure that the U suffix is applied
to a literal used in a context requiring
an unsigned integral expression.
2 - Small differences M2-13-2
4.2.2 Ensure that data loss does
not demonstrably occur in an integral
expression.
2 - Small differences A4-7-1, M5-
0-4, M5-0-6,
M5-0-9
4.3.1 Do not convert an expression of
wider floating point type to a narrower
floating point type.
2 - Small differences A4-7-1, M5-
0-6
4.4.1 Do not convert floating values to
integral types except through use of
standard library functions.
4 - Rejected Rules that
are related: M5-0-
3, M5-0-5, M5-0-6,
M5-0-7,
5.1.1 Use symbolic names instead of
literal values in code.
2 - Small differences A5-1-1
5.1.2 Do not rely on the sequence of
evaluation within an expression.
2 - Small differences A5-0-1
5.1.3 Use parentheses in expressions
to specify the intent of the expression.
2 - Small differences A5-
0-1, A5-2-6,
M5-2-10,
5.1.4 Do not capture variables implicitly
in a lambda.
2 - Small differences A5-1-2
5.1.5 Include a (possibly
empty) parameter list in every lambda
expression.
2 - Small differences A5-1-3
5.1.6 Do not code side effects into
the right-hand operands of: &&, ||,
sizeof, typeid or a function passed to
condition_variable::wait.
3 - Significant differences A5-3-1, M5-
3-4, M5-14-1
The condi-
tion_variable::wait
is not yet covered,
this will be ad-
dressed in future
when C++ libraries
are analyzed.
5.2.1 Ensure that pointer or array
access is demonstrably within bounds
of a valid object.
2 - Small differences A5-2-5
5.2.2 Ensure that functions do not call
themselves, either directly or indirectly .
2 - Small differences A7-5-2
5.3.1 Do not apply unary minus to
operands of unsigned type.
2 - Small differences M5-3-2
5.3.2 Allocate memory using new and
release it using delete.
2 - Small differences A18-5-1 Note that operators
new and
delete shall not be
used explicitly , see:
A18-5-2.
5.3.3 Ensure that the form of delete
matches the form of new used to
allocate the memory .
2 - Small differences A18-5-3 Note that operators
new and
delete shall not be
used explicitly , see:
A18-5-2.
5.4.1 Only use casting forms:
static_cast (excl. void*), dynamic_cast
or explicit constructor call.
2 - Small differences A5-2-1, A5-
2-2, A5-2-3,
A5-2-4
5.4.2 Do not cast an expression to an
enumeration type.
4 - Rejected It is allowed to cast
an expression to an
enumeration type,
but an expression
shall have a value
that corresponds to
an enumerator
of the enumeration,
see: A7-2-1.
5.4.3 Do not convert from a base class
to a derived class.
3 - Small differences M5-2-2, M5-
2-3, A5-2-1
Note that the
dynamic_cast is
unsuitable for use
with real-time
systems.
5.5.1 Ensure that the right hand
operand of the division or remainder
operators is demonstrably non-zero.
2 - Small differences A5-6-1
5.6.1 Do not use bitwise operators with
signed operands.
2 - Small differences M5-0-21
5.7.1 Do not write code that expects
floating point calculations to yield exact
results.
2 - Small differences M6-2-2
5.7.2 Ensure that a pointer to member
that is a virtual function is only
compared (==) with nullptr.
2 - Small differences A5-10-1
5.8.1 Do not use the conditional
operator (?:) as a sub-expression.
2 - Small differences A5-16-1
6.1.1 Enclose the body of a selection or
an iteration statement in a compound
statement.
2 - Small differences M6-3-1, M6-
4-1
6.1.2 Explicitly cover all paths through
multi-way selection statements.
2 - Small differences M6-4-2
6.1.3 Ensure that a non-empty case
statement block does not fall through
to the next label.
2 - Small differences M6-4-5
6.1.4 Ensure that a switch statement
has at least two case labels, distinct
from the default label.
2 - Small differences A6-4-1
6.2.1 Implement a loop that only uses
element values as a range-based loop.
2 - Small differences A6-5-1
6.2.2 Ensure that a loop has a
single loop counter, an optional control
variable, and is not degenerate.
2 - Small differences A6-5-2
6.2.3 Do not alter a control or counter
variable more than once in a loop.
3 - Significant differences M6-5-3 It is prohibited to
alter a control
or counter variable
within condition or
statement of a
loop.
6.2.4 Only modify a for loop counter in
the for expression.
2 - Small differences M6-5-3
6.3.1 Ensure that the label(s) for a
jump statement or a switch condition
appear later, in the same or an
enclosing block.
2 - Small differences M6-6-1
6.3.2 Ensure that execution of a
function with a non-void return type
ends in a return statement with a value.
2 - Small differences A8-4-2
6.4.1 Postpone variable definitions as
long as possible.
2 - Small differences M3-4-1
7.1.1 Declare each identifier on a
separate line in a separate declaration.
2 - Small differences A7-1-7
7.1.2 Use const whenever possible. 2 - Small differences A7-1-1, A7-
1-2
7.1.3 Do not place type
specifiers before non-type specifiers in
a declaration.
2 - Small differences A7-1-8
7.1.4 Place CV-qualifiers on the right
hand side of the type they apply to.
3 - Significant differences A7-1-3 Placement of cv-
qualifiers
is only restricted for
typedefs.
7.1.5 Do not inline large functions. 4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
7.1.6 Use class types or typedefs to
abstract scalar quantities and standard
integer types.
3 - Significant differences A3-9-1 AUTOSAR C++
Coding Guidelines
forces to use
typedefs for built-in
numerical types.
7.1.7 Use a trailing return type in
preference to type disambiguation
using typename.
2 - Small differences A8-2-1
7.1.8 Use auto id = expr when
declaring a variable to have the same
type as its initializer function call.
3 - Significant differences A7-1-5 The
rule is formulated
differently .
7.1.9 Do not explicitly specify the return
type of a lambda.
4 - Rejected T o avoid implicit
type conversion
return type of
lambda expression
needs to be
specified explicitly ,
see: A5-1-6.
7.1.10 Use static_assert for assertions
involving compile time constants.
3 - Significant differences A16-6-1 It is recommended
to use the
static_assert
instead of #error
directive.
7.2.1 Use an explicit enumeration base
and ensure that it is large enough to
store all enumerators.
2 - Small differences A7-2-2
7.2.2 Initialize none, the first only or all
enumerators in an enumeration.
2 - Small differences A7-2-4
7.3.1 Do not use using directives. 2 - Small differences M7-3-4
7.4.1 Ensure
that any objects, functions or types to
be used from a single translation unit
are defined in an unnamed namespace
in the main source file.
7.4.2 Ensure that an inline function, a
function template, or a type used from
multiple translation units is defined in a
single header file.
2 - Small differences A3-1-1, M3-
2-2
7.4.3 Ensure that an object or a
function used from multiple translation
units is declared in a single header file.
2 - Small differences A3-1-1, M3-
2-4
7.5.1 Do not use the asm declaration. 2 - Small differences A7-4-1
8.1.1 Do not use multiple levels of
pointer indirection.
3 - Significant differences A5-0-3 At most two levels
of
pointer indirection
are allowed.
8.2.1 Make parameter names absent
or identical in all declarations.
2 - Small differences M3-9-1
8.2.2 Do not declare functions with an
excessive number of parameters.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
8.2.3 Pass small objects with a trivial
copy constructor by value.
4 - Rejected The rule is vague,
“small” has no
technical meaning.
8.2.4 Do not pass std::unique_ptr by
const reference.
3 - Significant differences A8-4-11, A8-
4-12
A8-4-12 cov-
ers how to pass a
std::unique_ptr,
A8-4-11 cov-
ers when not
to pass by
std::unique_ptr.
8.3.1 Do not write functions
with an excessive McCabe Cyclomatic
Complexity .
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
8.3.2 Do not write functions with a high
static program path count.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
8.3.3 Do not use default arguments. 4 - Rejected Using
default arguments
is allowed with
some restrictions,
see e.g. M8-3-1.
8.3.4 Define =delete functions with
parameters of type rvalue reference to
const.
2 - Small differences A13-3-1,
A18-9-3
8.4.1 Do not access an invalid object or
an object with indeterminate value.
2 - Small differences A8-5-0, A12-
8-3
8.4.2 Ensure that a braced aggregate
initializer matches the layout of the
aggregate object.
2 - Small differences M8-5-2
9.1.1 Declare
static any member function that does
not require this. Alternatively , declare
const any member function that does
not modify the externally visible state
of the object.
2 - Small differences M9-3-3
9.1.2 Make default arguments the
same or absent when overriding a
virtual function.
2 - Small differences M8-3-1
9.1.3 Do not return non-const handles
to class data from const member
functions.
2 - Small differences M9-3-1, A9-
3-1
9.1.4 Do not write member functions
which return non-const handles to
data less accessible than the member
function.
3 - Significant differences A9-3-1 It
is allowed to return
non-const handles
to static data.
9.1.5 Do not introduce virtual functions
in a final class.
2 - Small differences A10-3-3
9.2.1 Declare bit-fields
with an explicitly unsigned integral or
enumeration type.
3 - Significant differences A9-6-1 Any
type with a defined
size is allowed to
be used for a bit-
field.
10.1.1 Ensure that access to base
class subobjects does not require
explicit disambiguation.
3 - Significant differences A10-1-1 Inheritance
from more than one
base class is
prohibited.
10.2.1 Use
the override special identifier when
overriding a virtual function.
2 - Small differences A10-3-2
10.3.1 Ensure that a derived class has
at most one base class which is not an
interface class.
2 - Small differences A10-1-1 Note that
the definition of an
interface changed,
see: Interface-
Class.
11.1.1 Declare all data members
private.
2 - Small differences M11-0-1
11.2.1 Do not use friend declarations. 2 - Small differences A11-3-1
12.1.1 Do not declare implicit user
defined conversions.
3 - Significant differences A12-1-4,
A13-5-2
12.2.1 Declare virtual, private or
protected the destructor of a type used
as a base class.
3 - Significant differences A12-4-1 Destructor of
a base class shall
be public virtual,
public override or
protected
non-virtual.
12.3.1 Correctly declare overloads for
operator new and delete.
2 - Small differences A18-5-11
12.4.1 Do not use the dynamic type
of an object unless the object is fully
constructed.
2 - Small differences M12-1-1
12.4.2 Ensure that a constructor
initializes explicitly all base classes and
non-static data members.
2 - Small differences A12-1-1
12.4.3 Do not specify both an NSDMI
and a
member initializer in a constructor for
the same non static member.
2 - Significant differences A12-1-2 Using both NSDMI
and
member initializer
list in one class is
not allowed.
12.4.4 Write
members in an initialization list in the
order in which they are declared.
2 - Small differences A8-5-1
12.4.5 Use delegating constructors to
reduce code duplication.
2 - Small differences A12-1-5
12.5.1 Define
explicitly =default or =delete implicit
special member functions of concrete
classes.
3 - Significant differences A12-0-1
12.5.2 Define special members
=default if the behavior is equivalent.
2 - Small differences A12-7-1
12.5.3 Ensure that
a user defined move/copy constructor
only moves/copies base and member
objects.
2 - Small differences A12-8-1
12.5.4 Declare noexcept the move
constructor and move assignment
operator.
3 - Significant differences A15-5-1 AUTOSAR C++
Coding Guidelines
requires
additional functions
to be noexcept.
12.5.5 Correctly reset moved-from
handles to resources in the move
constructor.
2 - Small differences A12-8-1
12.5.6 Use an atomic, non-throwing
swap operation to implement the copy
and move assignment operators.
2 - Small differences A12-8-2
12.5.7 Declare assignment operators
with the ref-qualifier &.
2 - Small differences A12-8-7
12.5.8 Make the copy assignment
operator of an abstract class protected
or define it =delete.
3 - Significant differences A12-8-6 AUTOSAR C++
Coding Guidelines
requires
additional functions
to be comply with
this rule.
13.1.1 Ensure that all overloads of a
function are visible from where it is
called.
2 - Small differences A7-3-1
13.1.2 If a member of a set of
callable functions includes a universal
reference parameter, ensure that one
appears in the same position for all
other members.
3 - Significant differences A13-3-1 A function taking
“forwarding
reference” shall not
be overloaded.
13.2.1 Do not overload operators with
special semantics.
2 - Small differences M5-2-11,
M5-3-3
13.2.2 Ensure that the return type of an
overloaded binary operator matches
the built-in counterparts.
2 - Small differences A13-
2-1, A13-2-
2, A13-2-3
13.2.3 Declare binary arithmetic and
bitwise operators as non-members.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
13.2.4 When overloading the subscript
operator (operator[]) implement both
const and non-const versions.
2 - Small differences A13-5-1
13.2.5 Implement a minimal set of
operators and use them to implement
all other related operators.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
14.1.1 Use variadic templates rather
than an ellipsis.
3 - Significant differences A8-4-1 AUTOSAR C++
Coding Guidelines
prohibits usage of
variadic
arguments.
14.2.1 Declare template
specializations in the same file as the
primary template they specialize.
3 - Significant differences A14-7-2 Allowed to declare
in a header file
that declares user-
defined
type, for which the
specialization is
declared.
14.2.2 Do not explicitly specialize a
function template that is overloaded
with other templates.
3 - Significant differences A14-8-2 Function templates
specialization is
forbidden.
14.2.3 Declare extern an explicitly
instantiated template.
4 - Rejected
15.1.1 Only use instances of
std::exception for exceptions.
2 - Small differences A15-1-1
15.2.1 Do not throw an exception from
a destructor.
2 - Small differences A15-5-1
15.3.1 Do
not access non-static members from a
catch handler of constructor/destructor
function try block.
2 - Small differences M15-3-3
15.3.2 Ensure that a program does not
result in a call to std::terminate.
2 - Small differences A15-5-2,
A15-5-3
16.1.1 Use the preprocessor only
for implementing include guards, and
including header files with include
guards.
3 - Significant differences A16-0-1 Conditional
and unconditional
file inclusion is
allowed.
16.1.2 Do not include a path specifier
in filenames supplied in #include
directives.
3 - Significant differences A16-2-1 Path specifier /is
allowed to specify
a path relative to
path passed to the
compiler.
16.1.3 Match the filename in a #include
directive to the one on the file system.
4 - Rejected
16.1.4 Use <> brackets for system and
standard library headers. Use quotes
for all other headers.
4 - Rejected The rule defines a
coding style.
Anyway ,
these are the only
forms allowed by
the C++ Language
Standard. No need
for a new rule.
16.1.5 Include directly the
minimum number of headers required
for compilation.
4 - Rejected There shall be
no unused include
directives, however
all needed headers
shall be included
explicitly . See:
A16-2-2, A16-2-3.
17.1.1 Do not use std::vector<bool>. 2 - Small differences A18-1-2
17.2.1 Wrap use of the C Standard
Library .
2 - Small differences A17-1-1
17.3.1 Do not use std::move on objects
declared with const or const & type.
2 - Small differences A18-9-3
17.3.2 Use std::forward to forward
universal references.
2 - Small differences A18-9-2
17.3.3 Do not subsequently use the
argument to std::forward.
2 - Small differences A18-9-4
17.3.4 Do not create smart pointers of
array type.
3 - Significant differences A18-1-4 Rule reformulated
to better capture
the problem cases
and to allow use of
smart pointer
specializations for
array types.
17.3.5 Do not create an rvalue
reference of std::array .
4 - Rejected The rule is only a
hint
saying that passing
std::array by rvalue
reference would be
less efficient
than passing it by
reference.
However, usage
depends on the
case, and it should
be allowed to pass
std::array by rvalue
reference.
17.4.1 Use const container calls when
result is immediately converted to a
const iterator.
2 - Small differences A23-0-1
17.4.2 Use API calls that construct
objects in place.
3 - Significant differences A18-5-2 A18-5-
2 prohibits explicit
calls to new and
delete operators,
std::make_shared,
std::make_unique
and similar
constructions are
recommended.
17.5.1 Do not ignore the
result of std::remove, std::remove_if or
std::unique.
2 - Small differences A0-1-2
18.1.1 Do not use platform specific
multi-threading facilities.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.2.1 Use high_integrity::thread in
place of std::thread.
4 - Rejected The
high_integrity::thread
is not part of the
C++ Language
Standard.
18.2.2 Synchronize access to data
shared between threads using a single
lock.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.2.3 Do not share volatile data
between threads.
3 - Significant differences A2-11-1 Volatile keyword
forbidden.
18.2.4 Use std::call_once rather than
the Double-Checked Locking pattern.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.1 Within the scope of a lock,
ensure that no static path results in a
lock of the same mutex.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.2 Ensure that order of nesting of
locks in a project forms a DAG.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.3 Do not use
std::recursive_mutex.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.4 Only use std::unique_lock when
std::lock_guard cannot be used.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.5 Do not access the members of
std::mutex directly .
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.6 Do not use relaxed atomics. 5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.4.1 Do
not use std::condition_variable_any on
a std::mutex
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
Table B.2: HIC++ v4.0
B.3 Traceability to JSF
The following table demonstrates the traceability to Joint Strike Fighter Air Vehicle C++
Coding Standard [8]. This is not considered as a reproduction, but a mean to compare
the two standards.
Note that the copyright of JSF-AV 2005 allows an unlimited distribution anyway .
JSF Rule: Relation type: Related
rule:
Comment:
AV Rule 8 All code shall conform to
ISO/IEC 14882:2002(E) standard C++.
2 - Small differences A1-1-1
AV Rule 9 Only those characters
specified in the C++ basic source
character set will be used. [...].
2 - Small differences A2-3-1
AV Rule 10 Values of character types
will be restricted to a defined and
documented subset of ISO 10646-1.
4 - Rejected Source
files encoding is
too restrictive and
not covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 11 Trigraphs will not be used. 2 - Small differences A2-5-1
AV Rule 12 The following digraphs will
not be used [...].
2 - Small differences A2-5-2
AV Rule 13 Multi-byte characters and
wide string literals will not be used.
4 - Rejected Agreed for wchar_t
type only , A2-13-3.
AV Rule 14 Literal suffixes shall
use uppercase rather than lowercase
letters.
2 - Small differences M2-13-4
AV Rule 15 Provision shall be
made for run-time checking (defensive
programming).
2 - Small differences M0-3-1
AV Rule 16 Only DO-178B level A [15]
certifiable or SEAL 1 C/C++ libraries
shall be used with safety-critical (i.e.
SEAL 1) code.
4 - Rejected JSF-specific rule.
AV Rule 17 The error indicator errno
shall not be used.
2 - Small differences M19-3-1
AV Rule 18 The macro offsetof, in
library <stddef.h>, shall not be used.
2 - Small differences M18-2-1
AV Rule 19 <locale.h> and the
setlocale function shall not be used.
2 - Small differences A18-0-3
AV Rule 20 The setjmp macro and the
longjmp function shall not be used.
2 - Small differences M17-0-5
AV Rule 21 The signal handling
facilities of <signal.h> shall not be
used.
2 - Small differences M18-7-1
AV Rule 22 The input /output library
<stdio.h> shall not be used.
2 - Small differences M27-0-1
AV Rule 23 The library functions atof,
atoi and atol from library <stdlib.h>
shall not be used.
2 - Small differences A18-0-2
AV Rule 24 The library functions abort,
exit, getenv and system from library
<stdlib.h> shall not be used.
2 - Small differences M18-0-3
AV Rule 25
The time handling functions of library
<time.h> shall not be used.
2 - Small differences M18-0-4
AV Rule 26 Only the following pre-
processor directives shall be used:
1. #ifndef 2. #define 3. #endif 4.
#include.
2 - Small differences A16-0-1
AV Rule 27 #ifndef, #define and #endif
will be used to prevent
multiple inclusions of the same header
file. Other techniques to prevent the
multiple inclusions of header files will
not be used.
2 - Small differences A16-0-1,
M16-2-3
AV Rule 28 The #ifndef and #endif pre-
processor directives will only be used
as defined in AV Rule 27 to prevent
multiple inclusions of the same header
file.
2 - Small differences A16-0-1
AV Rule 29 The #define pre-processor
directive shall not be used to create
inline macros. Inline functions shall be
used instead.
2 - Small differences A16-0-1
AV Rule 30 The #define pre-processor
directive shall not be used to define
constant values. Instead, the const
qualifier shall
be applied to variable declarations to
specify constant values.
2 - Small differences A16-0-1
AV Rule 31 The #define pre-processor
directive will only be used as part
of the technique to prevent multiple
inclusions of the same header file.
2 - Small differences A16-0-1
AV Rule 32 The #include pre-
processor directive will only be used to
include header (*.h) files.
2 - Small differences A16-0-1
AV Rule 33 The #include directive
shall use the <filename.h> notation to
include header files.
4 - Rejected Including
files using quotes is
also possible.
AV Rule 34 Header files should contain
logically related declarations only .
2 - Small differences A3-3-1
AV Rule 35 A header file will contain
a mechanism that prevents multiple
inclusions of itself.
2 - Small differences M16-2-3
AV Rule 36 Compilation dependencies
should be minimized when possible.
4 - Rejected The
rule is vague; more
precisely explained
by AV Rules 37 and
38.
AV Rule 37 Header (include) files
should include only those header
files that are required for them to
successfully compile. Files that are
only used by the associated .cpp file
should be placed in the .cpp file - not
the .h file.
2 - Small differences A16-2-2,
A16-2-3
AV Rule 38 Declarations of classes
that are only accessed via pointers (*)
or references (&) should be supplied
by forward headers that contain only
forward declarations.
3 - Significant differences A16-2-3 Forward
declarations
considered as
a possible solution
for unnecessarry
inclusions.
AV Rule 39 Header files (*.h) will not
contain non-const variable definitions
or function definitions.
2 - Small differences M3-2-4, A3-
3-1
AV Rule 40 Every implementation file
shall include the header files that
uniquely define the inline functions,
types, and templates used.
2 - Small differences M3-2-4, A3-
3-1
AV Rule 41 Source lines will be kept to
a length of 120 characters or less.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 42
Each expression-statement will be on
a separate line.
2 - Small differences A7-1-7
AV Rule 43 T abs should be avoided. 4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 44 All indentations will be at
least two spaces and be consistent
within the same source file.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 45 All words in an identifier will
be separated by the “_” character.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 46 User-specified identifiers
(internal and external) will not rely
on significance of more than 64
characters.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 47 Identifiers will not begin
with the underscore character “_”.
3 - Significant differences A17-0-1
AV Rule 48 Identifiers will not differ by:
(a) Only a mixture of case, (b) The
presence/absence of the underscore
character, (c) The interchange of the
letter “O”, with the number “0” or the
letter “D”, (d) The interchange of the
letter “I”, with the number “1” or the
letter “l”, (e) The interchange of the
letter “S” with the number “5”, (f) The
interchange of the letter “Z” with the
number “2”, (g) The interchange of the
letter “n” with the letter “h”.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 49 All acronyms in an identifier
will be composed of uppercase letters.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 50 The first word of the name
of a class, structure, namespace,
enumeration, or type created with
typedef will begin with an uppercase
letter. All others letters will be
lowercase.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 51 All letters contained in
function and variable names will be
composed entirely of lowercase letters.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 52 Identifiers for constant and
enumerator values shall be lowercase.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 53 Header files will always
have a file name extension of “.h”.
3 - Significant differences A3-1-2
AV Rule 53.1 The following character
sequences shall not appear in header
file names: ’, \, /*, //, or ”.
2 - Small differences A16-2-1
AV Rule 54 Implementation files will
always have a file name extension of
“.cpp”.
2 - Small differences A3-1-3
AV Rule 55 The name of a header
file should reflect the logical entity for
which it provides declarations.
2 - Small differences A2-8-1
AV Rule 56 The
name of an implementation file should
reflect the logical entity for which it
provides definitions and have a “.cpp”
extension (this name will normally be
identical to the header file that provides
the corresponding declarations.)
2 - Small differences A2-8-2
AV Rule 57 The public, protected, and
private sections
of a class will be declared in that order
(the public section is declared before
the protected section which is declared
before the private section).
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 58 When declaring and
defining functions with more than two
parameters, the leading parenthesis
and the first argument will be written
on the same line as the function
name. Each additional argument will
be written on a separate line (with the
closing parenthesis directly after the
last argument).
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 59 The statements forming
the body of an if, else if, else, while,
do...while or for statement shall always
be enclosed in braces, even if the
braces form an empty block.
2 - Small differences M6-3-1
AV Rule 60 Braces (“{}”) which enclose
a block will be placed in the same
column, on separate lines directly
before and after the block.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 61 Braces (“{}”) which enclose
a block will have nothing else on the
line except comments (if necessary).
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 62 The dereference operator
“*” and the address-of operator “&” will
be directly connected with the type-
specifier.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 63 Spaces will not be used
around “. ” or “->”, nor between unary
operators and operands.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 64 A class interface should be
complete and minimal.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 65 A structure should be used
to model an entity that does not require
an invariant.
3 - Significant differences A11-0-2
AV Rule 66 A class should be used
to model an entity that maintains an
invariant.
3 - Significant differences A11-0-1
AV Rule 67 Public and protected data
should only be used in structs - not
classes.
2 - Small differences M11-0-1
AV Rule 68 Unneeded
implicitly generated member functions
shall be explicitly disallowed.
3 - Significant differences A12-0-1 It
is allowed to follow
both “Rule of zero”
and “Rule of five”.
AV Rule 69 A member function that
does not affect the state of an object
(its instance variables) will be declared
const.
2 - Small differences M9-3-3
AV Rule 70 A class will have friends
only when a function or object requires
access to the private elements of the
class, but is unable to be a member
of the class for logical or efficiency
reasons.
4 - Rejected Friend declarations
are prohibited, see:
A11-3-1.
AV Rule 70.1 An object shall not
be improperly used before its lifetime
begins or after its lifetime ends.
2 - Small differences A3-8-1, A5-
1-4, M7-5-1,
M7-5-2, A7-
5-1, M12-1-1
AV Rule 71 Calls to an externally
visible operation of an object, other
than its constructors, shall not be
allowed until the object has been fully
initialized.
2 - Small differences A12-1-1,
M12-1-1
AV Rule 71.1 A class’s virtual functions
shall not be invoked from its destructor
or any of its constructors.
2 - Small differences M12-1-1
AV Rule
72 The invariant for a class should be:
(a) a part of the postcondition of every
class constructor, (b) a part of the
precondition of the class destructor (if
any), (c) a part of the precondition and
postcondition of every other publicly
accessible operation.
3 - Significant differences A15-2-
2, M11-0-1,
M9-3-1, A9-
3-1
No enforcement on
pre/postcondition
checking in the
Coding Guidelines
AV Rule 73 Unnecessary default
constructors shall not be defined.
4 - Rejected No rule needed.
AV Rule 74 Initialization of nonstatic
class members will be performed
through the member initialization list
rather than through assignment in the
body of a constructor.
2 - Small differences A12-6-1
AV Rule 75 Members
of the initialization list shall be listed in
the order in which they are declared in
the class.
2 - Small differences A8-5-1
AV Rule 76 A copy constructor and an
assignment operator shall be declared
for classes that contain pointers to data
items or nontrivial destructors.
2 - Small differences A12-7-1
AV Rule 77 A copy constructor shall
copy all data members and bases
that affect the class invariant (a data
element representing a cache, for
example, would not need to be copied).
2 - Small differences A12-8-1
AV Rule 77.1 The definition of a
member function shall not contain
default arguments that produce a
signature identical to that of the
implicitly-declared copy constructor for
the corresponding class/structure.
4 - Rejected No ambiguity in
C++14, see
ISO/IEC
14882:2014 C++14
12.8 [class.copy]2
AV Rule 78 All base classes with a
virtual function shall define a virtual
destructor.
2 - Small differences A12-4-1
AV Rule 79 All resources acquired by
a class shall be released by the class’s
destructor.
2 - Small differences A15-1-4,
A18-5-2
AV Rule 80 The default copy and
assignment operators will be used for
classes when those operators offer
reasonable semantics.
2 - Small differences A12-0-1
AV Rule 81 The assignment operator
shall handle self-assignment correctly .
2 - Small differences A12-8-5
AV Rule 82 An assignment operator
shall return a reference to *this.
2 - Small differences A13-2-1
AV Rule 83 An assignment operator
shall assign all data members and
bases that affect the class invariant (a
data element representing a cache, for
example, would not need to be copied).
2 - Small differences A6-2-1
AV Rule 84 Operator overloading
will be used sparingly and in a
conventional manner.
4 - Rejected The rule is vague.
Design
principle; There is
no need for a new
rule.
AV Rule 85 When two operators are
opposites (such as == and !=), both will
be defined and one will be defined in
terms of the other.
2 - Small differences A13-5-4
AV Rule 86 Concrete types should be
used to represent simple independent
concepts.
4 - Rejected The rule is vague.
Design
principle; There is
no need for a new
rule.
AV Rule 87 Hierarchies should be
based on abstract classes.
2 - Small differences A10-4-1
AV Rule 88 Multiple inheritance shall
only be allowed in the following
restricted form: n interfaces plus m
private implementations, plus at most
one protected implementation.
3 - Significant differences A10-1-1
AV Rule 88.1 A stateful virtual base
shall be explicitly declared in each
derived class that accesses it.
4 - Rejected Virtual inheritance
should not be used,
see: M10-1-1.
AV Rule 89 A base class shall not be
both virtual and non-virtual in the same
hierarchy .
2 - Small differences M10-1-3
AV Rule 90 Heavily used
interfaces should be minimal, general
and abstract.
4 - Rejected The rule is vague.
Design
principle; There is
no need for a new
rule.
AV Rule 91 Public inheritance will be
used to implement “is-a” relationships.
2 - Small differences A10-0-1
AV Rule 92 A subtype (publicly
derived classes) will conform to the
following guidelines with respect to all
classes involved in the polymorphic
assignment of different subclass
instances to the same variable or
parameter during the execution of the
system: (1) Preconditions of derived
methods must be at least as weak as
the preconditions of the methods they
override. (2) Postconditions of derived
methods must be at least as strong
as the postconditions of the methods
they override. In other words, subclass
methods must expect less and deliver
more than the base class methods
they override. This rule implies that
subtypes will conform to the Liskov
Substitution Principle.
4 - Rejected The rule is vague.
Design
principle; There is
no need for a new
rule.
AV Rule 93 “has-a” or “is-implemented-
in-terms-of” relationships will be
modeled through membership or non-
public inheritance.
2 - Small differences A10-0-2
AV Rule 94 An inherited nonvirtual
function shall not be redefined in a
derived class.
2 - Small differences A10-2-1
AV Rule 95 An inherited default
parameter shall never be redefined.
2 - Small differences M8-3-1
AV Rule 96 Arrays shall not be treated
polymorphically .
2 - Small differences A5-0-4
AV Rule 97 Arrays shall not be used
in interfaces. Instead, the Array class
should be used.
2 - Small differences M5-2-12
AV Rule 97.1 Neither operand of an
equality operator (== or !=) shall be a
pointer to a virtual member function.
3 - Significant differences A5-10-1 Testing for equality
with null-
pointer-constant is
allowed.
AV Rule 98 Every nonlocal name,
except main(), should be placed in
some namespace.
2 - Small differences M7-3-1
AV Rule 99 Namespaces will not be
nested more than two levels deep.
4 - Rejected Not compliant with
the
AUTOSAR general
requirements.
AV Rule 100
Elements from a namespace should
be selected as follows: (a) using
declaration or explicit qualification for
few (approximately five) names, (b)
using directive for many names.
3 - Significant differences M7-3-4, M7-
3-6
AV Rule 101 Templates shall be
reviewed as follows: (1) with respect
to the template in isolation considering
assumptions or requirements placed
on its arguments, (2) with respect
to all functions instantiated by actual
arguments.
4 - Rejected Rule concerns
code review
process.
AV Rule 102 Template tests shall be
created to cover all actual template
instantiations.
4 - Rejected Rule concerns test
process.
AV Rule 103 Constraint checks should
be applied to template arguments.
2 - Small differences A14-1-1
AV Rule 104 A template specialization
shall be declared before its use.
2 - Small differences A14-7-2
AV Rule 105 A template definition’s
dependence
on its instantiation contexts should be
minimized.
4 - Rejected This rule is vague.
“Minimized” has no
technical meaning.
AV Rule 106 Specializations for pointer
types should be made where
appropriate.
4 - Rejected This rule is vague.
“Where
appropriate”
has no technical
meaning.
AV Rule 107 Functions shall always be
declared at file scope.
2 - Small differences M3-1-2
AV Rule 108 Functions with variable
numbers of arguments shall not be
used.
2 - Small differences A8-4-1
AV Rule 109 A function definition
should not be placed in a class
specification unless the function is
intended to be inlined.
3 - Significant differences A3-1-5 Also included
template methods
and methods of
template classes.
AV Rule 110 Functions with more than
7 arguments will not be used.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 111 A function shall not return
a pointer or reference to a non-static
local object.
2 - Small differences M7-5-2
AV Rule
112 Function return values should not
obscure resource ownership.
2 - Small differences M9-3-1, A9-
3-1, A20-8-
2, A20-8-3
AV Rule 113 Functions will have a
single exit point.
4 - Rejected See Single-
point-of-exit.
AV Rule 114 All exit points of value-
returning functions shall be through
return statements.
2 - Small differences A8-4-2
AV Rule 115 If a function returns error
information, then that error information
will be tested.
2 - Small differences A8-4-2
AV Rule 116 Small, concrete-type
arguments (two or three words in size)
should be passed by value if changes
made to formal parameters should not
be reflected in the calling function.
2 - Small differences A8-4-7
AV Rule 117 Arguments should be
passed by reference if NULL values
are not possible.
2 - Small differences A8-4-10
AV Rule 117.1 An object should be
passed as const T& if the function
should not change the value of the
object.
2 - Small differences A8-4-7
AV Rule 117.2 An object should be
passed as T& if the function may
change the value of the object.
2 - Small differences A8-4-9
AV Rule 118 Arguments should be
passed via pointers if NULL values are
possible.
3 - Significant differences A8-4-10
AV Rule 118.1 An object should be
passed as const T* if its value should
not be modified.
3 - Significant differences A8-4-10
AV Rule 118.2 An object should be
passed as T* if its value may be
modified.
3 - Significant differences A8-4-10
AV Rule 119 Functions shall not call
themselves, either directly or indirectly
(i.e. recursion shall not be allowed).
2 - Small differences A7-5-2
AV Rule 120 Overloaded operations
or methods should form families that
use the same semantics, share the
same name, have the same purpose,
and that are differentiated by formal
parameters.
4 - Rejected This rule is vague.
It is not a coding
rule.
AV Rule 121 Only functions with 1
or 2 statements should be considered
candidates for inline functions.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 122 Trivial accessor and
mutator functions should be inlined.
2 - Small differences A3-1-6
AV Rule 123 The number of accessor
and mutator functions should be
minimized.
4 - Rejected This rule is vague.
It is not a coding
rule.
AV Rule 124 Trivial forwarding
functions should be inlined.
4 - Rejected Forwarding
functions are
mostly
templates and they
most likely will be
inlined.
AV Rule 125 Unnecessary temporary
objects should be avoided.
2 - Small differences M0-1-9, A1-
4-3
AV Rule 126 Only valid C++ style
comments (//) shall be used.
2 - Small differences M2-7-1
AV Rule 127 Code that is not used
(commented out) shall be deleted.
2 - Small differences A2-7-2
AV Rule 128 Comments that document
actions or sources (e.g. tables, figures,
paragraphs, etc.) outside of the file
being documented will not be allowed.
2 - Small differences A2-7-5
AV Rule 129 Comments in header files
should describe the externally visible
behavior of the functions or classes
being documented.
3 - Significant differences A2-7-3
AV Rule 130 The purpose of every
line of executable code should be
explained by a comment, although one
comment may describe more than one
line of code.
4 - Rejected
AV Rule 131 One should avoid stating
in comments what is better stated in
code (i.e. do not simply repeat what
is in the code).
4 - Rejected
AV Rule 132 Each variable declaration,
typedef, enumeration value, and
structure member will be commented.
4 - Rejected
AV Rule 133 Every source file will
be documented with an introductory
comment that
provides information on the file name,
its contents, and any program-required
information (e.g. legal statements,
copyright information, etc).
4 - Rejected
AV Rule 134 Assumptions (limitations)
made by
functions should be documented in the
function’s preamble.
3 - Significant differences A2-7-3
AV Rule 135 Identifiers in an inner
scope shall not use the same name
as an identifier in an outer scope, and
therefore hide that identifier.
2 - Small differences A2-10-1
AV Rule 136 Declarations should be at
the smallest feasible scope.
2 - Small differences M3-4-1
AV Rule 137 All declarations at file
scope should be static where possible.
3 - Significant differences A3-3-1
AV Rule 138 Identifiers shall not
simultaneously have both internal and
external linkage in the same translation
unit.
2 - Small differences M3-3-2
AV Rule 139 External objects will not
be declared in more than one file.
2 - Small differences M3-2-3
AV Rule 140 The register storage class
specifier shall not be used.
2 - Small differences A7-1-4
AV Rule 141 A class, structure, or
enumeration will not be declared in the
definition of its type.
2 - Small differences A7-1-9
AV Rule 142 All variables shall be
initialized before use.
2 - Small differences A8-5-0
AV Rule 143 Variables will not be
introduced until they can be initialized
with meaningful values.
2 - Small differences M3-4-1
AV Rule 144 Braces shall be used
to indicate and match the structure in
the non-zero initialization of arrays and
structures.
2 - Small differences M8-5-2
AV Rule 145 In an enumerator list,
the “=” construct shall not be used to
explicitly initialize members other than
the first, unless all items are explicitly
initialized.
2 - Small differences A7-2-4
AV Rule 146
Floating point implementations shall
comply with a defined floating point
standard. The standard that will be
used is the ANSI/IEEE Std 754
2 - Small differences A0-4-1
AV Rule
147 The underlying bit representations
of floating point numbers shall not be
used in any way by the programmer.
2 - Small differences M3-9-3
AV Rule 148 Enumeration types shall
be used instead of integer types (and
constants) to select from a limited
series of choices.
2 - Small differences A7-2-5
AV Rule 149 Octal constants (other
than zero) shall not be used.
2 - Small differences M2-13-2
AV Rule 150 Hexadecimal constants
will be represented using all uppercase
letters.
2 - Small differences A2-13-5
AV Rule 151 Numeric values in code
will not be used; symbolic values will
be used instead.
2 - Small differences A5-1-1
AV Rule 151.1 A string literal shall not
be modified.
2 - Small differences A2-13-4
AV Rule
152 Multiple variable declarations shall
not be allowed on the same line.
2 - Small differences A7-1-7
AV Rule 153 Unions shall not be used. 2 - Small differences A9-5-1
AV Rule 154
Bit-fields shall have explicitly unsigned
integral or enumeration types only .
3 - Significant differences A9-6-1 Any
type with a defined
size is allowed to
be used for a bit-
field.
AV Rule 155 Bit-fields will not be used
to pack data into a word for the sole
purpose of saving space.
2 - Small differences A9-6-2
AV Rule 156 All the members of a
structure (or class) shall be named and
shall only be accessed via their names.
2 - Small differences A12-0-2
AV Rule 157 The right hand operand of
a && or ||operator shall not contain side
effects.
2 - Small differences M5-14-1
AV Rule 158 The operands of a logical
&& or ||shall be parenthesized if the
operands contain binary operators.
2 - Small differences A5-2-6
AV Rule 159 Operators ||, &&, and
unary & shall not be overloaded.
2 - Small differences M5-2-11,
M5-3-3
AV Rule 160 An assignment
expression shall be used only as the
expression in an expression statement.
2 - Small differences M6-2-1
AV Rule 162 Signed and unsigned
values shall not be mixed in arithmetic
or comparison operations.
2 - Small differences M5-0-4, M5-
0-9
AV Rule 163 Unsigned arithmetic shall
not be used.
2 - Small differences M5-0-4, M5-
0-9
AV Rule 164 The right hand operand of
a shift operator shall lie between zero
and one less than the width in bits of
the left-hand operand (inclusive).
2 - Small differences M5-8-1
AV Rule 164.1 The left-hand operand
of a right-shift operator shall not have a
negative value.
2 - Small differences M5-8-1
AV Rule 165 The unary minus operator
shall not be applied to an unsigned
expression.
2 - Small differences M5-3-2
AV Rule 166 The sizeof operator
will not be used on expressions that
contain side effects.
2 - Small differences M5-3-4
AV Rule 167 The implementation of
integer division in the chosen compiler
shall be determined, documented and
taken into account.
3 - Significant differences A0-4-2
AV Rule 168 The comma operator shall
not be used.
2 - Small differences M5-18-1
AV Rule 169 Pointers to pointers
should be avoided when possible.
3 - Significant differences A5-0-3
AV Rule 170 More than 2 levels of
pointer indirection shall not be used.
3 - Significant differences A5-0-3
AV Rule 171 Relational operators shall
not be applied to pointer types except
where both operands are of the same
type and point to: (a) the same object,
(b) the same function, (c) members of
the same object, or (d) elements of the
same array (including one past the end
of the same array).
2 - Small differences M5-0-18
AV Rule 173 The address of an object
with automatic storage shall not be
assigned to an object which persists
after the object has ceased to exist.
2 - Small differences M7-5-2
AV Rule 174 The null pointer shall not
be de-referenced.
2 - Small differences A5-3-2
AV Rule 175 A pointer shall not be
compared to NULL or be assigned
NULL; use plain 0 instead.
4 - Rejected Only nullptr
constant shall be
used, see: A4-10-
1.
AV Rule 176 A typedef will be
used to simplify program syntax when
declaring function pointers.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
AV Rule 177 User-defined conversion
functions should be avoided.
2 - Small differences A13-5-3
AV Rule 178 Down casting (casting
from base to derived class) shall only
be allowed through one of the following
mechanism: (a) Virtual functions that
act like dynamic casts (most likely
useful in relatively simple cases), (b)
Use of the visitor (or similar) pattern
(most likely useful in complicated
cases)
2 - Small differences M5-2-2, A5-
2-6
AV Rule 179 A pointer to a virtual
base class shall not be converted to a
pointer to a derived class.
2 - Small differences M5-2-3
AV Rule 180 Implicit conversions that
may result in a loss of information shall
not be used.
2 - Small differences A4-7-1
AV Rule 181 Redundant explicit casts
will not be used.
2 - Small differences M0-1-9
AV Rule 182 T ype casting from any
type to or from pointers shall not be
used.
3 - Significant differences M5-2-9 Not fully covered.
AV Rule 183 Every possible measure
should be taken to avoid type casting.
4 - Rejected It is not a coding
rule.
AV Rule 184 Floating
point numbers shall not be converted
to integers unless such a conversion is
a specified algorithmic requirement or
is necessary for a hardware interface.
2 - Small differences M5-0-5
AV
Rule 185 C++ style casts (const_cast,
reinterpret_cast, and static_cast) shall
be used instead of the traditional C-
style casts.
2 - Small differences A5-2-2
AV Rule 186 There shall be no
unreachable code.
2 - Small differences M0-1-1
AV Rule 187 All non-null statements
shall potentially have a side-effect.
2 - Small differences M0-1-9
AV Rule 188 Labels will not be used,
except in switch statements.
3 - Significant differences A6-6-1
AV Rule 189 The goto statement shall
not be used.
2 - Small differences A6-6-1
AV Rule 190 The continue statement
shall not be used.
4 - Rejected The continue
statement usage is
allowed within for-
loops, see: M6-6-3.
AV Rule 191 The break statement shall
not be used (except to terminate the
cases of a switch statement).
2 - Small differences M6-4-5
AV Rule 192 All if, else if constructs
will contain either a final else clause or
a comment indicating why a final else
clause is not necessary .
2 - Small differences M6-4-2
AV Rule 193 Every non-empty case
clause in a switch statement shall be
terminated with a break statement.
2 - Small differences M6-4-3, M6-
4-5
AV Rule 194 All switch statements
that do not intend to test for every
enumeration value shall contain a final
default clause.
2 - Small differences M6-4-6
AV Rule 195 A switch expression will
not represent a Boolean value.
2 - Small differences M6-4-7
AV Rule 196 Every switch statement
will have at least two cases and a
potential default.
2 - Small differences A6-4-1
AV Rule 197 Floating point variables
shall not be used as loop counters.
2 - Small differences M6-5-2
AV Rule 198 The initialization
expression in a for loop will perform no
actions other than to initialize the value
of a single for loop parameter.
2 - Small differences A6-5-4
AV Rule 199 The increment expression
in a for loop will perform no action other
than to change a single loop parameter
to the next value for the loop.
2 - Small differences A6-5-4
AV Rule 200 Null initialize or increment
expressions in for loops will not be
used; a while loop will be used instead.
3 - Significant differences A6-5-2
AV Rule 201 Numeric variables being
used within a for loop for iteration
counting shall not be modified in the
body of the loop.
2 - Small differences M6-5-3
AV Rule 202 Floating point variables
shall not be tested for exact equality or
inequality .
2 - Small differences M6-2-2
AV Rule 203 Evaluation of expressions
shall not lead to overflow/underflow
(unless required algorithmically and
then should be heavily documented).
2 - Small differences M5-19-1,
A7-1-2
AV Rule 204 A single operation with
side-effects shall only be used in the
following contexts: 1. by itself 2.
the right-hand side of an assignment
3. a condition 4. the only argument
expression with a side-effect in a
function call 5. condition of a loop 6.
switch condition 7. single part of a
chained operation.
3 - Significant differences M6-2-1 Some of presented
examples are
not misleading and
some of them are
already covered.
AV Rule 204.1 The value of an
expression shall be the same under
any order of evaluation that the
standard permits.
2 - Small differences A5-0-1
AV Rule 205 The volatile keyword shall
not be used unless directly interfacing
with hardware.
3 - Significant differences A2-11-1 Volatile keyword
forbidden.
AV Rule 206 Allocation/deallocation
from/to the free store (heap) shall not
occur after initialization.
2 - Small differences A18-5-3
AV Rule 207 Unencapsulated global
data will be avoided.
3 - Significant differences A3-3-2 Restriction to
constant-initialized
objects only .
AV Rule 208 C++ exceptions shall not
be used (i.e. throw, catch and try shall
not be used.)
4 - Rejected C++
exceptions may be
used conditionally .
AV Rule 209 The basic types of
int, short, long, float and double
shall not be used, but specific-
length equivalents should be typedef’d
accordingly for each compiler, and
these type names used in the code.
2 - Small differences A3-9-1
AV Rule 210 Algorithms shall not make
assumptions concerning how data is
represented in memory (e.g. big
endian
vs. little endian, base class subobject
ordering in derived classes, nonstatic
data member ordering across access
specifiers, etc.)
2 - Small differences A12-0-2
AV Rule 210.1 Algorithms shall not
make assumptions concerning the
order of allocation of nonstatic data
members separated by an access
specifier.
2 - Small differences A12-0-2
AV Rule 211 Algorithms shall not
assume that shorts, ints, longs, floats,
doubles or long doubles begin at
particular addresses.
2 - Small differences A12-0-2
AV Rule 212 Underflow or overflow
functioning shall not be depended on
in any special way .
2 - Small differences A4-7-1
AV Rule 213 No dependence shall be
placed on C++’s operator precedence
rules, below arithmetic operators, in
expressions.
2 - Small differences A5-0-1
AV Rule 214 Assuming that non-local
static objects, in separate translation
units, are initialized in a special order
shall not be done.
2 - Small differences A3-3-2 Intent
of the rule achieved
by restriction to
constant-initialized
objects.
AV Rule 215 Pointer arithmetic will not
be used.
3 - Significant differences M5-0-15 Pointer arithmetic
may be used for
array indexing.
AV Rule 216 Programmers should not
attempt to prematurely optimize code.
4 - Rejected It is not a coding
rule.
AV Rule 217 Compile-time and link-
time errors should be preferred over
run-time errors.
4 - Rejected A16-6-1,
A14-1-1, A1-
4-3
This rule is
too generic, some
cases are covered.
AV Rule 218 Compiler warning levels
will be set in compliance with project
policies.
3 - Significant differences A1-1-2
AV Rule 219 All tests applied to a
base class interface shall be applied
to all derived class interfaces as well.
If the derived class poses stronger
postconditions/invariants, then the new
postconditions /invariants shall be
substituted in the derived class tests.
4 - Rejected It is not a coding
rule.
AV Rule 220 Structural coverage
algorithms shall be applied against
flattened classes.
4 - Rejected It is not a coding
rule.
AV Rule 221 Structural coverage
of a class within an inheritance
hierarchy containing virtual functions
shall include testing every possible
resolution for each set of identical
polymorphic references.
4 - Rejected It is not a coding
rule.
Table B.3: JSF
B.4 Traceability to SEI CERT C++
The following table demonstrates the traceability to SEI CERT C++ Coding Standard
[10]. This is not considered as a reproduction, but a mean to compare the two
standards.
Note that the copyright of SEI CERT C++ Coding Standard allows an unlimited
distribution anyway .
SEI CERT Rule: Relation type: Related
rule:
Comment:
DCL30-C. Declare objects with
appropriate storage durations.
2 - Small differences M7-5-2
DCL40-C. Do not create incompatible
declarations of the same function or
object.
2 - Small differences M3-9-1
DCL50-CPP . Do not define a C-style
variadic function.
2 - Small differences A8-4-1
DCL51-CPP . Do not declare or define
a reserved identifier.
2 - Small differences A13-1-2,
A17-0-1
DCL52-CPP . Never qualify a reference
type with const or volatile.
2 - Small differences A1-1-1 Covered by a more
general rule.
DCL53-CPP . Do not write syntactically
ambiguous declarations.
2 - Small differences A8-5-2
DCL54-CPP . Overload allocation and
deallocation functions as a pair in the
same scope.
3 - Significant differences A18-5-3,
A18-5-4
DCL55-
CPP . Avoid information leakage when
passing a class object across a trust
boundary .
5 - Not yet analyzed The Security
chapter is not yet
covered, this will
be addressed in
future.
DCL56-CPP . Avoid cycles during
initialization of static objects.
2 - Small differences A3-3-2 Intent
of the rule achieved
by restriction to
constant-initialized
objects.
DCL57-CPP . Do not
let exceptions escape from destructors
or deallocation functions.
3 - Significant differences A15-5-1 AUTOSAR C++
Coding Guidelines
specify more
functions that need
to be noexcept.
DCL58-CPP . Do not modify the
standard namespaces.
2 - Small differences A17-6-1
DCL59-CPP . Do not define
an unnamed namespace in a header
file.
2 - Small differences M7-3-3
DCL60-CPP . Obey the one-definition
rule.
2 - Small differences M3-2-2
EXP34-C. Do not dereference null
pointers.
2 - Small differences A5-3-2
EXP35-C. Do not modify objects with
temporary lifetime.
4 - Rejected Not applicable to
C++. See EXP54-
CPP .
EXP36-C. Do not cast pointers into
more strictly aligned pointer types.
2 - Small differences A5-2-4, M5-
2-8
Direct and indirect
casting of pointer
types is prohibited
via existing rules.
EXP37-C. Call functions with the
correct number and type of arguments.
2 - Small differences M5-2-6 The
only case possible
in C++ is prohibited
via existing rule.
EXP39-C. Do not access a variable
through a pointer of an incompatible
type.
2 - Small differences A5-2-2, A5-
2-4
Effectively
prohibited by
existing rules.
EXP42-C. Do not compare padding
data.
2 - Small differences A12-0-2
EXP45-C. Do not perform assignments
in selection statements.
2 - Small differences A5-0-2, M6-
2-1
EXP46-C. Do not use a bitwise
operator with a Boolean-like operand.
4 - Rejected Use
of bitwise operators
restricted
to following cases:
M5-0-10, M5-0-20,
M5-0-21.
EXP47-C. Do not call va_arg with an
argument of the incorrect type.
4 - Rejected Use of
variable arguments
are prohibited, see:
A8-4-1.
EXP50-CPP . Do not depend on the
order of evaluation for side effects.
2 - Small differences A5-0-1
EXP51-CPP . Do not delete an array
through a pointer of the incorrect type.
2 - Small differences M5-2-12,
A18-1-1
Covered
by a combination of
existing rules.
EXP52-CPP . Do not rely on side effects
in unevaluated operands.
3 - Significant differences M5-3-4, A5-
3-1
EXP53-CPP . Do not read uninitialized
memory .
2 - Small differences A8-5-0
EXP54-CPP . Do not access an object
outside of its lifetime.
2 - Small differences A3-8-1, A5-
1-4, M7-5-1,
M7-5-2, A7-
5-1, M12-1-1
EXP55-CPP . Do not
access a cv-qualified object through a
cv-unqualified type.
2 - Small differences A5-2-3
EXP56-CPP . Do not call a function with
a mismatched language linkage.
2 - Small differences M5-2-6
EXP57-CPP . Do not cast or delete
pointers to incomplete classes.
3 - Significant differences A5-3-3, A5-
2-2, A5-2-4
The
first part of EXP57-
CPP is entirely
covered by A5-3-3,
the second part is
implicitly rule out by
A5-2-2 and A5-2-4.
EXP58-CPP . Pass an object of the
correct type to va_start.
4 - Rejected Use of
variable arguments
are prohibited, see:
A8-4-1.
EXP59-CPP . Use offsetof() on valid
types and members.
4 - Rejected Use of offsetof()
is prohibited, see:
M18-2-1.
EXP60-CPP .
Do not pass a nonstandard-layout type
object across execution boundaries.
2 - Small differences M1-0-2
EXP61-CPP . A lambda object must not
outlive any of its reference captured
objects.
2 - Small differences A5-1-4
EXP62-CPP . Do not access the bits of
an object
representation that are not part of the
object’s value representation.
2 - Small differences A12-0-2
EXP63-CPP . Do not rely on the value
of a moved-from object.
2 - Small differences A12-8-3
INT30-C. Ensure that unsigned integer
operations do not wrap.
2 - Small differences A4-7-1, M5-
19-1
INT31-C. Ensure
that integer conversions do not result
in lost or misinterpreted data.
3 - Significant differences A4-7-1, M5-
0-15
INT32-C. Ensure that operations on
signed integers do not result in
overflow.
2 - Small differences A4-7-1
INT33-C. Ensure that division and
remainder operations do not result in
divide-by-zero errors.
2 - Small differences A5-6-1
INT34-C. Do not shift an expression by
a negative number of bits or by greater
than or equal to the number of bits that
exist in the operand.
2 - Small differences M5-8-1
INT35-C. Use correct integer
precisions.
3 - Significant differences A3-9-1
INT36-C. Converting a pointer to
integer or integer to pointer.
2 - Small differences M5-2-8, M5-
2-9
INT50-CPP . Do not cast to an out-of-
range enumeration value.
2 - Small differences A7-2-1
CTR50-CPP . Guarantee that container
indices and iterators are within the
valid range.
2 - Small differences A5-2-5
CTR51-CPP . Use valid references,
pointers, and iterators to reference
elements of a container.
2 - Small differences A23-0-2
CTR52-CPP . Guarantee that library
functions do not overflow.
2 - Small differences A5-2-5
CTR53-CPP . Use valid iterator ranges. 3 - Significant differences M5-0-
16, M5-0-17,
A5-2-5
CTR54-CPP . Do not subtract iterators
that do not refer to the same container.
3 - Significant differences M5-0-16,
M5-0-17
CTR55-CPP . Do not use an additive
operator on an iterator if the result
would overflow.
3 - Significant differences M5-0-
16, M5-0-17,
A5-2-5
CTR56-CPP . Do not
use pointer arithmetic on polymorphic
objects.
2 - Small differences A5-0-4
CTR57-CPP . Provide a valid ordering
predicate.
2 - Small differences A25-4-1
CTR58-CPP . Predicate function
objects should not be mutable.
2 - Small differences A25-1-1
ARR30-C. Do not form or use out-of-
bounds pointers or array subscripts.
3 - Significant differences A5-2-5
ARR37-C. Do not add or subtract an
integer to a pointer to a non-array
object.
3 - Significant differences M5-0-15
ARR38-
C. Guarantee that library functions do
not form invalid pointers.
3 - Significant differences
RuleLinkM5-
0-16
ARR39-C. Do not add or subtract a
scaled integer to a pointer.
3 - Significant differences M5-0-15
STR30-C. Do not attempt to modify
string literals.
4 - Rejected Use of C-style
arrays, apart from
static constexpr
members,
is prohibited. See:
A18-1-1.
STR31-C. Guarantee that storage
for strings has sufficient space for
character data and the null terminator.
3 - Significant differences A5-2-5 Effectively covered
by prohibiting out-
of-range array
access.
STR32-C. Do not pass a non-null-
terminated character sequence to a
library function that expects a string
4 - Rejected Use of functions
from <cstring> is
prohibited by M18-
0-5.
STR34-C. Cast characters to unsigned
char before converting to larger integer
sizes.
3 - Significant differences M5-0-4
STR37-C. Arguments to
character-handling functions must be
representable as an unsigned char.
2 - Small differences A21-8-1
STR38-C. Do not confuse narrow and
wide character strings and functions.
3 - Significant differences A2-13-2, A2-
13-3
Use of wchar_t is
prohibited.
STR50-CPP . Guarantee that storage
for strings has sufficient space for
character data and the null terminator.
3 - Significant differences A5-2-5 Effectively covered
by prohibiting out-
of-range array
access.
STR51-CPP . Do not attempt to create
a std::string from a null pointer.
3 - Significant differences A5-3-2 This is a special
case of a more
general rule.
STR52-CPP . Use valid references,
pointers, and iterators to reference
elements of a basic_string.
2 - Small differences A23-0-2
STR53-CPP . Range check element
access.
3 - Significant differences A5-2-5 The specific case
of A5-2-5.
MEM31-C. Free dynamically allocated
memory when no longer needed.
3 - Significant differences A15-1-4,
A18-5-2
Intent of this rule is
covered by
effectively
demanding the use
of the RAII pattern.
MEM34-C. Only free memory allocated
dynamically .
4 - Rejected Use of
malloc, calloc and
realloc functions is
prohibited, see:
A18-5-1.
MEM35-C. Allocate sufficient memory
for an object.
4 - Rejected Use of
malloc, calloc and
realloc functions is
prohibited, see:
A18-5-1.
MEM36-C.
Do not modify the alignment of objects
by calling realloc().
4 - Rejected Use of
malloc, calloc and
realloc functions is
prohibited, see:
A18-5-1.
MEM50-CPP . Do not access freed
memory .
2 - Small differences A3-8-1
MEM51-CPP . Properly deallocate
dynamically allocated resources.
3 - Significant differences A18-5-3 Use of
memory allocation
and deallocation
operators
limited by A18-5-2,
A18-5-4.
MEM52-CPP .
Detect and handle memory allocation
errors.
3 - Significant differences A15-
0-2, A15-2-
2, A15-3-3,
A15-5-3
MEM53-CPP . Explicitly construct and
destruct objects when manually
managing object lifetime.
4 - Rejected A18-5-2 Explicit
use of operators
new and delete is
prohibited.
Managing
object lifetime also
covered by A18-5-
1, A18-5-3.
MEM54-CPP . Provide placement new
with properly aligned pointers to
sufficient storage capacity .
2 - Small differences A18-5-10
MEM55-CPP .
Honor replacement dynamic storage
management requirements.
2 - Small differences A18-5-9
MEM56-CPP . Do not store an already-
owned pointer value in an unrelated
smart pointer.
2 - Small differences A20-8-1
MEM57-CPP . Avoid using default
operator new for over-aligned types.
4 - Rejected Current approach
is to use managed
memory objects,
which does not
allow to work on
a raw storage, but
on a type storage,
thus no need for
this rule.
FIO50-CPP . Do not alternately input
and output from a file stream without
an intervening positioning call.
2 - Small differences A27-0-3
FIO51-CPP . Close files when they are
no longer needed.
4 - Rejected Usage of RAII
solves the problem
and is
recommended,
see: A15-1-4, A18-
5-2.
FIO30-C. Exclude user input from
format strings.
2 - Small differences A27-0-1
FIO32-C. Do not perform operations on
devices that are only appropriate for
files.
4 - Rejected Non-generic
rule affecting only
particular file types
on some operating
systems.
FIO34-C. Distinguish between
characters read from a file and EOF or
WEOF .
4 - Rejected M27-0-1 The C IO library is
not used.
FIO37-C. Do not assume that fgets()
or fgetws() returns a nonempty string
when successful.
4 - Rejected M27-0-1 The C IO library is
not used.
FIO38-C. Do not copy a FILE object. 4 - Rejected M27-0-1 The C IO library is
not used.
FIO39-C. Do not alternately input
and output from a stream without an
intervening flush or positioning call.
2 - Small differences A27-0-3
FIO40-C. Reset strings on fgets() or
fgetws() failure.
4 - Rejected M27-0-1 The C IO library is
not used.
FIO41-C. Do not call getc(), putc(),
getwc(), or putwc() with a stream
argument that has side effects.
4 - Rejected M27-0-1 The C IO library is
not used.
FIO42-C. Close files when they are no
longer needed.
4 - Rejected M27-0-1 The C IO library is
not used.
FIO44-C. Only use values for fsetpos()
that are returned from fgetpos().
4 - Rejected M27-0-1 The C IO library is
not used.
FIO45-C. Avoid TOCTOU race
conditions while accessing files.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future. See also
CP .2
FIO46-C. Do not access a closed file. 4 - Rejected M27-0-1 The C IO library is
not used.
FIO47-C. Use valid format strings. 4 - Rejected M27-0-1 The C IO library is
not used.
ERR30-C. Set errno to zero before
calling a library function known to
set errno, and check errno only after
the function returns a value indicating
failure.
4 - Rejected Use of the errno
is prohibited, see:
M19-3-1.
ERR32-C. Do not rely on indeterminate
values of errno.
4 - Rejected Use of the errno
is prohibited, see:
M19-3-1.
ERR33-C. Detect and handle standard
library errors.
3 - Small differences M0-3-2,
A15-0-3
ERR34-C. Detect errors when
converting a string to a number.
2 - Small differences A18-0-2
ERR50-CPP . Do not abruptly terminate
the program.
2 - Small differences A15-5-2,
A15-5-3
ERR51-CPP . Handle all exceptions. 2 - Small differences A15-3-3,
A15-5-3
ERR52-CPP . Do not use setjmp() or
longjmp().
2 - Small differences M17-0-5
ERR53-CPP . Do not reference base
classes or class data members in a
constructor or destructor function-try-
block handler.
3 - Significant differences M15-3-3 Use of function-try-
blocks is anyway
not recommended.
See: A15-3-5.
ERR54-CPP . Catch handlers should
order their parameter types from most
derived to least derived.
2 - Small differences M15-3-6,
M15-3-7
ERR55-CPP . Honor exception
specifications.
3 - Significant differences A15-4-2 Use of
dynamic exception
specification
is prohibited, see:
A15-
4-1. The noexcept
specifier should be
used instead.
ERR56-CPP . Guarantee exception
safety .
2 - Small differences A15-0-2
ERR57-CPP . Do not leak resources
when handling exceptions.
3 - Significant differences A15-
0-2, A15-1-
2, A15-1-4
ERR58-CPP . Handle all exceptions
thrown before main() begins executing.
2 - Small differences A15-2-1
ERR59-
CPP . Do not throw an exception across
execution boundaries.
2 - Small differences A15-1-5
ERR60-CPP . Exception objects must
be nothrow copy constructible.
3 - Significant differences A15-5-3
ERR61-CPP . Catch exceptions by
lvalue reference.
2 - Small differences A15-3-5
ERR62-
CPP . Detect errors when converting a
string to a number.
2 - Small differences A18-0-2
OOP50-CPP . Do not invoke
virtual functions from constructors or
destructors.
2 - Small differences M12-1-1
OOP51-CPP . Do not slice derived
objects.
2 - Small differences A12-8-6,
A15-3-5
OOP52-CPP . Do not
delete a polymorphic object without a
virtual destructor.
2 - Small differences A12-4-1,
A12-4-2
OOP53-CPP .
Write constructor member initializers in
the canonical order.
2 - Small differences A8-5-1
OOP54-CPP . Gracefully handle self-
copy assignment.
2 - Small differences A12-8-5
OOP55-CPP . Do not use
pointer-to-member operators to access
nonexistent members.
2 - Small differences A5-5-1
OOP56-CPP . Honor replacement
handler requirements.
3 - Significant differences A18-
5-5, A15-5-
2, A15-5-3,
A15-4-1
std::terminate and
std::unexpected
handler forbidden,
std::new_handler
comments added.
OOP57-CPP . Prefer special member
functions and overloaded operators to
C Standard Library functions.
2 - Small differences A12-0-2
OOP58-CPP . Copy operations must
not mutate the source object.
2 - Small differences A12-8-1
CON50-CPP . Do not destroy a mutex
while it is locked.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON51-CPP . Ensure actively held
locks are released on exceptional
conditions.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON52-CPP . Prevent data races
when accessing bit-fields from multiple
threads.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON53-CPP . Avoid deadlock by
locking in a predefined order.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON54-CPP . Wrap functions that can
spuriously wake up in a loop.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON55-CPP . Preserve thread safety
and liveness when using condition
variables.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON56-CPP . Do not speculatively lock
a non-recursive mutex that is already
owned by the calling thread.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON33-C. Avoid race conditions when
using library functions.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON37-C. Do not call signal() in a
multithreaded program
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
CON40-C. Do not refer to an atomic
variable twice in an expression.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON41-C. Wrap functions that can fail
spuriously in a loop.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON43-C. Do not allow data races in
multithreaded code.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
MSC33-C. Do not pass invalid data to
the asctime() function.
4 - Rejected Use of time
handling functions
of <ctime>
is prohibited, see:
M18-0-4.
MSC38-C. Do not treat a predefined
identifier as an object if it might only be
implemented as a macro.
4 - Rejected Error indicator
errno, setjmp() and
variadic arguments
shall not be used,
see: M19-3-1,
M17-0-5, A8-4-1.
MSC39-C. Do not call va_arg() on a
va_list that has an indeterminate value.
4 - Rejected Use of
variadic arguments
is prohibited, see:
A8-4-1.
MSC40-C. Do not violate constraints. 2 - Small differences A1-1-1
MSC50-CPP . Do not use std::rand() for
generating pseudorandom numbers.
2 - Small differences A26-5-1
MSC51-CPP . Ensure your random
number generator is properly seeded.
2 - Small differences A26-5-2
MSC52-CPP . Value-returning functions
must return a value from all exit paths.
2 - Small differences A8-4-2
MSC53-CPP . Do not return from a
function declared [[noreturn]].
2 - Small differences A7-6-1
MSC54-CPP . A signal handler must be
a plain old function.
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
FLP30-C. Do not use floating-point
variables as loop counters.
2 - Small differences A6-5-2
FLP32-C. Prevent or detect domain
and range errors in math functions.
2 - Small differences A0-4-4
FLP34-C. Ensure that floating-point
conversions are within range of the
new type.
3 - Significant differences M5-0-5, M5-
0-6, M5-0-7
FLP36-C. Preserve precision when
converting integral values to floating-
point type.
3 - Significant differences M5-0-5, M5-
0-6, M5-0-7
FLP37-C. Do not
use object representations to compare
floating-point values.
2 - Small differences M3-9-3
ENV30-C. Do not modify the object
referenced by the return value of
certain functions.
2 - Small differences M18-
0-3, M18-0-
4, A18-0-3,
A17-1-1
Listed functions
are prohibited by
separate rules.
ENV31-C. Do not rely
on an environment pointer following an
operation that may invalidate it.
4 - Rejected In
general, a project
shall not rely on
environment-
specific
implementations.
ENV32-C. All exit handlers must return
normally .
3 - Significant differences A15-5-2,
A15-5-3
ENV33-C. Do not call system(). 2 - Small differences Covered by M18-0-
3
ENV34-C. Do
not store pointers returned by certain
functions.
3 - Significant differences A18-0-3,
M19-3-1
SIG31-C. Do not access shared
objects in signal handlers.
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
SIG34-C. Do not call signal() from
within interruptible signal handlers.
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
SIG35-C. Do not
return from a computational exception
signal handler.
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
PRE30-C. Do
not create a universal character name
through concatenation.
4 - Rejected Forbidden by A2-3-
1.
PRE31-
C. Avoid side effects in arguments to
unsafe macros.
3 - Significant differences Defining function-
like macros
is prohibited, see:
A16-0-1.
PRE32-C. Do not use preprocessor
directives in invocations of function-like
macros.
Defining function-
like macros
is prohibited, see:
A16-0-1.
Table B.4: SEI CERT C++
B.5 Traceability to C++ Core Guidelines
The following table demonstrates the traceability to C++ Core Guidelines [11]. This is
not considered as a reproduction, but a mean to compare the two standards.
Note that the copyright of C++ Core Guidelines allows a derivative work anyway .
C++ Core Guidelines Rule: Relation type: Related
rule:
Comment:
P .1: Express ideas directly in code. 4 - Rejected The rule is vague.
P .2: Write in ISO Standard C++. 2 - Small differences A0-4-3
P .3: Express intent. 4 - Rejected The rule is vague.
P .4: Ideally , a program should be
statically type safe.
3 - Significant differences The rule is covered
by: A5-2-1, A5-2-
2, A5-2-4, M5-2-
12, A8-5-2, A9-5-1
P .5: Prefer compile-time checking to
run-time checking.
3 - Significant differences M0-3-1
P .6: What cannot be checked at
compile time should be checkable at
run time.
3 - Significant differences A0-1-2, M0-
3-2
P .7: Catch run-time errors early . 3 - Significant differences A0-
1-2, M0-3-2,
A5-2-5, A15-
0-4, A15-0-5
P .8: Don’t leak any resources. 3 - Significant differences A18-
5-1, A18-5-
2, A15-1-4
P .9: Don’t waste time or space. 3 - Significant differences M0-1-1, A0-
1-1, M0-1-8,
M0-1-9
P .10: Prefer immutable data to mutable
data.
2 - Small differences A7-1-1
P .11: Encapsulate messy constructs,
rather than spreading through the
code.
4 - Rejected The rule is vague.
I.1: Make interfaces explicit. 4 - Rejected The rule is vague.
I.2 Avoid global variables. 3 - Significant differences A3-3-2 A3-3-2 covers only
the initialization of
global objects.
I.3: Avoid singletons. 3 - Significant differences A3-3-2 A3-3-2 covers only
the initialization of
static objects.
I.4: Make interfaces precisely and
strongly typed.
2 - Small differences A8-4-14 -
I.5: State preconditions (if any). 4 - Rejected The rule is vague.
I.6: Prefer Expects() for expressing
preconditions.
4 - Rejected Expects() is not
part of Language
Standard.
I.7: State postconditions. 4 - Rejected The rule is vague.
I.8: Prefer Ensures() for expressing
postconditions.
4 - Rejected Ensures() is not
part of Language
Standard.
I.9:
If an interface is a template, document
its parameters using concepts.
3 - Significant differences A14-1-1
I.10: Use exceptions to signal a failure
to perform a required task.
2 - Small differences A15-0-1
I.11: Never transfer ownership by a raw
pointer (T*).
2 - Small differences A8-4-12
I.12: Declare a pointer that must not be
null as not_null.
4 - Rejected The not_null is not
part of Language
Standard.
I.13: Do not pass an array as a single
pointer.
2 - Small differences M5-2-12
I.22: Avoid complex initialization of
global objects.
2 - Small differences A3-3-2 Intent
of the rule achieved
by restriction to
constant-initialized
objects.
I.23: Keep the number of function
arguments low.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
code metrics, see:
A1-4-1.
I.24: Avoid adjacent unrelated
parameters of the same type.
4 - Rejected Design rule,
requiring case-by-
case reasoning to
apply .
I.25: Prefer abstract classes as
interfaces to class hierarchies.
2 - Small differences A10-4-1
I.26: If you want a cross-compiler ABI,
use a C-style subset.
2 - Small differences M1-0-2 -
F .1: “Package” meaningful operations
as carefully named functions.
5 - Not yet analyzed - -
F .2: A function should perform a single
logical operation.
5 - Not yet analyzed - -
F .3: Keep functions short and simple. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
code metrics, see:
A1-4-1.
F .4: If a function may have to be
evaluated at compile time, declare it
constexpr.
2 - Small differences A7-1-2
F .5: If a function is very small and time-
critical, declare it inline.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
code metrics, see:
A1-4-1.
F .6: If your function may not throw,
declare it noexcept.
2 - Small differences A15-4-4
F .7: For general use, take T* or T&
arguments rather than smart pointers.
2 - Small differences A8-4-11 Added as a
reference.
F .8: Prefer pure functions. 4 - Rejected - There is no need
for a new rule.
F .9: Unused parameters should be
unnamed.
2 - Small differences A0-1-4, A0-
1-5
F .15: Prefer simple and conventional
ways of passing information.
2 - Small differences A8-4-3
F .16: For “in” parameters, pass
cheaply-copied types by value and
others by reference to const.
2 - Small differences A8-4-7
F .17: For “in-out” parameters, pass by
reference to non-const.
2 - Small differences A8-4-9
F .18: For “consume” parameters, pass
by X&& and std::move the parameter.
2 - Small differences A8-4-5
F .19: For “forward” parameters, pass
by TP&& and only std::forward the
parameter.
2 - Small differences A8-4-6
F .20: For “out” output values, prefer
return values to output parameters.
2 - Small differences A8-4-8
F .21: T o return multiple “out” values,
prefer returning a tuple or struct.
3 - Significant differences A8-4-4 Prefer to return as
a tuple.
F .22: Use T* or owner<T*> to
designate a single object.
3 - Significant differences M5-2-12 The owner<T*> is
not
part of Language
Standard.
F .23: Use a not_null<T> to indicate that
“null” is not a valid value.
4 - Rejected The not_null<T> is
not
part of Language
Standard.
F .24: Use a span<T> or a span_p<T>
to designate a half-open sequence.
4 - Rejected Neither
the span<T> nor
the span_p<T> are
part of Language
Standard.
F .25:
Use a zstring or a not_null<zstring> to
designate a C-style string.
4 - Rejected Neither
the zstring nor the
not_null<zstring>
are
part of Language
Standard.
F .26: Use a unique_ptr<T> to transfer
ownership where a pointer is needed.
2 - Small differences A20-8-2
F .27: Use a shared_ptr<T> to share
ownership.
2 - Small differences A20-8-3
F .60: Prefer T* over T& when no
argument is a valid option.
3 - Significant differences A8-4-10
F .42: Return a T* to indicate a position
(only).
3 - Significant differences M5-
0-15, M5-0-
16, M5-0-17,
M5-0-18
F .43: Never (directly or indirectly)
return a pointer or a reference to a local
object.
2 - Small differences M7-5-2 Added as a note to
this rule.
F .44: Return a T& when copy is
undesirable and returning no object
isn’t needed.
3 - Significant differences A9-3-1 Do not return non-
const reference to
private fields.
F .45: Don’t return a T&&. 2 - Small differences M7-5-2 Added as
a reference to this
rule.
F .46: int is the return type for main(). 2 - Small differences A0-4-3 Added as
a reference to this
rule.
F .47: Return T& from assignment
operators.
2 - Small differences A13-2-1 Added as
a reference to this
rule.
F .50: Use a lambda when a function
won’t do (to capture local variables, or
to write a local function).
4 - Rejected Design
principle. Prefer
using lambda over
functions while
variables capture is
required or it is
defined in a local
scope.
F .51: Where there is a choice, prefer
default arguments over overloading.
4 - Rejected Design
principle. Prefer
default arguments
over overloading.
F .52: Prefer capturing by reference
in lambdas that will be used locally ,
including passed to algorithms.
4 - Rejected This rule
is too specific and
this is a matter of
ownership, not only
lambda.
F .53: Avoid capturing by reference in
lambdas that will be used nonlocally ,
including returned, stored on the heap,
or passed to another thread.
2 - Small differences A5-1-4
F .54: If you capture this, capture all
variables explicitly (no default capture).
3 - Significant differences A5-1-2 AUTOSAR C++
Coding Guidelines
prohibits implicit
variables capturing
into a lambda
expression.
F .55: Don’t use va_arg arguments. 2 - Small differences A8-4-1 Added as
a reference to this
rule.
C.1: Organize related data into
structures (structs or classes).
4 - Rejected Design
principle. There is
no need for a new
rule..
C.2: Use class if the class has
an invariant; use struct if the data
members can vary independently .
3 - Significant differences Class shall be used
for all non-POD
types (see: A11-
0-1), and a struct
for types defined in
A11-0-2.
C.3: Represent the distinction between
an interface and an implementation
using a class.
4 - Rejected This rule is vague.
C.4: Make a function a member
only if it needs direct access to the
representation of a class.
2 - Small differences M9-3-3
C.5: Place helper functions in the same
namespace as the class they support.
5 - Not yet analyzed - -
C.7: Don’t define a class or enum and
declare a variable of its type in the
same statement.
2 - Small differences A7-1-9
C.8: Use class rather than struct if any
member is non-public.
2 - Small differences M11-0-1,
A11-0-1
C.9: Minimize exposure of members. 3 - Significant differences M9-3-1, A9-
3-1, M11-0-1
C.10 Prefer concrete types over class
hierarchies.
4 - Rejected This rule is vague.
Concrete types
and class
hierarchies
are highly context
dependent.
C.11: Make concrete types regular. 4 - Rejected This rule is vague.
“Concrete types”
has no technical
meaning.
C.20: If you can avoid defining default
operations, do.
2 - Small differences A12-0-1 Following “the rule
of
zero” is permitted if
no special member
functions need to
be defined.
C.21: If you define or =delete any
default operation, define or =delete
them all.
2 - Small differences A12-0-1
C.22: Make default operations
consistent.
2 - Small differences A12-1-1,
A12-8-1
C.30: Define a destructor if a class
needs an explicit action at object
destruction.
4 - Rejected Design principle.
Destructor shall be
defined only if a
class needs
an explicit action at
object destruction.
C.31: All resources acquired by a
class must be released by the class’s
destructor.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
C.32: If a class has a raw pointer (T*)
or reference (T&), consider whether it
might be owning.
4 - Rejected Memory managing
objects are
recommended.
C.33: If a class has an owning pointer
member, define a destructor.
4 - Rejected Memory managing
objects are
recommended.
C.34: If a class has an owning
reference member, define a destructor.
4 - Rejected Memory managing
objects are
recommended.
C.35: A base class destructor
should be either public and virtual, or
protected and nonvirtual.
2 - Small differences A12-4-1
C.36: A destructor may not fail. 2 - Small differences A15-5-1
C.37: Make destructors noexcept. 2 - Small differences A15-5-1
C.40: Define a constructor if a class
has an invariant.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.41: A constructor should create a
fully initialized object.
2 - Small differences A15-2-2,
A12-1-1, A8-
5-0
C.42: If a constructor cannot construct
a valid object, throw an exception.
2 - Small differences A15-2-2
C.43: Ensure that a class has a default
constructor.
4 - Rejected This rule is vague.
C.44: Prefer default constructors to be
simple and non-throwing.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.45:
Don’t define a default constructor that
only initializes data members; use in-
class member initializers instead.
2 - Small differences A12-1-3,
A12-7-1
C.46: By default, declare single-
argument constructors explicit.
2 - Small differences A12-1-4
C.47: Define and initialize member
variables in the order of member
declaration.
2 - Small differences A8-5-1
C.48: Prefer in-class initializers to
member initializers in constructors for
constant initializers.
3 - Significant differences A12-1-3 AUTOSAR C++
Coding Guidelines
states that NSDMI
shall not be mixed
with
member initializer
list of constructors,
see: A12-1-2.
C.49: Prefer initialization to
assignment in constructors.
2 - Small differences A12-6-1
C.50: Use a factory function if
you need “virtual behavior” during
initialization.
3 - Significant differences M12-1-1 Added
as a reference to
this rule, as it has
a good example
of virtual behaviour
during initialization.
C.51: Use delegating constructors
to represent common actions for all
constructors of a class.
2 - Small differences A12-1-5
C.52: Use inheriting constructors to
import constructors into a derived class
that does not need further explicit
initialization.
2 - Small differences A12-1-6
C.60: Make copy assignment non-
virtual, take the parameter by const&,
and return by non-const&.
2 - Small differences A10-3-5,
A13-2-1
C.61: A copy operation should copy . 2 - Small differences A12-8-1,
A12-8-2
C.62: Make copy assignment safe for
self-assignment.
2 - Small differences A12-8-5
C.63: Make move assignment non-
virtual, take the parameter by &&, and
return by non-const&.
2 - Small differences A10-3-5,
A13-2-1
C.64: A move operation should move
and leave its source in a valid state.
2 - Small differences A12-8-1,
A12-8-4
C.65: Make move assignment safe for
self-assignment.
2 - Small differences A12-8-5
C.66: Make move operations
noexcept.
2 - Small differences A15-5-1
C.67: A base class should suppress
copying, and provide a virtual clone
instead if copying” is desired.
2 - Small differences A12-8-6
C.80: Use =default if you have to
be explicit about using the default
semantics.
2 - Small differences A12-7-1
C.81: Use =delete when you want
to disable default behavior (without
wanting an alternative).
2 - Small differences A12-0-1,
A12-8-6
C.82: Don’t call virtual functions in
constructors and destructors.
2 - Small differences M12-1-1
C.83: For value-like types, consider
providing a noexcept swap function.
3 - Significant differences A12-8-2 The swap
function is explicitly
recommended
for copy and move
assignment
operators only .
C.84: A swap function may not fail. 2 - Small differences A15-5-1
C.85: Make swap noexcept. 2 - Small differences A15-5-1
C.86: Make
== symmetric with respect to operand
types and noexcept.
2 - Small differences A13-5-5 -
C.87: Beware of == on base classes. 2 - Small differences A13-5-5 This rule
is implicitly covered
by adhering to A13-
5-5.
C.89: Make a hash noexcept. 2 - Small differences A18-1-6
C.120: Use class
hierarchies to represent concepts with
inherent hierarchical structure (only).
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.121: If a base class is used as an
interface, make it a pure abstract class.
2 - Small differences AUTOSAR C++
Coding
Guidelines defines
an interface class
definition,
see: Interface-
Class.
C.122: Use abstract classes as
interfaces when complete separation
of interface and implementation is
needed.
2 - Small differences A10-4-1
C.126: An abstract class typically
doesn’t need a constructor.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.127: A class with a virtual function
should have a virtual or protected
destructor.
2 - Small differences A12-4-1
C.128: Virtual functions should specify
exactly one of virtual, override, or final.
2 - Small differences A10-3-1
C.129: When
designing a class hierarchy , distinguish
between implementation inheritance
and interface inheritance.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.130: Redefine or prohibit copying
for a base class; prefer a virtual clone
function instead.
2 - Small differences A12-8-6
C.131: Avoid trivial getters and setters. 4 - Rejected All members
in non-POD types
shall be private.
C.132: Don’t make a function virtual
without reason.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.133: Avoid protected data. 3 - Significant differences M11-0-1 All members
in non-POD types
shall be private.
C.134: Ensure all non-const data
members have the same access level.
2 - Small differences M11-0-1,
A11-0-2
C.135: Use multiple inheritance to
represent multiple distinct interfaces.
2 - Small differences A10-1-1
C.136: Use multiple inheritance to
represent the union of implementation
attributes.
4 - Rejected Multiple
implementation
inheritance is
prohibited
by AUTOSAR C++
Coding Guidelines,
it allows only
multiple interface
inheritance.
C.137: Use virtual bases to avoid
overly general base classes.
4 - Rejected It is allowed to use
virtual inheritance
only in a diamond
hierarchy , see:
M10-1-1, M10-1-2.
C.138: Create an overload set for a
derived class and its bases with using.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.139: Use final sparingly . 3 - Significant differences A12-4-2 Class shall
be declared final if
it has a non-virtual
destructor.
C.140: Do not provide different default
arguments for a virtual function and an
overrider.
2 - Small differences M8-3-1
C.145: Access polymorphic objects
through pointers and references.
3 - Significant differences A12-8-6,
A15-3-5
Functionalities that
could lead to slicing
are prohibited.
C.146: Use dynamic_cast where class
hierarchy navigation is unavoidable.
2 - Small differences A5-2-1
C.147: Use dynamic_cast to a
reference type when failure to find the
required class is considered an error.
4 - Rejected The dynamic_cast
should not be used,
see: A5-2-1.
C.148: Use dynamic_cast to a pointer
type when failure to find the required
class is considered a valid alternative.
4 - Rejected The dynamic_cast
should not be used,
see: A5-2-1.
C.149: Use unique_ptr or shared_ptr
to avoid forgetting to delete objects
created using new.
2 - Small differences A18-5-2
C.150: Use
make_unique() to construct objects
owned by unique_ptrs.
2 - Small differences A20-8-5
C.151: Use
make_shared() to construct objects
owned by shared_ptrs.
2 - Small differences A20-8-6
C.152: Never assign a pointer to an
array of derived class objects to a
pointer to its base.
2 - Small differences M5-2-12
C.153: Prefer virtual function to
casting.
3 - Significant differences M5-2-2, M5-
2-3, A5-2-1
C.160: Define operators primarily to
mimic conventional usage.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.161: Use nonmember functions for
symmetric operators.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.162: Overload operations that are
roughly equivalent.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.163: Overload only for operations
that are roughly equivalent.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.164: Avoid conversion operators. 2 - Small differences A13-5-3
C.165: Use using for customization
points.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
C.166: Overload unary & only as part
of a system of smart pointers and
references.
3 - Significant differences M5-3-3 The unary
& operator shall not
be overloaded.
C.167:
Use an operator for an operation with
its conventional meaning.
4 - Rejected Design
principle; There is
no need for a new
rule.
C.168: Define overloaded operators in
the namespace of their operands.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.170: If you feel like overloading a
lambda, use a generic lambda.
4 - Rejected Design
principle; There is
no need for a
new rule. Creating
generic lambda
expressions is
allowed, see: A7-1-
5.
C.180: Use unions to save memory . 4 - Rejected Unions shall not be
used, see: A9-5-1.
C.181: Avoid “naked” unions. 2 - Small differences A9-5-1
C.182: Use anonymous unions to
implement tagged unions.
2 - Small differences A9-5-1 Tagged
unions allowed as
an exception, but
only as POD.
C.183: Don’t use a union for type
punning.
4 - Rejected Unions shall not be
used, see: A9-5-1.
Enum.1: Prefer enumerations over
macros.
3 - Significant differences A16-0-1 Usage of macros is
prohibited.
Enum.2:
Use enumerations to represent sets of
related named constants.
2 - Small differences A7-2-5
Enum.3: Prefer class enums over
“plain” enums.
2 - Small differences A7-2-3
Enum.4: Define operations on
enumerations for safe and simple use.
4 - Rejected Design
principle. There is
no need for a new
rule.
Enum.5: Don’t use ALL_CAPS for
enumerators.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
Enum.6: Avoid unnamed
enumerations.
3 - Significant differences A7-2-3 Enum classes shall
be used instead of
enums; it is not
allowed to declare
unnamed enum
class.
Enum.7: Specify the underlying type of
an enumeration only when necessary .
4 - Rejected AUTOSAR C++
Coding Guidelines
forces
a programmer to
specify the
underlying
base type explicitly ,
as only fixed-width
numeric types shall
be used. See: A3-
9-1.
Enum.8: Specify enumerator values
only when necessary .
3 - Significant differences A7-2-4 It is defined how
enumerators
values should be
specified.
R.1: Manage resources automatically
using resource handles and RAII
(Resource Acquisition Is Initialization).
4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
rules for coding
patterns. Note that
usage of RAII is
recommended,
see: A15-1-4, A18-
5-2.
R.2: In interfaces, use raw pointers to
denote individual objects (only).
2 - Small differences M5-2-12
R.3: A raw pointer (a T*) is non-
owning.
4 - Rejected Ownership is
covered by
memory managing
objects, see: A18-
5-2.
R.4: A raw reference (a T&) is non-
owning.
4 - Rejected Ownership is
covered by
memory managing
objects, see: A18-
5-2.
R.5: Don’t heap-allocate
unnecessarily .
2 - Small differences A18-5-8
R.6: Avoid non-const global variables. 3 - Significant differences A3-3-2 A3-3-2 covers only
the initialization of
global objects.
R.10: Avoid malloc() and free(). 2 - Small differences A18-5-1
R.11: Avoid calling new and delete
explicitly .
2 - Small differences A18-5-2
R.12: Immediately give the result of
an explicit resource allocation to a
manager object.
2 - Small differences A18-5-2
R.13: Perform at most one
explicit resource allocation in a single
expression statement.
2 - Small differences A5-0-1
R.14: ??? array vs. pointer parameter. 2 - Small differences M5-2-12
R.15: Always overload matched
allocation/deallocation pairs.
3 - Significant differences A18-5-3
R.20: Use unique_ptr or shared_ptr to
represent ownership.
2 - Small differences A20-8-2,
A20-8-3
R.21: Prefer
unique_ptr over shared_ptr unless you
need to share ownership.
2 - Small differences A20-8-4
R.22: Use make_shared() to make
shared_ptrs.
2 - Small differences A20-8-6
R.23: Use make_unique() to make
unique_ptrs.
2 - Small differences A20-8-5
R.24: Use std::weak_ptr to break
cycles of shared_ptrs.
2 - Small differences A20-8-7
R.30: T ake
smart pointers as parameters only to
explicitly express lifetime semantics.
2 - Small differences A8-4-11
R.31: If you have non-std smart
pointers, follow the basic pattern from
std.
4 - Rejected There is no need
for a new rule.
Smart pointers are
a part of Language
Standard.
R.32: T ake a unique_ptr<widget>
parameter to express that a function
assumes ownership of a widget.
2 - Small differences A8-4-12
R.33: T ake a unique_ptr<widget>&
parameter to express that a function
reseats thewidget.
2 - Small differences A8-4-12
R.34: T ake a shared_ptr<widget>
parameter to express that a function is
part owner.
2 - Small differences A8-4-13
R.35: T ake a shared_ptr<widget>&
parameter to express that a function
might reseat the shared pointer.
2 - Small differences A8-4-13
R.36: T ake a
const shared_ptr<widget>& parameter
to express that it might retain a
reference count to the object ???.
2 - Small differences A8-4-13
R.37: Do not pass a pointer or
reference obtained from an aliased
smart pointer.
2 - Small differences A8-4-11,
A18-5-2
Added as a
reference in these
rules and a note in
A8-4-11.
ES.1: Prefer the standard library to
other libraries and to “handcrafted
code”.
4 - Rejected Design
principle; There is
no need for a new
rule.
ES.2: Prefer suitable abstractions to
direct use of language features.
4 - Rejected Design
principle; There is
no need for a new
rule.
ES.5: Keep scopes small. 2 - Small differences M3-4-1
ES.6: Declare names in for-statement
initializers and conditions to limit
scope.
2 - Small differences M3-4-1 As an exeception
from the A7-
1-7, it is allowed to
declare variables in
for-statement
initializer.
ES.7: Keep common and local names
short, and keep uncommon and
nonlocal names longer.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
ES.8: Avoid similar-looking names. 2 - Small differences M2-10-1
ES.9: Avoid ALL_CAPS names. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
ES.10: Declare one name (only) per
declaration.
2 - Small differences A7-1-7
ES.11: Use auto to avoid redundant
repetition of type names.
3 - Significant differences A7-1-5 It is
not recommended
to use the auto
specifier, but it is
allowed.
ES.12: Do not reuse names in nested
scopes.
2 - Small differences A2-10-1
ES.20: Always initialize an object. 2 - Small differences A8-5-0
ES.21: Don’t introduce a variable (or
constant) before you need to use it.
2 - Small differences M3-4-1
ES.22: Don’t declare a variable until
you have a value to initialize it with.
2 - Small differences M3-4-1, A8-
5-0
ES.23: Prefer the {} initializer syntax. 2 - Small differences A8-5-2
ES.24: Use a unique_ptr<T> to hold
pointers.
3 - Significant differences A18-
5-2, A15-1-
4, A18-1-3
AUTOSAR C++
Coding Guidelines
does not force a
programmer to use
std::unique_ptr, it is
just highly
recommended
within examples
and rationales.
ES.25: Declare an object const or
constexpr unless you want to modify its
value later on.
2 - Small differences A7-1-1
ES.26: Don’t use a variable for two
unrelated purposes.
4 - Rejected This rule is vague.
“Unrelated” is
highly context
dependent.
ES.27: Use std::array or stack_array
for arrays on the stack.
3 - Significant differences A18-1-1 C-style arrays shall
not be used, and
it is recommended
to use std::array
instead.
ES.28: Use lambdas
for complex initialization, especially of
const variables.
4 - Rejected Design
principle. There is
no need for a new
rule.
ES.30: Don’t use macros for program
text manipulation.
2 - Small differences A16-0-1 Usage of macros is
prohibited.
ES.31: Don’t use macros for constants
or “functions”.
2 - Small differences A16-0-1 Usage of macros is
prohibited.
ES.32: Use ALL_CAPS for all macro
names.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
ES.33: If you must use macros, give
them unique names.
2 - Small differences M2-10-1
ES.34: Don’t define a (C-style) variadic
function.
2 - Small differences A8-4-1
ES.70: Prefer a switch-statement to an
if-statement when there is a choice.
4 - Rejected Design principle;
The switch
statement
shall have at least
two case-clauses,
distinct from the
default label. See:
A6-4-1.
ES.71: Prefer a range-for-statement to
a for-statement when there is a choice.
3 - Significant differences A6-5-1 It is recommended
to use range-based
for statement to
replace equivalent
for-statements.
ES.72: Prefer a for-statement to
a while-statement when there is an
obvious loop variable.
2 - Small differences A6-5-2
ES.73: Prefer a while-statement to a
for-statement when there is no obvious
loop variable.
3 - Significant differences A6-5-2 It is required that a
for-loop contains a
loop-counter.
ES.74: Prefer to declare a loop
variable in the initializer part of a for-
statement.
3 - Significant differences M3-4-1 It is required that
each identifier is
defined in a block
that minimizes its
visibility .
ES.75: Avoid do-statements. 2 - Small differences A6-5-3
ES.76: Avoid goto. 2 - Small differences A6-6-1
ES.78: Always end a non-empty case
with a break.
2 - Small differences M6-4-5
ES.79: Use default to handle common
cases (only).
4 - Rejected There is no need
for a new rule.
ES.84: Don’t (try to) declare a local
variable with no name.
2 - Small differences A6-2-2 -
ES.85: Make empty statements visible. 2 - Small differences M6-3-1, M6-
4-1, M6-4-1
ES.86: Avoid modifying loop control
variables inside the body of raw for-
loops.
2 - Small differences M6-5-3
ES.40: Avoid complicated expressions. 4 - Rejected This rule is vague.
Order of evaluation
is covered by A5-0-
1.
ES.41: If in doubt about operator
precedence, parenthesize.
2 - Small differences A5-2-6, M5-
0-2
ES.42: Keep use of pointers simple
and straightforward.
3 - Significant differences M5-0-
15, M5-0-16,
A5-2-5
’span’
is not covered as it
is not part of the
language standard.
ES.43: Avoid expressions with
undefined order of evaluation.
2 - Small differences A5-0-1
ES.44: Don’t depend on order of
evaluation of function arguments.
2 - Small differences A5-0-1
ES.45: Avoid "magic constants"; use
symbolic constants.
2 - Small differences A5-1-1
ES.46: Avoid lossy (narrowing,
truncating) arithmetic conversions.
2 - Small differences A4-7-1, M5-
0-6
ES.47: Use nullptr rather than 0 or
NULL.
2 - Small differences A4-10-1
ES.48: Avoid casts. 2 - Small differences A5-2-1, A5-
2-2, A5-2-3,
A5-2-4
ES.49: If you must use a cast, use a
named cast.
2 - Small differences A5-2-2
ES.50: Don’t cast away const. 2 - Small differences A5-2-3
ES.55: Avoid the need for range
checking.
3 - Significant differences A6-5-1 A6-5-1 only covers
for-loops
ES.56: Write std::move() only when
you need to explicitly move an object
to another scope.
3 - Significant differences A12-
8-3, A18-9-
2, A18-9-3
Vulnerabilities
of std::move() are
explained.
ES.60: Avoid new and delete outside
resource management functions.
2 - Small differences A18-5-2
ES.61: Delete arrays using delete[]
and non-arrays using delete.
2 - Small differences A18-5-3
ES.62: Don’t compare pointers into
different arrays.
2 - Small differences M5-0-16
ES.63: Don’t slice. 3 - Significant differences A12-8-6,
A15-3-5
The functionalities
that could
lead to slicing were
prohibited.
ES.64: Use the T{e} notation for
construction.
2 - Small differences A8-5-2
ES.65: Don’t dereference an invalid
pointer.
2 - Small differences A5-3-2
ES.100: Don’t mix signed and
unsigned arithmetic.
2 - Small differences M5-0-4, M5-
0-9
ES.101: Use unsigned types for bit
manipulation.
2 - Small differences M5-0-21
ES.102: Use signed types for
arithmetic.
3 - Significant differences A4-7-1, M5-
19-1
ES.103: Don’t overflow. 2 - Small differences A4-7-1
ES.104: Don’t underflow. 2 - Small differences A4-7-1
ES.105: Don’t divide by zero. 2 - Small differences A5-6-1
Per.1: Don’t optimize without reason. 4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.2: Don’t optimize prematurely . 4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.3: Don’t optimize something that’s
not performance critical.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.4: Don’t assume that complicated
code is necessarily faster than simple
code.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.5: Don’t assume that low-level
code is necessarily faster than high-
level code.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.6: Don’t make claims about
performance without measurements.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.7: Design to enable optimization. 4 - Rejected Design
principle; There is
no need for a new
rule.
Per.10: Rely on the static type system. 4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.11: Move computation from run
time to compile time
2 - Small differences A3-3-2, A7-
1-1, A7-1-2
Per.12: Eliminate redundant aliases 4 - Rejected This rule is
incomplete.
Per.13: Eliminate redundant
indirections
4 - Rejected This rule is
incomplete.
Per.14: Minimize the number of
allocations and deallocations
4 - Rejected This rule is
incomplete.
Per.15: Do not allocate on a critical
branch
4 - Rejected This rule is
incomplete.
Per.16: Use compact data structures 4 - Rejected This rule is
incomplete.
Per.18: Space is time 4 - Rejected This rule is
incomplete.
Per.19: Access memory predictably . 4 - Rejected Implementation
principle. There is
no need for a new
rule.
CP .1: Assume that your code will run
as part of a multi-threaded program.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .2: Avoid data races. 5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .3: Minimize explicit sharing of
writable data.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .4: Think in terms of tasks, rather
than threads.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .8: Don’t try to use volatile for
synchronization.
3 - Significant differences A2-11-1 Volatile keyword
forbidden.
CP .20: Use RAII, never plain
lock()/unlock().
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .21: Use std::lock() to acquire
multiple mutexes.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .22: Never call unknown code while
holding a lock (e.g., a callback).
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .23: Think of a joining thread as a
scoped container.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .24: Think of a detached thread as a
global container.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .25: Prefer gsl::raii_thread over
std::thread unless you plan to detach().
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .26: Prefer gsl::detached_thread
over std::thread if you plan to detach().
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .27: Use plain std::thread for
threads that detach based on a run-
time condition (only).
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .28: Remember to join scoped
threads that are not detach()ed.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .30: Do not pass pointers to local
variables to non-raii_threads.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .31: Pass small amounts of data
between threads by value, rather than
by reference or pointer.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
[CP .32: T o share ownership between
unrelated threads use shared_ptr.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .40: Minimize context switching. 5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .41: Minimize thread creation and
destruction.
55 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .42: Don’t wait without a condition. 5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .43: Minimize time spent in a critical
section.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .44: Remember to name your
lock_guards and unique_locks.
2 - Small differences A6-2-2 This is a special
case of the more
generic rule.
P .50: Define a mutex together with the
data it guards.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .60: Use a future to return a value
from a concurrent task.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .61: Use a async() to spawn a
concurrent task.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .100: Don’t
use lock-free programming unless you
absolutely have to.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .101: Distrust your
hardware/compiler combination.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .102: Carefully study the literature. 5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .110: Do not write your own double-
checked locking for initialization.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .111: Use a conventional pattern
if you really need double-checked
locking.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .200: Use volatile only to talk to non-
C++ memory .
3 - Significant differences A2-11-1 Volatile keyword
forbidden.
E.1: Develop an error-handling
strategy early in a design.
4 - Rejected Design
principle; There is
no need for a new
rule.
E.2: Throw an exception to signal that
a function can’t perform its assigned
task.
2 - Small differences A15-0-1
E.3: Use exceptions for error handling
only .
2 - Small differences A15-0-1
E.4: Design your error-handling
strategy around invariants.
4 - Rejected Design
principle; There is
no need for a new
rule.
E.5: Let a constructor establish an
invariant, and throw if it cannot.
2 - Small differences A15-2-2
E.6: Use RAII to prevent leaks. 4 - Rejected Design
principle; There is
no need for a new
rule.
E.7: State your preconditions. 4 - Rejected Design
principle; There is
no need for a new
rule.
E.8: State your postconditions. 4 - Rejected Design
principle; There is
no need for a new
rule.
E.12: Use noexcept when exiting
a function because of a throw is
impossible or unacceptable.
2 - Small differences A15-4-4
E.13: Never throw while being the
direct owner of an object.
3 - Significant differences A15-1-4 It is required to
release all
acquired resources
and objects before
a throw or a return
statement.
E.14: Use purpose-designed user-
defined types as exceptions (not built-
in types).
3 - Significant differences A15-1-1 It is
required that user-
defined exceptions
inherit
from std::exception
class.
E.15:
Catch exceptions from a hierarchy by
reference.
2 - Small differences A15-3-5
E.16: Destructors, deallocation, and
swap must never fail.
2 - Small differences A15-5-1
E.17: Don’t try to catch every
exception in every function.
2 - Small differences A15-3-2 AUTOSAR C++
Coding Guidelines
introduces checked
and unchecked
exceptions.
Whether an
exception should
be caught depends
if meaningful action
can be performed
in a given context.
E.18: Minimize the use of explicit
try/catch.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
E.19: Use a final_action object to
express cleanup if no suitable resource
handle is available.
4 - Rejected The
finally is not part of
the C++ Language
Standard.
E.25: If you can’t throw
exceptions, simulate RAII for resource
management.
3 - Rejected the RAII is a coding
pattern; There is no
need for
a new rule. On the
other hand, usage
of RAII
is recommended in
the example of the
A15-1-4.
E.26: If you can’t throw exceptions,
consider failing fast.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
E.27: If you can’t throw exceptions, use
error codes systematically .
4 - Rejected AUTOSAR C++
Coding Guidelines
does not force any
specific error
handling
mechanism. It
requires that every
error information
will be tested, see:
M0-3-2.
E.28: Avoid error handling based on
global state (e.g. errno).
2 - Small differences M19-3-1
Con.1: By default, make objects
immutable.
2 - Small differences A7-1-1
Con.2: By default, make member
functions const.
2 - Small differences M9-3-3
Con.3: By default, pass pointers and
references to consts.
2 - Small differences M7-1-2
Con.4: Use const to define objects
with values that do not change after
construction.
2 - Small differences A7-1-1
Con.5: Use constexpr for values that
can be computed at compile time.
2 - Small differences A7-1-2
T .1: Use templates to raise the level of
abstraction of code.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .2: Use templates to
express algorithms that apply to many
argument types.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .3: Use templates to express
containers and ranges.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .4: Use templates to express syntax
tree manipulation.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .5: Combine
generic and OO techniques to amplify
their strengths, not their costs.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .10: Specify concepts for all template
arguments.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .11: Whenever possible use standard
concepts.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .12: Prefer concept names over auto
for local variables.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .13: Prefer the shorthand notation for
simple, single-type argument
concepts.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .20: Avoid “concepts” without
meaningful semantics.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .21: Require a complete set of
operations for a concept.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .22: Specify axioms for concepts. 4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .23: Differentiate a refined concept
from its more general case by adding
new use patterns..
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .24: Use tag classes or traits to
differentiate concepts that differ only in
semantics..
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .25: Avoid complementary
constraints.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .26: Prefer to define concepts in
terms of use-patterns rather than
simple syntax.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .40: Use function objects to pass
operations to algorithms.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .41: Require only essential properties
in a template’s concepts.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .42: Use template aliases to simplify
notation and hide implementation
details.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .43: Prefer using over typedef for
defining aliases.
2 - Small differences A7-1-6
T .44: Use function templates to deduce
class template argument types (where
feasible).
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .46: Require template arguments to
be at least Regular or SemiRegular.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .47: Avoid
highly visible unconstrained templates
with common names.
4 - Rejected M17-0-2,
M17-0-3
This rule is vague.
"Highly visible" and
"common names"
have no technical
meaning.
T .48: If your compiler does not support
concepts, fake them with enable_if.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .49: Where possible, avoid type-
erasure.
4 - Rejected This rule
is incomplete. This
rule
is vague. "Where
possible" has no
technical meaning.
T .60: Minimize a template’s context
dependencies.
4 - Rejected This rule is vague.
T .61: Do not over-parameterize
members (SCARY).
2 - Small differences A14-1-1,
A14-7-1
T .62: Place non-dependent class
template members in a non-templated
base class.
2 - Small differences A14-5-2 -
T .65:
Use tag dispatch to provide alternative
implementations of a function.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .68: Use rather than () within
templates to avoid ambiguities.
2 - Small differences A8-5-2
T .69: Inside a template, don’t make
an unqualified nonmember function
call unless you intend it to be a
customization point.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .80: Do not naively templatize a class
hierarchy .
5 - Not yet analyzed - -
T .81: Do not mix hierarchies and
arrays.
2 - Small differences A5-0-4
T .83: Do not declare a member
function template virtual.
4 - Rejected There is
no need for a new
rule. Handled by a
compiler.
T .84: Use
a non-template core implementation to
provide an ABI-stable interface.
4 - Rejected Design
principle. There is
no need for a new
rule.
T .100: Use variadic templates when
you need a function that takes a
variable number of arguments of a
variety of types.
2 - Small differences A8-4-1
T .101: How to pass arguments to a
variadic template.
4 - Rejected This rule is
incomplete.
T .102: How to process arguments to a
variadic template.
4 - Rejected There is no need
for a new rule.
T .103: Don’t use variadic templates for
homogeneous argument lists.
4 - Rejected There is no need
for a new rule.
T .120: Use
template metaprogramming only when
you really need to.
4 - Rejected This rule is vague.
"When you really
need to" has no
technical meaning.
T .121: Use template
metaprogramming primarily to emulate
concepts.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .122: Use templates (usually template
aliases) to compute types at compile
time.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .123: Use constexpr functions to
compute values at compile time.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .124: Prefer to use standard-library
TMP facilities.
4 - Rejected There is no need
for a new rule.
T .125: If you need to go beyond the
standard-library TMP facilities, use an
existing library .
4 - Rejected This rule is vague.
"beyond the
standard-library
TMP facilities" has
no technical
meaning.
T .140: Name all operations with
potential for reuse.
4 - Rejected
T .141: Use an unnamed lambda if you
need a simple function object in one
place only .
3 - Significant differences A5-1-9 Only
forbids duplication
of identical lambda
expressions.
T .142: Use template variables to
simplify notation.
4 - Rejected This rule is
incomplete.
T .143: Don’t write unintentionally
nongeneric code.
5 - Not yet analyzed - -
T .144: Don’t specialize function
templates.
2 - Small differences A14-8-2
T .150: Check that a class matches a
concept using static_assert.
2 - Small differences A14-1-1
CPL.1: Prefer C++ to C. 2 - Small differences A17-1-1,
A18-0-1
CPL.2: If you must use C, use the
common subset of C and C++, and
compile the C code as C++.
4 - Rejected There is no need
for a new rule.
CPL.3: If you must use C for interfaces,
use C++ in the calling code using such
interfaces.
5 - Not yet analyzed - -
SF .1: Use a .cpp suffix for code
files and .h for interface files if your
project doesn’t already follow another
convention.
3 - Significant differences A3-1-2, A3-
1-3
For header file
names, AUTOSAR
C++ Coding
Guidelines allows
either “.h”, “.hpp” or
“.hxx” extension.
SF .2: A .h file may not contain
object definitions or non-inline function
definitions.
2 - Small differences A3-1-1
SF .3: Use .h files for all declarations
used in multiple source files.
2 - Small differences M3-2-2, A3-
3-1
SF .4: Include .h files before other
declarations in a file.
2 - Small differences M16-0-1
SF .5: A .cpp file must include the .h
file(s) that defines its interface.
5 - Not yet analyzed - -
SF .7: Don’t write using namespace in
a header file.
2 - Small differences M7-3-6
SF .8: Use #include guards for all .h
files.
2 - Small differences M16-2-3
SF .9: Avoid cyclic dependencies
among source files.
5 - Not yet analyzed - -
SF .21: Don’t use an
unnamed (anonymous) namespace in
a header.
2 - Small differences M7-3-3
SF .22: Use
an unnamed (anonymous) namespace
for all internal/nonexported entities.
5 - Not yet analyzed - -
SL.1: Use libraries wherever possible. 4 - Rejected Design
principle; There is
no need for a new
rule.
SL.2: Prefer the standard library to
other libraries.
4 - Rejected Design
principle; There is
no need for a new
rule.
SL.3: Do not add non-standard entities
to namespace std.
2 - Small differences A17-6-1
SL.con.1: Prefer using STL array or
vector instead of a C array .
2 - Small differences A18-1-1
SL.con.2: Prefer using STL vector by
default unless you have a reason to
use a different container.
4 - Rejected This rule is vague.
“have a reason to”
has no technical
meaning.
SL.str.1: Use std::string to own
character sequences
2 - Small differences A27-0-4
SL.io.50: Avoid endl. 5 - Not yet analyzed - -
T ype.1: Don’t use reinterpret_cast. 2 - Small differences A5-2-4
T ype.2:
Don’t use static_cast downcasts. Use
dynamic_cast instead.
2 - Small differences M5-2-2
T ype.3: Don’t use const_cast to cast
away const (i.e., at all).
2 - Small differences A5-2-3
T ype.4: Don’t
use C-style (T) expression casts that
would perform a static_cast downcast,
const_cast, or reinterpret_cast.
2 - Small differences A5-2-2
T ype.5: Don’t use a variable before it
has been initialized.
2 - Small differences A8-5-0
T ype.6: Always initialize a member
variable.
2 - Small differences A12-1-1
T ype.7: Avoid accessing members of
raw unions. Prefer variant instead.
2 - Small differences A9-5-1
T ype.8: Avoid reading from varargs
or passing vararg arguments. Prefer
variadic template parameters instead.
2 - Small differences A8-4-1
Bounds.1: Don’t use pointer arithmetic.
Use span instead.
2 - Small differences M5-0-15
Bounds.2: Only index into arrays using
constant expressions.
2 - Small differences A5-2-5
Bounds.3: No array-to-pointer decay . 2 - Small differences M5-2-12
Bounds.4: Don’t use standard library
functions and types that are not
bounds-checked.
5 - Not yet analyzed - -
NL.1: Don’t say in comments what can
be clearly stated in code.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.2: State intent in comments. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.3: Keep comments crisp. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.4: Maintain a consistent indentation
style.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.5 Don’t encode type information in
names.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.7: Make the length of a name
roughly proportional to the length of its
scope.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.8: Use a consistent naming style. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.9: Use ALL_CAPS for macro
names only .
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.10: Avoid CamelCase. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.15: Use spaces sparingly . 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.16: Use a conventional class
member declaration order.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.17: Use K&R-derived layout. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.18: Use C++-style declarator
layout.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.19: Avoid names that are easily
misread.
2 - Small differences M2-10-1
NL.20: Don’t place two statements on
the same line.
3 - Significant differences A7-1-7 It is required for
declarations only .
NL.21: Declare one name (only) per
declaration.
2 - Small differences A7-1-7
NL.25: Don’t use void as an argument
type.
5 - Not yet analyzed - -
NL.26: Use conventional const
notation.
5 - Not yet analyzed - -
Table B.5: C++ Core Guidelines
B.6 Traceability to ISO 26262
Each method in the tables referenced from the ISO 26262 standard is an entry that is
one of the following:
• consecutive – all methods shall be applied as recommended, but with different
recommendation level that depends on the ASIL level.
• alternative – an appropriate combination of methods shall be applied.
Consecutive methods are marked by a sequence number, e.g. 1, 2, 3. Alternative
entries are marked by a number followed by a letter, e.g. 1a, 1b, 1c.
This chapter traces mostly principles and recommendations from Section 8 (Software
unit design and implementation) of the Part 6 of the ISO 26262. The rest of the
document is not applicable to the AUTOSAR C++14 Coding Guidelines. Although
AUTOSAR C++14 Coding Guidelines contain multiple rules allocated to other work
products (e.g. software architectural design, verification), those are considered as
recommendations for doing review of such work products, not as a direct fulfillment of
ISO 26262 requirements.
Part 6: Product development at the software level
5: Initiation of product development at the software level
5.4: Requirements and recommendations
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1 an unambiguous definition 6 - Implemented [3, ISO/IEC
14882:2014],
A2-13-2,
A1-1-1
Syntax and semantics of the
language unambiguously
defined. Restrictions on
using conditionally-supported
or deprecated features.
2 the support for
embedded real time software
and runtime error handling
6 - Implemented A15-0-1,
A15-0-4,
A15-0-5,
A15-0-6,
A15-0-7,
A15-0-8,
A18-5-5,
A18-5-6,
A18-5-7
Introduction of Checked and
Unchecked Exceptions.
Usage of exceptions
limited only to error handling.
Additional requirements on
toolchain support for memory
management and exceptions
handling.
3 the support for modularity ,
abstraction and structured
constructs
6 - Implemented A8-4-14,
A10-0-1,
A10-0-2,
A10-4-1
Recommendations on which
constructs to use to increase
software reusability and hide
implementation details.
Table B.6: The criteria that shall be considered when selecting a suitable modeling or
programming language. Paragraph 5.4.6 from [5].
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1a Enforcement of low
complexity
6 - Implemented A1-4-1 Requirements on code metrics.
Plenty of AUTOSAR
C++14 Coding Guidelines rules
forbid constructs that introduce
unnecessary complexity and
are error-prone, e.g. A9-6-2,
M10-2-1, A10-2-1.
1b Use of language subsets 6 - Implemented 3.1 Plenty of AUTOSAR C++14
Coding Guidelines rules forbid
constructs that are allowed from
the C++ language perspective,
but (1) lead to unstructured
designs, (2)
are misleading for a developer,
(3) are implementation defined.
In case some features are to
be used in a particular project
nonetheless, see chapter 5.4.
1c Enforcement of strong typing 6 - Implemented M5-2-2,
M5-2-3,
A5-2-2,
A5-2-3,
M5-2-6,
A5-2-4,
M5-2-9,
A8-4-14,
A7-2-3
Restrictions on type casting.
Recommendations on strongly-
typed interfaces and scoped
enums.
1d Use of defensive
implementation techniques
6 - Implemented A0-4-4,
A4-7-1,
A5-2-5,
A6-5-1,
A14-1-1,
A15-3-4
Error checking
required for math functions,
integer expressions, array
access. Limitations on iteration
statements. Recommendations
on how to cope with external
code failures.
1e Use of established design
principles
6 - Implemented 6.18.5,
A18-5-2,
A0-1-4
Recommendation on RAII,
exception in rules that facilitate
correct usage of SFINAE and
Concepts. Multiple
rules contain references to
corresponding rules
from multiple standards, which
confirms that the provided rule
set reflects widely approved
coding techniques.
1f Use of unambiguous
graphical representation
8 - Not applicable Recommendations on graphical
representation is out of scope
of AUTOSAR C++14 Coding
Guidelines.
1g Use of style guides 8 - Not applicable AUTOSAR C++14 Coding
Guidelines does not introduce
rules related to coding style.
1h Use of naming conventions 8 - Not applicable AUTOSAR
C++14 Coding Guidelines does
not introduce rules related to
naming convention.
Table B.7: Topics to be covered by modelling and coding guidelines. Table 1 from [5].
8: Software unit design and implementation
8.4: Requirements and recommendations
ISO 26262 requirement: Relation type: Related rule: Comment:
1a Natural language 7 - Partially
implemented
A2-7-3, A2-7-5 Requirements on: providing
documentation for user-defined
types, content and structure of
the documentation.
1b Informal notations
1c Semi-formal notations
1d Formal notations
Table B.8: Notations for software unit design. Table 7 from [5].
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1a One entry and one exit
point in subprograms
and functions
6 - Implemented See Single-point-of-exit. All
the benefits from this approach are
handled by different measures. Code
modularity aspects are also ensured
by techniques and limitations that
fulfill other ISO26262 requirements,
see: Enforcement of low complexity,
Readability and comprehensibility,
Suitability for modifications.
1b No dynamic objects
or variables, or else
online test during their
creation
6 - Implemented A18-5-5,
A18-5-6,
A18-5-7,
A18-5-2,
A18-5-9,
A18-5-10
Dynamic memory allowed, but under
multiple constraints affecting memory
management. Allocated objects
lifetime maintenance delegated to
shared
pointers and memory management
objects. Restrictions set for custom
implementations of dynamic memory
allocation and placement new.
1c Initialization of
variables
6 - Implemented A8-5-0,
A3-3-2,
A6-5-4,
A8-5-1,
A8-5-3,
A8-5-4,
A12-1-1,
A12-1-2,
A12-1-6
Required is: memory initialization
before access, constant initialization
of static and thread–local objects, loop
counters initialization. Defined are
requirements
for: initialization lists, initialization of
type auto, user-declared constructors,
NSDMI, delegating constructors.
1d No multiple use of
variable names
6 - Implemented M2-10-1,
A2-10-1,
A2-10-6,
A2-10-4,
A2-10-5,
M3-4-1
Limitations on
identifier hiding and requirements on
typographical unambiguity .
1e Avoid global variables
or else justify their
usage
7 - Partially
implemented
A3-3-2 Global variables shall be constant-
initialized.
1f Limited use of pointers 6 - Implemented A8-4-11,
A8-4-10,
M5-0-15,
M5-0-16,
M5-0-17,
M5-0-18,
A5-0-4,
A5-0-3
Lifetime semantics is to be handled
using smart pointers and usage of
raw pointers is limited only to passing
parameters that are not owned by
the pointer (as currently no constructs
from C++14 Standard could replace
it), which resolves problems with
possible memory leaks. Restrictions
on pointers arithmetic, no more
than two levels of pointer indirection,
pointers usage limited only to single
objects. Listed rule set fulfills also
all the requirements described in
[19], chapter C.2.6.6 “Limited use of
pointers”, apart from “Data exchange
should be done via the operating
system”, which is out of scope of this
document.
1g No implicit type
conversions
6 - Implemented A4-5-1,
A4-7-1,
M4-10-1,
M5-0-4,
M5-0-5,
M5-0-6,
A7-2-3,
A8-5-2,
A13-5-2,
A13-5-3,
A23-0-1
It is
forbidden to use: enums in arithmetic
contexts, integer conversions that lead
to data loss, NULL as an integer value,
non-scoped enumerations, conversion
from iterator to const_iterator.
It is additionally protected by forcing:
braced initialization
of variables and restrictions on user-
defined conversion operators.
1h No hidden data or
control flow
7 - Partially
implemented
A15-0-6,
A15-0-7,
A15-0-8,
6.15
Usage of exceptions as a method
for error handling is not enforced
by the AUTOSAR Coding Guidelines.
However, if it is to be used in a
particular project, it (1) is allowed
only if strict requirements on a
toolchain are fulfilled, e.g. analysis of
failure modes of exception handling,
deterministic worst-
case execution time. (2) is forbidden
as part of the typical program flow
and is limited only for handling errors
where a function failed to perform
its assigned task. (3) requires
analysis of maximum execution time
constraints for a particular software
project. Using Checked Exceptions
for signaling recoverable errors brings
benefits to completeness of error
handling procedure, as it enforces
developers to provide a dedicated
handling hook for each type of such
errors. Rules for stack unwinding are
unambiguously defined by [3, ISO/IEC
14882:2014], thus it is possible to
establish a matching catch clause
for each exception thrown in the
software, to which the control flow
will jump after exception is thrown.
By default, handling of Unchecked
Exceptions should lead to proper
program termination, therefore stack
unwinding ensures correct invocation
of destructors for all objects with
automatic storage duration,
which prevents from possible memory
leaks in case of errors (considering
no violations of available rules for
memory management). However,
usage of exceptions still introduces
a hidden control flow into a program
execution, thus such an approach only
partially implements this requirement
from the ISO26262-6 [5].
1i No unconditional
jumps
6 - Implemented A6-6-1,
M17-0-2
Lack of
exact definition of “unconditional jump”
in ISO 26262 [5] and C++14 Standard
[3], therefore the statement from IEC
61508 Annex C [19] was assumed:
“avoid unconditional jumps (goto) in
higher level languages”.
1j No recursions 6 - Implemented A7-5-2
Table B.9: Design principles for software unit design and implementation. Table 8 from
[5].
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1a correct order of execution of
subprograms and
functions within the software
units, based on the software
architectural design
6 - Implemented A15-4-1,
A15-4-2,
A15-5-2,
A15-5-3
Restrictions on constructs that
may lead
to program termination without
calling proper exit handlers and
destructors.
1b consistency of the interfaces
between the software units
6 - Implemented M1-0-2,
A15-1-5
Restrictions on: passing non-
standard layout type
objects and exceptions across
execution boundaries.
1c correctness of data flow and
control flow between and
within the software units
6 - Implemented M0-3-1
A15-0-1,
A15-0-4,
A15-0-5,
A15-3-2,
A15-3-3,
A15-3-4,
M15-0-3,
A6-6-1
Checked and Unchecked
exceptions are to be used
only for error handling, they
are forbidden for handling the
normal control flow. Additional
explanation of this property
from [19]: “The software design
shall include, commensurate
with the required safety integrity
level, self-monitoring of control
flow and data flow. On failure
detection, appropriate actions
shall be taken. ”
1d simplicity 6 - Implemented A1-4-1,
A8-4-3,
A10-1-1,
A14-7-2
Forcing limitations for cases
that limit maintainability and
readability .
1e readability and
comprehensibility
6 - Implemented A1-4-1,
A1-4-3,
A5-1-1,
A5-1-9,
A10-2-1,
M10-2-1,
A12-7-1,
A14-7-2
Enforcing code
metrics, forbidding constructs
that are confusing, lead to
code duplication or introduce
unnecessary complexity .
1f robustness 6 - Implemented M0-3-1,
M0-3-2,
A1-1-1,
A15-0-2,
A15-0-3,
A15-0-6,
A15-0-7,
A18-5-6
Checked exceptions concept
which facilitates tracking if a
particular error type is handled.
Recommendations on how to
report errors in an application.
Requirements on analysis of
failure modes and worst-case
execution
time for exception handling and
memory management.
1g suitability for software
modification
6 - Implemented A8-4-14,
A10-0-1,
A10-0-2,
A10-4-1
Recommending constructs that
increase software reusability ,
eliminate redundancy and hide
implementation details.
1h testability 6 - Implemented A1-2-1,
A1-4-1,
A3-3-2
Requirements on: testing error
information if this is generated,
using code metrics
which will increase code quality
and modularity . Restrictions on
constructs that obscure code
maintainability . Suggestions
on how to perform extensive
testing.
Table B.10: Properties to be achieved by applying design principles from Table 8.
Paragraph 8.4.4 from [5].
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1a Walk-through 8 - Not applicable Process of system examination
to reveal discrepancies
between a specification and
implementation is out of scope
of AUTOSAR C++14 Coding
Guidelines.
1b Inspection 8 - Not applicable Structured processes (at any
level of rigour) of revealing
defects in developed software
components are out of scope
of AUTOSAR C++14 Coding
Guidelines.
1c Semi-formal verification 8 - Not applicable Aspects
of proving the correctness
of a program basing on an
abstract model are out of
scope of AUTOSAR C++14
Coding Guidelines.
1d Formal verification
1e Control flow analysis 7 - Partially
implemented
M0-1-1,
M0-1-2,
M0-1-8,
M0-1-9,
M0-1-10,
A0-1-3
Available are rules oriented
on finding suspect areas of
code (e.g. inaccessible code,
infeasible paths), but analysis
of directed program graph (from
the definition from paragraph
C.5.9 [19]) is out of scope
of AUTOSAR C++14 Coding
Guidelines.
1f Data flow analysis 6 - Implemented M0-1-3,
M0-1-4,
A0-1-1,
A0-1-4,
A0-1-5,
A0-1-6,
A8-5-0
Available are rules oriented on
analysis of sequences
of creating, referencing and
deleting variables.
1g Static code analysis 6 - Implemented All automated rules included
in AUTOSAR C++14 Coding
Guidelines are enforceable by
means of static code analysis.
1h Semantic code analysis 8 - Not applicable Mathematical
source code analysis by use
of an abstract representation of
possible values is out of scope
of AUTOSAR C++14 Coding
Guidelines.
Table B.11: Methods for the verification of software unit design and implementation.
Table 9 from [5].
C Glossary
Abbreviation / Acronym: Description:
Real-time application (RT A) A real-time application is a program that guarantees response
within defined time constraints. The latency must be less than
a defined value, usually measured in seconds or milliseconds.
Whether or not a given application program qualifies as an
RT A depends on the worst-case execution time (WCET) - the
maximum length of time a defined task requires on a given
hardware platform.
MISRA Motor Industry Software Reliability Association.
HIC++ High Integrity C++ Coding Standard.
cvalue expression An expression that should not undergo further conversions, either
implicitly or explicitly , is called a cvalue expression.
Ownership Ownership of a resource means that the resource’s lifetime is
fully managed by the single class instance or tied with the class
instance lifetime. See also: chapter 6.18.5
One definition rule The rule states that:
• There shall be one and only one definition of any variable,
function, class type, enumeration type, or template in
a translation unit. Some of these may have multiple
declarations, but only one definition is allowed.
• There shall be one and only one definition of every non-
inline function or variable that is odr-used in the entire
program.
• An inline function definition is required in every translation
unit where it is odr-used.
• There shall be one and only one definition of a class in
any translation unit where the class is used in a way that
requires it to be complete.
• There can be more than one definition of any class,
enumeration type, inline function with external linkage,
class template, non-static function template, static data
member of a class template, member function of a class
template, partial template specialization in a program, as
long as all of the following is true:
– each definition consists of the same sequence of
tokens (typically , appears in the same header file)
– name lookup from within each definition finds the
same entities (after overload-resolution), except that
constants with internal or no linkage may refer to
different objects as long as they are not ODR-used
and have the same values in every definition.
– overloaded operators, including conversion,
allocation, and deallocation functions refer to the
same function from each definition (unless referring
to one defined within the definition)
– the language linkage is the same (e.g. the include
file isn’t inside an extern “C” block)
– the three rules above apply to every default
argument used in each definition
– if the definition is for a class with an implicitly-
declared constructor, every translation unit where it
is odr-used must call the same constructor for the
base and members
– if the definition is for a template, then all these
requirements apply to both names at the point of
definition and dependent names at the point of
instantiation
If all these requirements are satisfied, the program
behaves as if there is only one definition in the entire
program. Otherwise, the behavior is undefined.
ODR-use An object is odr-used if its address is taken, or a reference is
bound to it. A function is odr-used if a function call to it is made
or its address is taken.
POD T ype POD (Plain Old Data) type is the type that is compatible with
types used in the C programming language, can be manipulated
using C library functions, and can be exchanged with C libraries
directly in its binary form.
Trivially Copyable Class A class (C++ Language Standard [3], chapter 9):
• where each copy constructor, move constructor, copy
assignment operator, move assigment operator is either
deleted or trivial
• that has at least one non-deleted copy constructor,
move constructor, copy assignment operator, or move
assignment operator, and
• that has a trivial, non-deleted destructor
Standard-Layout Class A class that (C++ Language Standard [3], chapter 9):
• has no non-static data members of type non-standard-
layout class (or array of such types) or reference
• has no virtual functions and no virtual base classes
• has the same access control for all non-static data
members
• has no non-standard-layout base classes
• has at most one base class subobject of any given type
• has all non-static data members and bit-fields in the class
and its base classes first declared in the same class
• has no element of the set M(X) of types as a base class
where M(X) is defined as follows:
– If X is a non-union class type, the set M(X) is
empty if X has no (possibly inherited) non-static
data members; otherwise, it consists of the type of
the first non-static data member of X (where said
member may be an anonymous union), X0, and the
elements of M(X0).
– If X is a union type, the set M(X) is the union of all
M(Ui) and the set containing all Ui, where each Ui is
the type of the i-th non-static data member of X.
– If X is a non-class type, the set M(X) is empty .
Dataflow Anomaly The state of a variable at a point in a program can be described
using the following terms:
• Undefined (U): The value of the variable is indeterminate.
• Referenced (R): The variable is used in some way (e.g. in
an expression).
• Defined (D): The variable is explicitly initialized or assigned
a value.
Given the above, the following dataflow anomalies can be
defined:
• UR dataflow anomaly: Variable not assigned a value
before the specified use (this may result in undefined
behavior).
• DU dataflow anomaly: Variable is assigned a value that is
never subsequently used.
• DD dataflow anomaly: Variable is assigned a value twice
with no intermediate use.
Dead Code Dead code (also known as redundant code) consists of evaluated
expressions whose removal would not affect the output program.
Unreachable Code Unreachable code is code to which there is no syntactic (control
flow) path, e.g. a function which is never called, either directly or
indirectly .
Diamond Problem The “diamond problem” is an ambiguity that arises when two
classes B and C inherit from A, and class D inherits from both B
and C. If there is a method provided by class A, that is overriden
in both B and C and D does not override it, then there is an
ambiguity which version of the method does D actually inherit.
See: Wikipedia.org for more details.
Interface class An interface class is a class which has following properties:
• if there are any , all member functions are public pure
virtual
• if there are any , all data members are public static
constexpr
Extended precision format The IEEE Standard for Floating-Point Arithmetic (IEEE 754)
specifies extended precision formats, that are recommended for
allowing a greater precision format than that provided by the
basic formats.
For an extended format the exponent range must be as great
as that of the next wider basic format. For instance, 64-bit
extended precision binary number must have an “exponent max”
of at least 16383, which is equal to “exponent max” of 128-
bit binary floating-point. The 80-bit extended format meets this
requirement.
Fundamental types C++ built-in types defined in C++ Language Standard [3] in
chapter 3.9.1, e.g. char, signed char, unsigned char, int, long
long int, wchar_t, bool, float, double, void, std::nullptr_t, etc.
Scalar types The following types are scalar types:
• integral types
• floating point types
• pointers and pointers to members
• enumerations
• std::nullptr_t
glvalue A glvalue is an expression whose evaluation determines the
identity of an object, bit-field, or function.
xvalue An xvalue refers to an object, usually near the end of its lifetime,
so that its resources may be moved.
prvalue A prvalue is an expression whose evaluation initializes an object
or a bit-field, or computes the value of the operand of an operator.
rvalue An rvalue is an xvalue or a prvalue.
lvalue An lvalue is a glvalue that is not an xvalue.
Implicitly-defined default
constructor
Implicitly-defined default constructor calls default constructors of
its base classes and non-static data members. It has exactly the
same effect as a user-defined constructor with empty body and
empty initializer list.
Implicitly-defined copy
constructor
Implicitly-defined copy constructor of a class type (class or struct)
performs full member-wise copy of the object’s bases and non-
static data members, in their initialization order, using direct
initialization.
Implicitly-defined move
constructor
Implicitly-defined move constructor of a class type (class or
struct) performs full member-wise move of the object’s bases
and non-static members, in their initialization order, using direct
initialization with an xvalue argument.
Implicitly-defined copy
assignment operator
Implicitly-defined copy assignment operator of a class type
(class or struct) performs full member-wise copy assignment
of the object’s bases and non-static data members, in their
initialization order, using built-in assignment for the scalars and
copy assignment operator for class types.
Implicitly-defined move
assignment operator
Implicitly-defined move assignment operator of a class type
(class or struct) performs full member-wise move assignment
of the object’s direct bases and immediate non-static data
members, in their initialization order, using built-in assignment
for the scalars, member-wise move-assignment for arrays, and
move assignment operator for class types (called non-virtually).
Implicitly-defined destructor Implicitly-defined destructor has an empty body . After the body of
the destructor is executed, the destructors for all non-static non-
variant data members of the class are called, in reverse order
of declaration. Then it calls destructors of all direct non-virtual
base classes, in reverse order of construction, and then it calls
the destructors of all virtual bases.
Is-a relationship Subsumption relationship between types. If one class B is a
subclass of another class A (i.e. B is a more specialized concept
than A), then B class specification implies A class specification
and a B class object can be used for any expression that requires
an A class object.
Has-a relationship Composition relationship where one object is a part or member
of another object with respect to the rules of ownership.
Table C.1: Acronyms
Definition: Description:
Single point of exit Approach background:
• IEC 61508 [19], as one of methods for providing modular
approach
• ISO26262 part 6 [5] with the requirement for ASIL A-D.
• MISRA-C++ 2008 with the rule M6-6-5.
AUTOSAR Coding Guidelines consider that the only reason for
such an approach is improving robustness of resource handling,
e.g. ensuring that resources are properly released in case of an
early exit from the function. However, it is fully ensured by other
rules existing in the document that:
• enforce usage of smart
pointers and memory management objects for expressing
lifetime semantics (A18-5-2)
• enforce allocate local objects on stack (A18-5-8)
• recommend usage of RAII (A15-1-4, A18-5-2)
Single point of exit is considered to decrease code readability
and will not bring any additional benefits for improving coding
standards, thus it is not enforced by the AUTOSAR Coding
Guidelines.
Table C.2: Definitions
D Changelog
This section shows changes done between document releases.
D.1 Release 17-10
Type of change: Modified rules:
Title, example, exceptions A7-1-7, A15-0-4, A15-0-5, A15-3-1, A18-5-2
Rule classification A9-3-1
References A0-4-3, M3-4-1, M5-2-12, A5-0-1, A5-1-2, A5-1-4, A6-5-2, M7-
1-2, M7-5-2, A7-1-1, A7-1-7, A8-4-1, M9-3-3, A12-0-1, A12-8-6,
A18-5-2, A18-9-2
New rule A0-1-4, A0-1-5, A6-5-3, A8-4-4, A9-5-1, A12-1-5, A12-1-6, A13-
5-2, A18-1-6, A18-5-8
MISRA review changes A0-1-3, A2-10-5, A5-1-7, M10-1-2
Other Traceability updated for HIC (see B.2), CERT (see B.4), C++
Core Guidelines (see B.5). Added changelog appendix chapter.
Table D.1: Changelog for release 17-10.
D.2 Release 18-03
Type of change: Modified rules:
Title, example, exceptions A1-4-1, A2-3-1, A2-7-3, A2-8-1, A3-3-2, A5-2-5, A12-0-1, A12-8-
1, A13-3-1, A15-0-5, A15-3-2, A15-3-3, A15-4-5, A15-5-1, A18-
0-2, A18-1-1, A18-1-4, A18-1-6, A18-5-8
Rule classification, numbering A5-6-1, A2-13-1, A2-13-2, A2-13-3, 6.2.5 (A2-5-2), 6.2.8 (A2-8-1)
6.2.10 (A2-10-1, A2-10-4, A2-10-5), A15-0-6, A15-0-7, A15-0-8,
A15-1-1, A15-3-3, A18-1-1
Chapter numbering 6.2.3 (A2-3-1), 6.2.5 (A2-5-2), 6.2.8 (A2-8-1) 6.2.10 (A2-10-1,
A2-10-4, A2-10-5)
References, notes M0-1-9, A2-7-3, A2-8-1, A3-3-2, A4-7-1, A5-0-1, M5-0-2, A5-2-1,
A5-2-5, M5-2-2, A6-5-1, A7-1-7, A8-5-2, A9-3-1, A12-1-1, A12-4-
1, A12-4-2, A13-5-2, A14-1-1, A15-0-4, A15-0-5, A15-4-1, A15-
5-2, A15-5-3, M18-0-4, M18-0-5, A18-5-5
New rule A0-1-6, A0-4-4, A1-4-3, M2-7-1, A2-7-5, A2-8-2, A2-10-6, A2-11-
1, A2-13-4, A2-13-5, A2-13-6, A3-1-5, A3-1-6, A3-8-1, A5-0-4,
A5-1-9, A5-2-6, A5-3-2, A5-3-3, A5-5-1, A6-2-1, A6-5-4, A7-1-9,
A7-2-5, A7-3-1, A7-6-1, A8-4-5, A8-4-6, A8-4-8, A8-4-9, A8-4-10,
A8-4-11, A8-4-12, A8-4-13, A8-5-0, A10-0-1, A10-0-2, A10-4-1,
A12-0-2, A13-5-3, A13-5-4, A14-5-1, A14-7-2, A14-8-2, A17-6-1,
A18-5-9, A18-5-10, A20-8-1, A20-8-2, A20-8-3, A20-8-4, A20-8-
5, A20-8-6, A20-8-7, A21-8-1, A23-0-2, A25-1-1, A25-4-1, A26-
5-1, A26-5-2, A27-0-3, A27-0-4
Removed rule M0-1-5, A1-4-2, A2-7-4, A2-10-2, A2-10-3, M2-10-6, A5-1-5, M5-
2-1, M7-3-5, M8-5-1, A13-1-1, M14-5-2, M14-7-3, A14-8-1, M14-
8-1, A15-3-1, A15-4-6, A18-1-5
Definitions Is-a-relationship, Has-a-relationship
Other Traceability updated for MISRA (see B.1), HIC++ (see B.2), JSF
(see B.3), CERT (see B.4), C++ Core Guidelines (see B.5)
Table D.2: Changelog for release 18-03.
D.3 Release 18-10
Type of change: Modified rules:
Title, example, exceptions A8-5-2, A8-5-4, A9-6-1, A10-2-1, A11-3-1, A13-5-4, A15-4-3,
A16-2-2, A16-2-3, A18-5-2, A18-5-3
References, notes A5-0-4
New rule A6-2-2, A8-4-14, M9-6-4, A13-5-5, A14-5-2, A14-5-3, A18-5-11
Other Traceability updated for MISRA (see B.1), C++ Core Guidelines
(see B.5), HIC++ (see B.2). Traceability added for ISO 26262
(see B.6).
Table D.3: Changelog for release 18-10.
See also:
• SEI CERT C++ Coding Standard [10]: FIO39-C: Do not alternately input and
output from a stream without an intervening flush or positioning call
• SEI CERT C++ Coding Standard [10]: FIO50-CPP: Do not alternately input and
output from a file stream without an intervening positioning call
7 References
Bibliography
[1] ISO/IEC 14882:2003, The C++ Standard Incorporating Technical Corrigendum 1 ,
International Organization for Standardization, 2003.
[2] ISO/IEC 14882:2011, ISO International Standard ISO/IEC 14882:2011(E) -
Programming Language C++ , International Organization of Standardization, 2011.
[3] ISO/IEC 14882:2014, ISO International Standard ISO/IEC 14882:2014(E) -
Programming Language C++, International Organization for Standardization, 2016.
[4] ISO 26262-6, Road vehicles - Functional safety - Part 6: Product development at
the software level, International Organization for Standardization, 2011.
[5] ISO 26262-6, Road vehicles - Functional safety - Part 6: Product development at
the software level, International Organization for Standardization, 2011.
[6] ISO 26262-8, Road vehicles - Functional safety - Part 8: Supporting processes ,
International Organization for Standardization, 2011.
[7] MISRA C++:2008 Guidelines for the use of the C++ language in critical systems ,
The Motor Industry Software Reliability Association, 2008.
[8] Joint Strike Fighter Air Vehicle C++ Coding Standards for the System Development
and Demonstration Program , Document Number 2RDU00001 Rev C, Lockheed
Martin Corporation, 2005.
[9] High Integrity C++ Coding Standard Version 4.0, Programming Research Ltd, 2013.
[10] Software Engineering Institute CERT C++ Coding Standard , Software
Engineering Institute Division at Carnegie Mellon University , 2016.
[11] Bjarne Stroustrup, Herb Sutter, C++ Core Guidelines , 2017.
[12] Google C++ Style Guide , Google, 2017.
[13] Scott Meyers, Effective Modern C++ , ISBN: 978-1-491-90399-5, O’Reilly , 2015.
[14] Bjarne Stroustrup, The C++ Programming Language, Fourth Edition , ISBN: 978-
0-321-56384-2, Addison-Wesley , 2013.
[15] Joshua Bloch, Effective Java, Second Edition , ISBN: 978-0321356680, Addison-
Wesley , 2008
[16] cppreference.com, online reference for the C and C++ languages and standard
libraries, 2017
[17] stackoverflow.com, community of programmers, 2017
[18] open-std.org, site holding a number of web pages for groups producing open
standards, 2017
[19] IEC 61508-3, Functional safety of electrical/electronic/programmable electronic
safety-related systems – Annex C, Overview of techniques and measures for
achieving software safety integrity , International Electrotechnical Commission,
2010.
A Allocation of rules to work products
This chapter lists the rules that are allocated to ISO 26262 work products or activities
that are impacted by the usage of C++ (in particular for software architectural design
specification, software unit design specification, toolchain and others).
The rules listed below can be used as guidelines for peforming those activities or as
checklists for performing reviews. For example, it can be used for performing the review
of software architectural design specification.
A.1 Rules allocated to architecture
A2-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A2-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
A2-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
M2-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
A2-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
A2-13-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
A2-13-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
M2-13-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A2-13-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A2-13-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A3-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
A3-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
A3-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A4-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
A15-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
A15-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
A15-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
A15-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
A.2 Rules allocated to design
A2-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A2-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
A2-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
M2-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
A2-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
A2-10-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
A2-11-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
A2-13-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
A2-13-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
M2-13-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A2-13-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A2-13-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A3-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
A3-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
A3-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A3-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A3-1-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A3-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
A4-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
A7-2-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
A8-4-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .156
A8-4-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .157
A8-4-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158
A8-4-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159
A8-4-7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
A8-4-8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .162
A8-4-9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .163
A8-4-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
A8-4-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
A8-4-12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
A8-4-13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
A8-4-14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
A9-6-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .184
A9-6-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .185
A10-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
A10-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
A10-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
A14-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
A14-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
A15-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
A15-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
A15-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
A15-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
A.3 Rules allocated to toolchain
A0-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A0-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
M1-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A1-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A1-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A1-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
A15-0-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
A15-0-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
A15-0-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
A18-5-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
A18-5-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
A.4 Rules allocated to infrastructure
A0-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A.5 Rules allocated to analysis
A.6 Rules allocated to hardware
A.7 Rules allocated to management
A.8 Rules allocated to verification
M0-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
A1-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
A15-0-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
A15-0-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
A15-0-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
A18-5-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
A.9 Rules allocated to implementation
M0-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
M0-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
M0-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
M0-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
A0-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
A0-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
M0-1-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
M0-1-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
M0-1-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A0-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A0-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
A0-1-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
A0-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
M0-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
M0-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
M0-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
M0-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
M0-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A0-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
A0-4-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
A1-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
A1-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A1-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
A1-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A2-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A2-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
A2-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
M2-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
A2-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
A2-7-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
A2-7-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
A2-7-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
A2-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
A2-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
M2-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
A2-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
A2-10-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
A2-10-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47
A2-10-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
A2-11-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
A2-13-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
A2-13-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
A2-13-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
M2-13-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A2-13-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .52
A2-13-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A2-13-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A3-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
A3-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
A3-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
M3-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A3-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
M3-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
M3-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
M3-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
M3-2-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
A3-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
A3-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
M3-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
M3-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
A3-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
M3-9-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
A3-9-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
M3-9-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
M4-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
A4-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
M4-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
A4-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
M4-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
A4-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
M4-10-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
A5-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
M5-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
M5-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
M5-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
M5-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
M5-0-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
M5-0-12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
A5-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
M5-0-14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
M5-0-15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
M5-0-16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
M5-0-17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
A5-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
M5-0-18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
A5-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
M5-0-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
M5-0-21 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
A5-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
A5-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
A5-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
A5-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
A5-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
A5-1-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
A5-1-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
A5-1-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
M5-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
M5-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
A5-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
A5-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
A5-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
M5-2-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
A5-2-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
A5-2-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100
M5-2-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
M5-2-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
M5-2-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
M5-2-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
A5-2-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102
M5-2-12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
M5-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
M5-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
M5-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
M5-3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
A5-3-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105
A5-3-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .106
A5-3-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107
A5-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109
A5-6-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .110
M5-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
A5-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
M5-14-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
A5-16-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
M5-17-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
M5-18-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
M5-19-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
M6-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
A6-2-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .114
A6-2-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .116
M6-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
M6-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
M6-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
M6-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
A6-4-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
A6-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .120
A6-5-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
M6-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
M6-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
M6-5-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
M6-5-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
M6-5-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
A6-5-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .124
A6-5-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .125
A6-6-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .126
M6-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
M6-6-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
M6-6-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
A7-1-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .127
A7-1-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .128
M7-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
A7-1-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
A7-1-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
A7-1-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
A7-1-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .133
A7-1-7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .134
A7-1-8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .135
A7-1-9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .136
A7-2-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
A7-2-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .139
A7-2-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .140
A7-2-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
M7-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
M7-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
M7-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
M7-3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
A7-3-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
M7-3-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
A7-4-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .146
M7-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
M7-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
M7-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
M7-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
M7-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
A7-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .147
A7-5-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149
A7-6-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .151
M8-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
A8-2-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .152
M8-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
A8-4-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
M8-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
A8-4-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155
M8-4-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
A8-5-0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
A8-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173
M8-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
A8-5-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
A8-5-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .177
A8-5-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .178
M9-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
A9-3-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .180
M9-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
A9-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .182
M9-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
M9-6-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
A10-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
M10-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
M10-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
M10-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
M10-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
A10-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
A10-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
A10-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
A10-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
A10-3-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
M10-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
M11-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
A11-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
A11-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
A11-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
A12-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
A12-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
A12-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
M12-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
A12-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
A12-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
A12-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
A12-1-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
A12-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
A12-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
A12-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
A12-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
A12-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
A12-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
A12-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
A12-8-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
A12-8-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
A12-8-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
A12-8-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
A12-8-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
A13-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
A13-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
A13-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
A13-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
A13-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
A13-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
A13-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
A13-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
A13-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
A13-5-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
A13-5-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
A13-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
A14-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
A14-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
M14-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
M14-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
A14-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
A14-7-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
A14-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
A15-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
A15-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
A15-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
A15-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
A15-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
A15-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
A15-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
M15-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
M15-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
M15-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
M15-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
A15-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
A15-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
A15-1-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
A15-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
A15-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
M15-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
A15-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
A15-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
A15-3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
M15-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
M15-3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
A15-3-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
M15-3-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
M15-3-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
A15-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
A15-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
A15-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
A15-4-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
A15-4-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
A15-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
A15-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
A15-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
A16-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
M16-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
M16-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
M16-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
M16-0-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
M16-0-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
M16-0-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
M16-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
M16-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
M16-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
A16-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
A16-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
A16-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
M16-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
M16-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
A16-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
A16-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
A17-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
M17-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
M17-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
A17-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
M17-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
A17-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
A17-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
A18-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
A18-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
M18-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
M18-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
M18-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
A18-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
A18-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
A18-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
A18-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
A18-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
A18-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
M18-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
A18-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
A18-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
A18-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
A18-5-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
A18-5-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
A18-5-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
A18-5-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
A18-5-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
A18-5-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
M18-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
A18-9-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
A18-9-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
A18-9-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
A18-9-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
M19-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
A20-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
A20-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
A20-8-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
A20-8-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
A20-8-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
A20-8-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
A20-8-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
A21-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
A23-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
A23-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
A25-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
A25-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
A26-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
A26-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
M27-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
A27-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
A27-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
A27-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
A27-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
B Traceability to existing standards
This section demonstrates the traceability of AUTOSAR C++14 rules to existing
important C++ coding standards and to ISO 26262.
For each rule, the relation is identified:
1. Identical (only for MISRA C++): the rule text, rationale, exceptions, code example
are identical. Only the rule classification can be different. There can be also an
additional note with clarifications.
2. Small differences: the content of the rule is included by AUTOSAR C++14 rules
with minor differences.
3. Significant differences: the content of the rule is included by AUTOSAR C++14
rules with significant differences.
4. Rejected: the rule in the referred document is rejected by AUTOSAR C++14
guidelines.
5. Not yet analyzed: The rule is not yet analyzed in the current release.
6. Implemented (only for ISO 26262): A clause is implemented by the AUTOSAR
C++14 rules.
7. Partially implemented (only for ISO 26262): A clause covered to some extent that
is in scope of this document.
8. Not applicable (only for ISO 26262): A clause that is out of scope of this
document.
B.1 Traceability to MISRA C++:2008
MISRA C++:2008 [7] is a required prerequisite for readers of the document. MISRA
C++:2008 can be purchased over MISRA web store.
The following table demonstrates the traceability to MISRA C++:2008. This is not
considered as a reproduction of a part of MISRA C++:2008, but a mean to compare
the two standards.
MISRA Rule: Relation type: Related
rule:
Comment:
0-1-1 (Required) A project shall not
contain unreachable code.
1 - Identical M0-1-1 -
0-1-2 (Required) A project shall not
contain infeasible paths.
2 - Small differences M0-1-2 Note about
constexpr functions
added.
0-1-3 (Required) A project shall not
contain unused variables.
1 - Identical M0-1-3 -
0-1-4 (Required) A project shall not
contain non-volatile POD variables
having only one use.
1 - Identical M0-1-4 -
0-1-5 (Required) A project shall not
contain unused type declarations.
3 - Significant differences A0-1-6 Obligation
level changed to
“Advisory”.
0-1-6 (Required) A project shall
not contain instances of non-volatile
variables being given values that are
never subsequently used.
2 - Small differences A0-1-1 Example reworked.
0-1-7 (Required) The value returned
by a function having a non-void return
type that is not an overloaded operator
shall always be used.
2 - Small differences A0-1-2 Rationale
reformulated.
0-1-8 (Required) All functions with void
return type shall have external side
effect(s).
1 - Identical M0-1-8 -
0-1-9 (Required) There shall be no
dead code.
1 - Identical M0-1-9 -
0-1-10 (Required)
Every defined function shall be called
at least once.
3 - Significant differences M0-1-10,
A0-1-2
Rule divided into:
(1) Identical rule
with obligation level
“Advisory”, (2) Rule
with obligation level
“Required”
which applies to
static functions and
private methods.
0-1-11 (Required) There shall be
no unused parameters (named or
unnamed) in non-virtual functions.
3 - Significant differences A0-1-4 Unused
parameters
are allowed to be
unnamed.
0-1-12 (Required) There shall be
no unused parameters (named or
unnamed) in the set of parameters for
a virtual function and all the functions
that override it.
3 - Significant differences A0-1-5 Unused
parameters
are allowed to be
unnamed.
0-2-1 (Required) An object shall not be
assigned to an overlapping object.
1 - Identical M0-2-1 -
0-3-1 (Document) Minimization of run-
time failures shall be ensured by the
use of at least one of: (a) static
analysis tools/techniques; (b) dynamic
analysis tools/techniques; (c) explicit
coding of checks to handle run-time
faults.
1 - Identical M0-3-1 -
0-3-2 (Required) If a function
generates error information, then that
error information shall be tested.
1 - Identical M0-3-2 -
0-4-1 (Document) Use of scaled-
integer or fixed-point arithmetic shall
be documented.
1 - Identical M0-4-1 -
0-4-2 (Document) Use of floating-point
arithmetic shall be documented.
1 - Identical M0-4-2 -
0-4-3 (Document) Floating-point
implementations shall comply with a
defined floating-point standard.
3 - Significant differences A0-4-1 Specified that
floating-point
implementations
need to
comply with IEEE
754 standard.
1-0-1 (Required) All code shall
conform to ISO/IEC 14882:2003 “The
C++ Standard Incorporating Technical
Corrigendum 1”.
2 - Small differences A1-1-1 Specified that the
code shall conform
to ISO/IEC
14882:2014.
1-0-2 (Document) Multiple compilers
shall only be used if they have a
common, defined interface.
1 - Identical M1-0-2 -
1-0-3 (Document) The implementation
of integer division in the chosen
compiler shall be determined and
documented.
3 - Significant differences A0-4-2 Specified that
the implementation
of integer division
shall comply with
the C++ Language
Standard.
2-2-1 (Document) The character set
and the corresponding encoding shall
be documented.
3 - Significant differences A2-3-1
2-3-1 (Required) Trigraphs shall not be
used.
2 - Small differences A2-5-1 All trigraphs listed
in rationale.
Example extended.
2-5-1 (Advisory) Digraphs should not
be used.
3 - Significant differences A2-5-2 Obligation
level changed to
“Required”.
2-7-1 (Required)
The character sequence /* shall not be
used within a C-style comment.
1 - Identical M2-7-1 -
2-7-2 (Required) Sections of code shall
not be commented out using C-style
comments.
2 - Small differences A2-7-1 Commenting-
out code sections
is not allowed.
2-7-3 (Advisory) Sections of code
should not be “commented out” using
C++ comments.
2 - Small differences A2-7-1 Obligation
level changed to
“Required”.
Commenting-
out code sections
is not allowed.
2-10-1 (Required) Different identifiers
shall be typographically unambiguous.
1 - Identical M2-10-1 -
2-10-2 (Required) Identifiers declared
in an inner scope shall not hide an
identifier declared in an outer scope.
2 - Small differences A2-10-1 Added a note to
rationale. Example
extended.
2-10-3 (Required) A typedef name
(including qualification, if any) shall be
a unique identifier.
4 - Rejected This rule is
considered as too
restrictive.
2-10-4 (Required) A class, union or
enum name (including qualification, if
any) shall be a unique identifier.
4 - Rejected This rule is
considered as too
restrictive.
2-10-5 (Advisory) The identifier name
of a non-member object or function
with static storage duration should not
be reused.
3 - Significant differences A2-10-4 Obligation
level changed to
“Required”. Scope
of the rule
changed.
2-10-6 (Required) If an identifier refers
to a type, it shall not also refer to an
object or a function in the same scope.
2 - Small differences A2-10-6
2-13-1 (Required) Only those escape
sequences that are defined in ISO/IEC
14882:2003 shall be used.
2 - Small differences A2-13-1 Standard changed
to ISO/IEC
14882:2014.
2-13-2 (Required) Octal constants
(other than zero) and octal escape
sequences (other than “\0” ) shall not
be used.
1 - Identical M2-13-2 -
2-13-3 (Required) A “U” suffix shall
be applied to all octal or hexadecimal
integer literals of unsigned type.
1 - Identical M2-13-3 -
2-13-4 (Required) Literal suffixes shall
be upper case.
1 - Identical M2-13-4 -
2-13-5 (Required)
Narrow and wide string literals shall not
be concatenated.
2 - Small differences A2-13-2 Example extended.
3-1-1 (Required) It shall be possible
to include any header file in multiple
translation units without violating the
One Definition Rule.
3 - Significant differences A3-1-1 Rationale
reformulated.
Example extended.
3-1-2 (Required) Functions shall not be
declared at block scope.
1 - Identical M3-1-2 -
3-1-3 (Required) When an array is
declared, its size shall either be
stated explicitly or defined implicitly by
initialization.
2 - Small differences A3-1-4 Specified that
this rule applies to
arrays with external
linkage only .
3-2-1 (Required) All declarations of
an object or function shall have
compatible types.
1 - Identical M3-2-1 -
3-2-2 (Required) The One Definition
Rule shall not be violated.
1 - Identical M3-2-2 -
3-2-3 (Required) A type, object or
function that is used in multiple
translation units shall be declared in
one and only one file.
1 - Identical M3-2-3 -
3-2-4 (Required) An identifier with
external linkage shall have exactly one
definition.
1 - Identical M3-2-4 -
3-3-1 (Required) Objects or functions
with external linkage shall be declared
in a header file.
2 - Small differences A3-3-1 Added a note to
rationale. Example
extended.
3-3-2 (Required) If a function has
internal linkage then all re-declarations
shall include the static storage class
specifier.
1 - Identical M3-3-2 -
3-4-1 (Required) An identifier declared
to be an object or type shall be defined
in a block that minimizes its visibility .
1 - Identical M3-4-1 -
3-9-1 (Required) The types used for
an object, a function return type, or a
function parameter shall be token-for-
token identical in all declarations and
re-declarations.
1 - Identical M3-9-1 -
3-9-2 (Advisory) typedefs that indicate
size and signedness should be used in
place of the basic numerical types.
3 - Significant differences M3-9-1 Rule
title and rationale
reformulated to use
types from
<cstdint> header
file. All types that
should be
used were listed.
Example changed.
3-9-3 (Required) The underlying bit
representations of floating-point values
shall not be used.
1 - Identical M3-9-3 -
4-5-1 (Required) Expressions with type
bool shall not be used as operands
to built-in operators other than the
assignment operator =, the logical
operators &&, ||, !, the equality
operators == and !=, the unary &
operator, and the conditional operator.
1 - Identical M4-5-1 -
4-5-2 (Required) Expressions with type
enum shall not be used as operands
to built-in operators other than the
subscript operator [ ], the assignment
operator =, the equality operators ==
and !=, the unary & operator, and the
relational operators <, <=, >, >=.
3 - Significant differences A4-5-1 Changed the rule
so it applies to
enum classes too.reformulated.
Example reworked.
12-1-3 (Required) All constructors that
are callable with a single argument
of fundamental type shall be declared
explicit.
2 - Small differences A12-1-4 Example reworked.
12-8-1 (Required) A copy constructor
shall only initialize its base classes and
the non-static members of the class of
which it is a member.
3 - Significant differences A12-8-1 Rule reformulated
to cover
move constructors,
too. Rationale
reformulated.
Example reworked.
12-
8-2 (Required) The copy assignment
operator shall be declared protected or
private in an abstract class.
3 - Significant differences A12-8-6 Rule reformulated
to cover move
assignment
operators and all
base
classes. Rationale
reformulated.
Example reworked.
12-
8-2 (Required) The copy assignment
operator shall be declared protected or
private in an abstract class.
3 - Significant differences A12-8-1 Rule reformulated
to cover
move constructors,
too. Rationale
reformulated.
Example reworked.
14-5-1 (Required) A non-
member generic function shall only be
declared in a namespace that is not an
associated namespace.
3 - Significant differences A14-5-3 Changed the
scope of the rule
from all generic
functions to
operators only , as
most problematic
case. Changed
severity to
Advisory .
14-5-2 (Required) A copy constructor
shall be declared when there is a
template constructor with a single
parameter that is a generic parameter.
3 - Significant differences A14-5-1 Avoids
the ambiguity by
requiring the
template
parameter to
be constrained to
never
match a copy/move
constructor.
14-5-3 (Required) A copy assignment
operator shall be declared when there
is a template assignment operator
with a parameter that is a generic
parameter.
1 - Identical M14-5-3 -
14-6-1 (Required) In a class template
with a dependent base, any name that
may be found in that dependent base
shall be referred to using a qualified-id
or this->.
1 - Identical M14-6-1 -
14-6-2 (Required) The function chosen
by overload resolution shall resolve to
a function declared previously in the
translation unit.
4 - Rejected - Usage of the
ADL functionality is
allowed. It is also
used in
STL for overloaded
operators lookup in
e.g. out streams,
STL containers.
14-7-1 (Required) All class templates,
function templates, class template
member functions and class template
static members shall be instantiated at
least once.
4 - Rejected - It is allowed to not
use all of the public
methods of a class.
14-7-2 (Required)
For any given template specialization,
an explicit instantiation of the template
with the template-arguments used in
the specialization shall not render the
program ill-formed.
3 - Significant differences A14-7-1 Rule reformulated
to explicitly state
what is required.
Example reworked.
14-7-3 (Required) All partial and
explicit specializations for a template
shall be declared in the same file as the
declaration of their primary template.
3 - Significant differences A14-7-2 Allowed to declare
in a header file
that declares user-
defined
type, for which the
specialization is
declared.
14-8-1 (Required) Overloaded function
templates shall not be explicitly
specialized.
3 - Significant differences A14-8-2 Function templates
specialization is
forbidden.
14-8-2 (Advisory) The viable function
set for a function call should either
contain no function specializations, or
only contain function specializations.
3 - Small differences A14-8-2 Function templates
specialization is
forbidden.
15-0-1 (Document) Exceptions shall
only be used for error handling.
3 - Significant differences A15-0-1 Rule reformulated,
example
significantly
extended.
15-0-2 (Advisory) An exception object
should not have pointer type.
3 - Significant differences A15-1-2 Obligation
level changed, rule
reformulated.
15-0-3 (Required) Control shall not be
transferred into a try or catch block
using a goto or a switch statement.
1 - Identical M15-0-3 -
15-1-1 (Required) The assignment-
expression of a throw statement shall
not itself cause an exception.
1 - Identical M15-1-1 -
15-1-2 (Required) NULL shall not be
thrown explicitly .
1 - Identical M15-1-2 -
15-1-3 (Required)
An empty throw (throw;) shall only be
used in the compound-statement of a
catch handler.
1 - Identical M15-1-3 -
15-3-1 (Required) Exceptions shall be
raised only after start-up and before
termination of the program.
1 - Identical M15-3-1 -
15-3-2 (Advisory) There should be at
least one exception handler to catch all
otherwise unhandled exceptions.
2 - Small differences A15-3-3 Obligation level
changed. Rule
extended to cover
multi-threading.
15-3-3 (Required) Handlers of
a function-try-block implementation of
a class constructor or destructor shall
not reference non-static members from
this class or its bases.
1 - Identical M15-3-3 -
15-3-4 (Required) Each exception
explicitly thrown in the code shall have
a handler of a compatible type in all call
paths that could lead to that point.
1 - Identical M15-3-4 -
15-
3-5 (Required) A class type exception
shall always be caught by reference.
2 - Small differences A15-3-5 Possibility to catch
by const reference
added
15-3-6 (Required) Where multiple
handlers are provided in a single try-
catch statement or function-try-block
for a derived class and some or all of
its bases, the handlers shall be ordered
most-derived to base class.
1 - Identical M15-3-6 -
15-3-7 (Required) Where multiple
handlers are provided in a single try-
catch statement or function-try-block,
any ellipsis (catch-all) handler shall
occur last.
1 - Identical M15-3-7 -
15-4-1 (Required) If a
function is declared with an exception-
specification, then all declarations of
the same function (in other translation
units) shall be declared with the same
set of type-ids.
3 - Significant differences A15-4-3 Dynamic exception
specification was
prohibited. Rule
was reformulated
in terms of the
noexcept
specification.
15-5-1 (Required) A class destructor
shall not exit with an exception.
3 - Significant differences A15-5-1 Rule significantly
extended
with other special
functions and
operators.
15-5-2 (Required) Where a function’s
declaration includes an exception-
specification, the function shall only be
capable of throwing exceptions of the
indicated type(s).
3 - Significant differences A15-4-2 Dynamic exception
specification was
prohibited. Rule
was reformulated
in terms of the
noexcept
specification.
15-5-3 (Required) The std::terminate()
function shall not be called implicitly .
2 - Small differences A15-5-3 Rationale and
example extended.
16-0-1 (Required) #include directives
in a file shall only be preceded by other
preprocessor directives or comments.
1 - Identical M16-0-1 -
16-0-2 (Required) Macros shall only
be #define’d or #undef’d in the global
namespace.
1 - Identical M16-0-2 -
16-0-3 (Required) #undef shall not be
used.
4 - Rejected - The
rule replaced with
global rule: A16-0-
1.
16-0-4 (Required) Function-like
macros shall not be defined.
4 - Rejected - The
rule replaced with
global rule: A16-0-
1.
16-0-5 (Required) Arguments to a
function-like macro shall not contain
tokens that look like preprocessing
directives.
1 - Identical M16-0-5 -
16-0-6 (Required) In the definition of
a function-like macro, each instance
of a parameter shall be enclosed in
parentheses, unless it is used as the
operand of # or ##.
1 - Identical M16-0-6 -
16-0-7 (Required) Undefined macro
identifiers shall not be used in #if or
#elif preprocessor directives, except as
operands to the defined operator.
1 - Identical M16-0-7 -
16-0-8 (Required) If the # token
appears as the first token on a line,
then it shall be immediately followed by
a pre-processing token.
1 - Identical M16-0-8 -
16-1-
1 (Required) The defined preprocessor
operator shall only be used in one of
the two standard forms.
1 - Identical M16-1-1 -
16-1-2 (Required) All #else, #elif and
#endif pre-processor directives shall
reside in the same file as the #if
or #ifdef directive to which they are
related.
1 - Identical M16-1-2 -
16-2-1 (Required) The pre-processor
shall only be used for file inclusion and
include guards.
4 - Rejected - The
rule replaced with
global rule: A16-0-
1.
16-2-2 (Required) C++ macros shall
only be used for include guards, type
qualifiers, or storage class specifiers.
4 - Rejected - The
rule replaced with
global rule: A16-0-
1.
16-2-3 (Required) Include guards shall
be provided
1 - Identical M16-2-3 -
16-2-4 (Required) The ’, ”, /* or //
characters shall not occur in a header
file name.
2 - Small differences A16-2-1 Merged with
MISRA Rule 16-2-
5.
16-2-5 (Advisory) The
character \should not occur in a header
file name.
2 - Small differences A16-2-1 Obligation
level changed to
“Required”.
Merged with
MISRA Rule 16-2-
4.
16-2-6 (Required) The #include
directive shall be followed by either a
<filename> or “filename” sequence.
4 - Rejected - These are the only
forms allowed by
the C++ Language
Standard; No need
for a new rule.
16-3-1 (Required) There shall be at
most one occurrence of the # or ##
operators in a single macro definition.
1 - Identical M16-3-1 -
16-3-2 (Advisory) The # and ##
operators should not be used.
1 - Identical M16-3-2 -
16-6-
1 (Required) All uses of the #pragma
directive shall be documented.
4 - Rejected - The #pragma
directive shall not
be used, see: A16-
7-1.
17-0-1 (Required) Reserved
identifiers, macros and functions in the
standard library shall not be defined,
redefined or undefined.
2 - Small differences A17-0-1 Example extended.
17-0-2 (Required) The names of
standard library macros and objects
shall not be reused.
1 - Identical M17-0-2 -
17-0-3 (Required) The names of
standard library functions shall not be
overridden.
1 - Identical M17-0-3 -
17-0-4 (Required) All library code shall
conform to MISRA C++.
4 - Rejected - The rule
replaced with A17-
0-2 saying that all
code shall conform
to
AUTOSAR C++14
Coding Guidelines.
17-0-5 (Required) The setjmp macro
and the longjmp function shall not be
used.
1 - Identical M17-0-5 -
18-0-1 (Required) The C library shall
not be used.
2 - Small differences A18-0-1 Rule reformulated.
18-0-2 (Required) The library functions
atof, atoi and atol from library <cstdlib>
shall not be used.
2 - Small differences A18-0-2
18-0-3 (Required) The library functions
abort, exit, getenv and system from
library <cstdlib> shall not be used.
1 - Identical M18-0-3 -
18-0-4 (Required) The time handling
functions of library <ctime> shall not be
used.
1 - Identical M18-0-4 -
18-0-5 (Required) The unbounded
functions of library <cstring> shall not
be used.
1 - Identical M18-0-5 -
18-2-1 (Required) The macro offsetof
shall not be used.
1 - Identical M18-2-1 -
18-4-1 (Required) Dynamic heap
memory allocation shall not be used.
4 - Rejected - Dynamic heap
memory allocation
usage is allowed
conditionally , see:
A18-5-1, A18-5-2,
A18-5-3.
18-7-1 (Required) The signal handling
facilities of <csignal> shall not be used.
1 - Identical M18-7-1 -
19-3-1 (Required) The error indicator
errno shall not be used.
1 - Identical M19-3-1 -
27-
0-1 (Required) The stream input/output
library <cstdio> shall not be used.
1 - Identical M27-0-1 -
Table B.1: MISRA C++
B.2 Traceability to HIC++ v4.0
The following table demonstrates the traceability to High Integrity C++ Coding Standard
Version 4.0 [9]. This is not considered as a reproduction, but a mean to compare the
two standards.
This document complies with the conditions of use of HIC++ v4.0, as any rule in this
document that is based on HIC++ v4.0 refers to the related HIC++ v4.0 rule.
HIC++ Rule: Relation type: Related
rule:
Comment:
1.1.1 Ensure that code complies with
the 2011 ISO C++ Language Standard.
2 - Small differences A1-1-1 Specified that the
code shall conform
to ISO/IEC
14882:2014
1.2.1 Ensure that all statements are
reachable.
2 - Small differences M0-1-1
1.2.2 Ensure that no expression or
sub-expression is redundant.
2 - Small differences M0-1-9
1.3.1 Do not use the increment
operator (++) on a variable of type bool
2 - Small differences M4-5-1
1.3.2 Do not use the register keyword. 2 - Small differences A7-1-4
1.3.3 Do not use the C Standard
Library .h headers
2 - Small differences A18-0-1
1.3.4 Do not use deprecated STL
library features
2 - Small differences A1-1-1, A18-
1-3, A18-9-1
1.3.5 Do not use throw exception
specifications.
2 - Small differences A15-4-1
2.1.1 Do not use tab characters in
source files.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
2.2.1 Do not use digraphs or trigraphs. 2 - Small differences A2-5-1, A2-
5-2
2.3.1 Do not use the C comment
delimiters /* ... */.
2 - Small differences M2-7-1
2.3.2 Do not comment out code. 2 - Small differences A2-7-2
2.4.1 Ensure that each identifier is
distinct from any other visible identifier.
2 - Small differences M2-10-1
2.5.1 Do not concatenate strings with
different encoding prefixes.
2 - Small differences A2-13-2
2.5.2 Do not use octal constants (other
than zero).
2 - Small differences M2-13-2
2.5.3 Use nullptr for the null pointer
constant.
2 - Small differences A4-10-1
3.1.1 Do not hide declarations. 2 - Small differences A2-10-1, A2-
10-6
3.2.1 Do not declare functions at block
scope.
2 - Small differences M3-1-2
3.3.1 Do not use variables with static
storage duration.
3 - Significant differences A3-3-2 Limited to
constant-initialized
objects only .
3.4.1 Do not return a reference or
a pointer to an automatic variable
defined within the function.
2 - Small differences M7-5-1
3.4.2 Do not assign the address of
a variable to a pointer with a greater
lifetime.
2 - Small differences M7-5-2
3.4.3 Use RAII for resources. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
rules for coding
patterns. Note that
usage of RAII is
recommended,
see: A15-1-4.
3.5.1 Do not make any assumptions
about the internal representation of a
value or object.
2 - Small differences A3-9-1,
M3-9-3, M5-
0-15, M5-0-
21, A9-5-1,
M18-2-1
4.1.1 Ensure that a function argument
does not undergo an array-to-pointer
conversion.
2 - Small differences M5-2-12
4.2.1 Ensure that the U suffix is applied
to a literal used in a context requiring
an unsigned integral expression.
2 - Small differences M2-13-2
4.2.2 Ensure that data loss does
not demonstrably occur in an integral
expression.
2 - Small differences A4-7-1, M5-
0-4, M5-0-6,
M5-0-9
4.3.1 Do not convert an expression of
wider floating point type to a narrower
floating point type.
2 - Small differences A4-7-1, M5-
0-6
4.4.1 Do not convert floating values to
integral types except through use of
standard library functions.
4 - Rejected Rules that
are related: M5-0-
3, M5-0-5, M5-0-6,
M5-0-7,
5.1.1 Use symbolic names instead of
literal values in code.
2 - Small differences A5-1-1
5.1.2 Do not rely on the sequence of
evaluation within an expression.
2 - Small differences A5-0-1
5.1.3 Use parentheses in expressions
to specify the intent of the expression.
2 - Small differences A5-
0-1, A5-2-6,
M5-2-10,
5.1.4 Do not capture variables implicitly
in a lambda.
2 - Small differences A5-1-2
5.1.5 Include a (possibly
empty) parameter list in every lambda
expression.
2 - Small differences A5-1-3
5.1.6 Do not code side effects into
the right-hand operands of: &&, ||,
sizeof, typeid or a function passed to
condition_variable::wait.
3 - Significant differences A5-3-1, M5-
3-4, M5-14-1
The condi-
tion_variable::wait
is not yet covered,
this will be ad-
dressed in future
when C++ libraries
are analyzed.
5.2.1 Ensure that pointer or array
access is demonstrably within bounds
of a valid object.
2 - Small differences A5-2-5
5.2.2 Ensure that functions do not call
themselves, either directly or indirectly .
2 - Small differences A7-5-2
5.3.1 Do not apply unary minus to
operands of unsigned type.
2 - Small differences M5-3-2
5.3.2 Allocate memory using new and
release it using delete.
2 - Small differences A18-5-1 Note that operators
new and
delete shall not be
used explicitly , see:
A18-5-2.
5.3.3 Ensure that the form of delete
matches the form of new used to
allocate the memory .
2 - Small differences A18-5-3 Note that operators
new and
delete shall not be
used explicitly , see:
A18-5-2.
5.4.1 Only use casting forms:
static_cast (excl. void*), dynamic_cast
or explicit constructor call.
2 - Small differences A5-2-1, A5-
2-2, A5-2-3,
A5-2-4
5.4.2 Do not cast an expression to an
enumeration type.
4 - Rejected It is allowed to cast
an expression to an
enumeration type,
but an expression
shall have a value
that corresponds to
an enumerator
of the enumeration,
see: A7-2-1.
5.4.3 Do not convert from a base class
to a derived class.
3 - Small differences M5-2-2, M5-
2-3, A5-2-1
Note that the
dynamic_cast is
unsuitable for use
with real-time
systems.
5.5.1 Ensure that the right hand
operand of the division or remainder
operators is demonstrably non-zero.
2 - Small differences A5-6-1
5.6.1 Do not use bitwise operators with
signed operands.
2 - Small differences M5-0-21
5.7.1 Do not write code that expects
floating point calculations to yield exact
results.
2 - Small differences M6-2-2
5.7.2 Ensure that a pointer to member
that is a virtual function is only
compared (==) with nullptr.
2 - Small differences A5-10-1
5.8.1 Do not use the conditional
operator (?:) as a sub-expression.
2 - Small differences A5-16-1
6.1.1 Enclose the body of a selection or
an iteration statement in a compound
statement.
2 - Small differences M6-3-1, M6-
4-1
6.1.2 Explicitly cover all paths through
multi-way selection statements.
2 - Small differences M6-4-2
6.1.3 Ensure that a non-empty case
statement block does not fall through
to the next label.
2 - Small differences M6-4-5
6.1.4 Ensure that a switch statement
has at least two case labels, distinct
from the default label.
2 - Small differences A6-4-1
6.2.1 Implement a loop that only uses
element values as a range-based loop.
2 - Small differences A6-5-1
6.2.2 Ensure that a loop has a
single loop counter, an optional control
variable, and is not degenerate.
2 - Small differences A6-5-2
6.2.3 Do not alter a control or counter
variable more than once in a loop.
3 - Significant differences M6-5-3 It is prohibited to
alter a control
or counter variable
within condition or
statement of a
loop.
6.2.4 Only modify a for loop counter in
the for expression.
2 - Small differences M6-5-3
6.3.1 Ensure that the label(s) for a
jump statement or a switch condition
appear later, in the same or an
enclosing block.
2 - Small differences M6-6-1
6.3.2 Ensure that execution of a
function with a non-void return type
ends in a return statement with a value.
2 - Small differences A8-4-2
6.4.1 Postpone variable definitions as
long as possible.
2 - Small differences M3-4-1
7.1.1 Declare each identifier on a
separate line in a separate declaration.
2 - Small differences A7-1-7
7.1.2 Use const whenever possible. 2 - Small differences A7-1-1, A7-
1-2
7.1.3 Do not place type
specifiers before non-type specifiers in
a declaration.
2 - Small differences A7-1-8
7.1.4 Place CV-qualifiers on the right
hand side of the type they apply to.
3 - Significant differences A7-1-3 Placement of cv-
qualifiers
is only restricted for
typedefs.
7.1.5 Do not inline large functions. 4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
7.1.6 Use class types or typedefs to
abstract scalar quantities and standard
integer types.
3 - Significant differences A3-9-1 AUTOSAR C++
Coding Guidelines
forces to use
typedefs for built-in
numerical types.
7.1.7 Use a trailing return type in
preference to type disambiguation
using typename.
2 - Small differences A8-2-1
7.1.8 Use auto id = expr when
declaring a variable to have the same
type as its initializer function call.
3 - Significant differences A7-1-5 The
rule is formulated
differently .
7.1.9 Do not explicitly specify the return
type of a lambda.
4 - Rejected T o avoid implicit
type conversion
return type of
lambda expression
needs to be
specified explicitly ,
see: A5-1-6.
7.1.10 Use static_assert for assertions
involving compile time constants.
3 - Significant differences A16-6-1 It is recommended
to use the
static_assert
instead of #error
directive.
7.2.1 Use an explicit enumeration base
and ensure that it is large enough to
store all enumerators.
2 - Small differences A7-2-2
7.2.2 Initialize none, the first only or all
enumerators in an enumeration.
2 - Small differences A7-2-4
7.3.1 Do not use using directives. 2 - Small differences M7-3-4
7.4.1 Ensure
that any objects, functions or types to
be used from a single translation unit
are defined in an unnamed namespace
in the main source file.
7.4.2 Ensure that an inline function, a
function template, or a type used from
multiple translation units is defined in a
single header file.
2 - Small differences A3-1-1, M3-
2-2
7.4.3 Ensure that an object or a
function used from multiple translation
units is declared in a single header file.
2 - Small differences A3-1-1, M3-
2-4
7.5.1 Do not use the asm declaration. 2 - Small differences A7-4-1
8.1.1 Do not use multiple levels of
pointer indirection.
3 - Significant differences A5-0-3 At most two levels
of
pointer indirection
are allowed.
8.2.1 Make parameter names absent
or identical in all declarations.
2 - Small differences M3-9-1
8.2.2 Do not declare functions with an
excessive number of parameters.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
8.2.3 Pass small objects with a trivial
copy constructor by value.
4 - Rejected The rule is vague,
“small” has no
technical meaning.
8.2.4 Do not pass std::unique_ptr by
const reference.
3 - Significant differences A8-4-11, A8-
4-12
A8-4-12 cov-
ers how to pass a
std::unique_ptr,
A8-4-11 cov-
ers when not
to pass by
std::unique_ptr.
8.3.1 Do not write functions
with an excessive McCabe Cyclomatic
Complexity .
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
8.3.2 Do not write functions with a high
static program path count.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
8.3.3 Do not use default arguments. 4 - Rejected Using
default arguments
is allowed with
some restrictions,
see e.g. M8-3-1.
8.3.4 Define =delete functions with
parameters of type rvalue reference to
const.
2 - Small differences A13-3-1,
A18-9-3
8.4.1 Do not access an invalid object or
an object with indeterminate value.
2 - Small differences A8-5-0, A12-
8-3
8.4.2 Ensure that a braced aggregate
initializer matches the layout of the
aggregate object.
2 - Small differences M8-5-2
9.1.1 Declare
static any member function that does
not require this. Alternatively , declare
const any member function that does
not modify the externally visible state
of the object.
2 - Small differences M9-3-3
9.1.2 Make default arguments the
same or absent when overriding a
virtual function.
2 - Small differences M8-3-1
9.1.3 Do not return non-const handles
to class data from const member
functions.
2 - Small differences M9-3-1, A9-
3-1
9.1.4 Do not write member functions
which return non-const handles to
data less accessible than the member
function.
3 - Significant differences A9-3-1 It
is allowed to return
non-const handles
to static data.
9.1.5 Do not introduce virtual functions
in a final class.
2 - Small differences A10-3-3
9.2.1 Declare bit-fields
with an explicitly unsigned integral or
enumeration type.
3 - Significant differences A9-6-1 Any
type with a defined
size is allowed to
be used for a bit-
field.
10.1.1 Ensure that access to base
class subobjects does not require
explicit disambiguation.
3 - Significant differences A10-1-1 Inheritance
from more than one
base class is
prohibited.
10.2.1 Use
the override special identifier when
overriding a virtual function.
2 - Small differences A10-3-2
10.3.1 Ensure that a derived class has
at most one base class which is not an
interface class.
2 - Small differences A10-1-1 Note that
the definition of an
interface changed,
see: Interface-
Class.
11.1.1 Declare all data members
private.
2 - Small differences M11-0-1
11.2.1 Do not use friend declarations. 2 - Small differences A11-3-1
12.1.1 Do not declare implicit user
defined conversions.
3 - Significant differences A12-1-4,
A13-5-2
12.2.1 Declare virtual, private or
protected the destructor of a type used
as a base class.
3 - Significant differences A12-4-1 Destructor of
a base class shall
be public virtual,
public override or
protected
non-virtual.
12.3.1 Correctly declare overloads for
operator new and delete.
2 - Small differences A18-5-11
12.4.1 Do not use the dynamic type
of an object unless the object is fully
constructed.
2 - Small differences M12-1-1
12.4.2 Ensure that a constructor
initializes explicitly all base classes and
non-static data members.
2 - Small differences A12-1-1
12.4.3 Do not specify both an NSDMI
and a
member initializer in a constructor for
the same non static member.
2 - Significant differences A12-1-2 Using both NSDMI
and
member initializer
list in one class is
not allowed.
12.4.4 Write
members in an initialization list in the
order in which they are declared.
2 - Small differences A8-5-1
12.4.5 Use delegating constructors to
reduce code duplication.
2 - Small differences A12-1-5
12.5.1 Define
explicitly =default or =delete implicit
special member functions of concrete
classes.
3 - Significant differences A12-0-1
12.5.2 Define special members
=default if the behavior is equivalent.
2 - Small differences A12-7-1
12.5.3 Ensure that
a user defined move/copy constructor
only moves/copies base and member
objects.
2 - Small differences A12-8-1
12.5.4 Declare noexcept the move
constructor and move assignment
operator.
3 - Significant differences A15-5-1 AUTOSAR C++
Coding Guidelines
requires
additional functions
to be noexcept.
12.5.5 Correctly reset moved-from
handles to resources in the move
constructor.
2 - Small differences A12-8-1
12.5.6 Use an atomic, non-throwing
swap operation to implement the copy
and move assignment operators.
2 - Small differences A12-8-2
12.5.7 Declare assignment operators
with the ref-qualifier &.
2 - Small differences A12-8-7
12.5.8 Make the copy assignment
operator of an abstract class protected
or define it =delete.
3 - Significant differences A12-8-6 AUTOSAR C++
Coding Guidelines
requires
additional functions
to be comply with
this rule.
13.1.1 Ensure that all overloads of a
function are visible from where it is
called.
2 - Small differences A7-3-1
13.1.2 If a member of a set of
callable functions includes a universal
reference parameter, ensure that one
appears in the same position for all
other members.
3 - Significant differences A13-3-1 A function taking
“forwarding
reference” shall not
be overloaded.
13.2.1 Do not overload operators with
special semantics.
2 - Small differences M5-2-11,
M5-3-3
13.2.2 Ensure that the return type of an
overloaded binary operator matches
the built-in counterparts.
2 - Small differences A13-
2-1, A13-2-
2, A13-2-3
13.2.3 Declare binary arithmetic and
bitwise operators as non-members.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
13.2.4 When overloading the subscript
operator (operator[]) implement both
const and non-const versions.
2 - Small differences A13-5-1
13.2.5 Implement a minimal set of
operators and use them to implement
all other related operators.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
14.1.1 Use variadic templates rather
than an ellipsis.
3 - Significant differences A8-4-1 AUTOSAR C++
Coding Guidelines
prohibits usage of
variadic
arguments.
14.2.1 Declare template
specializations in the same file as the
primary template they specialize.
3 - Significant differences A14-7-2 Allowed to declare
in a header file
that declares user-
defined
type, for which the
specialization is
declared.
14.2.2 Do not explicitly specialize a
function template that is overloaded
with other templates.
3 - Significant differences A14-8-2 Function templates
specialization is
forbidden.
14.2.3 Declare extern an explicitly
instantiated template.
4 - Rejected
15.1.1 Only use instances of
std::exception for exceptions.
2 - Small differences A15-1-1
15.2.1 Do not throw an exception from
a destructor.
2 - Small differences A15-5-1
15.3.1 Do
not access non-static members from a
catch handler of constructor/destructor
function try block.
2 - Small differences M15-3-3
15.3.2 Ensure that a program does not
result in a call to std::terminate.
2 - Small differences A15-5-2,
A15-5-3
16.1.1 Use the preprocessor only
for implementing include guards, and
including header files with include
guards.
3 - Significant differences A16-0-1 Conditional
and unconditional
file inclusion is
allowed.
16.1.2 Do not include a path specifier
in filenames supplied in #include
directives.
3 - Significant differences A16-2-1 Path specifier /is
allowed to specify
a path relative to
path passed to the
compiler.
16.1.3 Match the filename in a #include
directive to the one on the file system.
4 - Rejected
16.1.4 Use <> brackets for system and
standard library headers. Use quotes
for all other headers.
4 - Rejected The rule defines a
coding style.
Anyway ,
these are the only
forms allowed by
the C++ Language
Standard. No need
for a new rule.
16.1.5 Include directly the
minimum number of headers required
for compilation.
4 - Rejected There shall be
no unused include
directives, however
all needed headers
shall be included
explicitly . See:
A16-2-2, A16-2-3.
17.1.1 Do not use std::vector<bool>. 2 - Small differences A18-1-2
17.2.1 Wrap use of the C Standard
Library .
2 - Small differences A17-1-1
17.3.1 Do not use std::move on objects
declared with const or const & type.
2 - Small differences A18-9-3
17.3.2 Use std::forward to forward
universal references.
2 - Small differences A18-9-2
17.3.3 Do not subsequently use the
argument to std::forward.
2 - Small differences A18-9-4
17.3.4 Do not create smart pointers of
array type.
3 - Significant differences A18-1-4 Rule reformulated
to better capture
the problem cases
and to allow use of
smart pointer
specializations for
array types.
17.3.5 Do not create an rvalue
reference of std::array .
4 - Rejected The rule is only a
hint
saying that passing
std::array by rvalue
reference would be
less efficient
than passing it by
reference.
However, usage
depends on the
case, and it should
be allowed to pass
std::array by rvalue
reference.
17.4.1 Use const container calls when
result is immediately converted to a
const iterator.
2 - Small differences A23-0-1
17.4.2 Use API calls that construct
objects in place.
3 - Significant differences A18-5-2 A18-5-
2 prohibits explicit
calls to new and
delete operators,
std::make_shared,
std::make_unique
and similar
constructions are
recommended.
17.5.1 Do not ignore the
result of std::remove, std::remove_if or
std::unique.
2 - Small differences A0-1-2
18.1.1 Do not use platform specific
multi-threading facilities.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.2.1 Use high_integrity::thread in
place of std::thread.
4 - Rejected The
high_integrity::thread
is not part of the
C++ Language
Standard.
18.2.2 Synchronize access to data
shared between threads using a single
lock.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.2.3 Do not share volatile data
between threads.
3 - Significant differences A2-11-1 Volatile keyword
forbidden.
18.2.4 Use std::call_once rather than
the Double-Checked Locking pattern.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.1 Within the scope of a lock,
ensure that no static path results in a
lock of the same mutex.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.2 Ensure that order of nesting of
locks in a project forms a DAG.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.3 Do not use
std::recursive_mutex.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.4 Only use std::unique_lock when
std::lock_guard cannot be used.
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.5 Do not access the members of
std::mutex directly .
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.3.6 Do not use relaxed atomics. 5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
18.4.1 Do
not use std::condition_variable_any on
a std::mutex
5 - Not yet analyzed The “Concurrency”
chapter is not yet
covered, this will
be addressed in
future.
Table B.2: HIC++ v4.0
B.3 Traceability to JSF
The following table demonstrates the traceability to Joint Strike Fighter Air Vehicle C++
Coding Standard [8]. This is not considered as a reproduction, but a mean to compare
the two standards.
Note that the copyright of JSF-AV 2005 allows an unlimited distribution anyway .
JSF Rule: Relation type: Related
rule:
Comment:
AV Rule 8 All code shall conform to
ISO/IEC 14882:2002(E) standard C++.
2 - Small differences A1-1-1
AV Rule 9 Only those characters
specified in the C++ basic source
character set will be used. [...].
2 - Small differences A2-3-1
AV Rule 10 Values of character types
will be restricted to a defined and
documented subset of ISO 10646-1.
4 - Rejected Source
files encoding is
too restrictive and
not covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 11 Trigraphs will not be used. 2 - Small differences A2-5-1
AV Rule 12 The following digraphs will
not be used [...].
2 - Small differences A2-5-2
AV Rule 13 Multi-byte characters and
wide string literals will not be used.
4 - Rejected Agreed for wchar_t
type only , A2-13-3.
AV Rule 14 Literal suffixes shall
use uppercase rather than lowercase
letters.
2 - Small differences M2-13-4
AV Rule 15 Provision shall be
made for run-time checking (defensive
programming).
2 - Small differences M0-3-1
AV Rule 16 Only DO-178B level A [15]
certifiable or SEAL 1 C/C++ libraries
shall be used with safety-critical (i.e.
SEAL 1) code.
4 - Rejected JSF-specific rule.
AV Rule 17 The error indicator errno
shall not be used.
2 - Small differences M19-3-1
AV Rule 18 The macro offsetof, in
library <stddef.h>, shall not be used.
2 - Small differences M18-2-1
AV Rule 19 <locale.h> and the
setlocale function shall not be used.
2 - Small differences A18-0-3
AV Rule 20 The setjmp macro and the
longjmp function shall not be used.
2 - Small differences M17-0-5
AV Rule 21 The signal handling
facilities of <signal.h> shall not be
used.
2 - Small differences M18-7-1
AV Rule 22 The input /output library
<stdio.h> shall not be used.
2 - Small differences M27-0-1
AV Rule 23 The library functions atof,
atoi and atol from library <stdlib.h>
shall not be used.
2 - Small differences A18-0-2
AV Rule 24 The library functions abort,
exit, getenv and system from library
<stdlib.h> shall not be used.
2 - Small differences M18-0-3
AV Rule 25
The time handling functions of library
<time.h> shall not be used.
2 - Small differences M18-0-4
AV Rule 26 Only the following pre-
processor directives shall be used:
1. #ifndef 2. #define 3. #endif 4.
#include.
2 - Small differences A16-0-1
AV Rule 27 #ifndef, #define and #endif
will be used to prevent
multiple inclusions of the same header
file. Other techniques to prevent the
multiple inclusions of header files will
not be used.
2 - Small differences A16-0-1,
M16-2-3
AV Rule 28 The #ifndef and #endif pre-
processor directives will only be used
as defined in AV Rule 27 to prevent
multiple inclusions of the same header
file.
2 - Small differences A16-0-1
AV Rule 29 The #define pre-processor
directive shall not be used to create
inline macros. Inline functions shall be
used instead.
2 - Small differences A16-0-1
AV Rule 30 The #define pre-processor
directive shall not be used to define
constant values. Instead, the const
qualifier shall
be applied to variable declarations to
specify constant values.
2 - Small differences A16-0-1
AV Rule 31 The #define pre-processor
directive will only be used as part
of the technique to prevent multiple
inclusions of the same header file.
2 - Small differences A16-0-1
AV Rule 32 The #include pre-
processor directive will only be used to
include header (*.h) files.
2 - Small differences A16-0-1
AV Rule 33 The #include directive
shall use the <filename.h> notation to
include header files.
4 - Rejected Including
files using quotes is
also possible.
AV Rule 34 Header files should contain
logically related declarations only .
2 - Small differences A3-3-1
AV Rule 35 A header file will contain
a mechanism that prevents multiple
inclusions of itself.
2 - Small differences M16-2-3
AV Rule 36 Compilation dependencies
should be minimized when possible.
4 - Rejected The
rule is vague; more
precisely explained
by AV Rules 37 and
38.
AV Rule 37 Header (include) files
should include only those header
files that are required for them to
successfully compile. Files that are
only used by the associated .cpp file
should be placed in the .cpp file - not
the .h file.
2 - Small differences A16-2-2,
A16-2-3
AV Rule 38 Declarations of classes
that are only accessed via pointers (*)
or references (&) should be supplied
by forward headers that contain only
forward declarations.
3 - Significant differences A16-2-3 Forward
declarations
considered as
a possible solution
for unnecessarry
inclusions.
AV Rule 39 Header files (*.h) will not
contain non-const variable definitions
or function definitions.
2 - Small differences M3-2-4, A3-
3-1
AV Rule 40 Every implementation file
shall include the header files that
uniquely define the inline functions,
types, and templates used.
2 - Small differences M3-2-4, A3-
3-1
AV Rule 41 Source lines will be kept to
a length of 120 characters or less.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 42
Each expression-statement will be on
a separate line.
2 - Small differences A7-1-7
AV Rule 43 T abs should be avoided. 4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 44 All indentations will be at
least two spaces and be consistent
within the same source file.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 45 All words in an identifier will
be separated by the “_” character.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 46 User-specified identifiers
(internal and external) will not rely
on significance of more than 64
characters.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 47 Identifiers will not begin
with the underscore character “_”.
3 - Significant differences A17-0-1
AV Rule 48 Identifiers will not differ by:
(a) Only a mixture of case, (b) The
presence/absence of the underscore
character, (c) The interchange of the
letter “O”, with the number “0” or the
letter “D”, (d) The interchange of the
letter “I”, with the number “1” or the
letter “l”, (e) The interchange of the
letter “S” with the number “5”, (f) The
interchange of the letter “Z” with the
number “2”, (g) The interchange of the
letter “n” with the letter “h”.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 49 All acronyms in an identifier
will be composed of uppercase letters.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 50 The first word of the name
of a class, structure, namespace,
enumeration, or type created with
typedef will begin with an uppercase
letter. All others letters will be
lowercase.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 51 All letters contained in
function and variable names will be
composed entirely of lowercase letters.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 52 Identifiers for constant and
enumerator values shall be lowercase.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 53 Header files will always
have a file name extension of “.h”.
3 - Significant differences A3-1-2
AV Rule 53.1 The following character
sequences shall not appear in header
file names: ’, \, /*, //, or ”.
2 - Small differences A16-2-1
AV Rule 54 Implementation files will
always have a file name extension of
“.cpp”.
2 - Small differences A3-1-3
AV Rule 55 The name of a header
file should reflect the logical entity for
which it provides declarations.
2 - Small differences A2-8-1
AV Rule 56 The
name of an implementation file should
reflect the logical entity for which it
provides definitions and have a “.cpp”
extension (this name will normally be
identical to the header file that provides
the corresponding declarations.)
2 - Small differences A2-8-2
AV Rule 57 The public, protected, and
private sections
of a class will be declared in that order
(the public section is declared before
the protected section which is declared
before the private section).
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 58 When declaring and
defining functions with more than two
parameters, the leading parenthesis
and the first argument will be written
on the same line as the function
name. Each additional argument will
be written on a separate line (with the
closing parenthesis directly after the
last argument).
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 59 The statements forming
the body of an if, else if, else, while,
do...while or for statement shall always
be enclosed in braces, even if the
braces form an empty block.
2 - Small differences M6-3-1
AV Rule 60 Braces (“{}”) which enclose
a block will be placed in the same
column, on separate lines directly
before and after the block.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 61 Braces (“{}”) which enclose
a block will have nothing else on the
line except comments (if necessary).
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 62 The dereference operator
“*” and the address-of operator “&” will
be directly connected with the type-
specifier.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 63 Spaces will not be used
around “. ” or “->”, nor between unary
operators and operands.
4 - Rejected Coding style is not
covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 64 A class interface should be
complete and minimal.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 65 A structure should be used
to model an entity that does not require
an invariant.
3 - Significant differences A11-0-2
AV Rule 66 A class should be used
to model an entity that maintains an
invariant.
3 - Significant differences A11-0-1
AV Rule 67 Public and protected data
should only be used in structs - not
classes.
2 - Small differences M11-0-1
AV Rule 68 Unneeded
implicitly generated member functions
shall be explicitly disallowed.
3 - Significant differences A12-0-1 It
is allowed to follow
both “Rule of zero”
and “Rule of five”.
AV Rule 69 A member function that
does not affect the state of an object
(its instance variables) will be declared
const.
2 - Small differences M9-3-3
AV Rule 70 A class will have friends
only when a function or object requires
access to the private elements of the
class, but is unable to be a member
of the class for logical or efficiency
reasons.
4 - Rejected Friend declarations
are prohibited, see:
A11-3-1.
AV Rule 70.1 An object shall not
be improperly used before its lifetime
begins or after its lifetime ends.
2 - Small differences A3-8-1, A5-
1-4, M7-5-1,
M7-5-2, A7-
5-1, M12-1-1
AV Rule 71 Calls to an externally
visible operation of an object, other
than its constructors, shall not be
allowed until the object has been fully
initialized.
2 - Small differences A12-1-1,
M12-1-1
AV Rule 71.1 A class’s virtual functions
shall not be invoked from its destructor
or any of its constructors.
2 - Small differences M12-1-1
AV Rule
72 The invariant for a class should be:
(a) a part of the postcondition of every
class constructor, (b) a part of the
precondition of the class destructor (if
any), (c) a part of the precondition and
postcondition of every other publicly
accessible operation.
3 - Significant differences A15-2-
2, M11-0-1,
M9-3-1, A9-
3-1
No enforcement on
pre/postcondition
checking in the
Coding Guidelines
AV Rule 73 Unnecessary default
constructors shall not be defined.
4 - Rejected No rule needed.
AV Rule 74 Initialization of nonstatic
class members will be performed
through the member initialization list
rather than through assignment in the
body of a constructor.
2 - Small differences A12-6-1
AV Rule 75 Members
of the initialization list shall be listed in
the order in which they are declared in
the class.
2 - Small differences A8-5-1
AV Rule 76 A copy constructor and an
assignment operator shall be declared
for classes that contain pointers to data
items or nontrivial destructors.
2 - Small differences A12-7-1
AV Rule 77 A copy constructor shall
copy all data members and bases
that affect the class invariant (a data
element representing a cache, for
example, would not need to be copied).
2 - Small differences A12-8-1
AV Rule 77.1 The definition of a
member function shall not contain
default arguments that produce a
signature identical to that of the
implicitly-declared copy constructor for
the corresponding class/structure.
4 - Rejected No ambiguity in
C++14, see
ISO/IEC
14882:2014 C++14
12.8 [class.copy]2
AV Rule 78 All base classes with a
virtual function shall define a virtual
destructor.
2 - Small differences A12-4-1
AV Rule 79 All resources acquired by
a class shall be released by the class’s
destructor.
2 - Small differences A15-1-4,
A18-5-2
AV Rule 80 The default copy and
assignment operators will be used for
classes when those operators offer
reasonable semantics.
2 - Small differences A12-0-1
AV Rule 81 The assignment operator
shall handle self-assignment correctly .
2 - Small differences A12-8-5
AV Rule 82 An assignment operator
shall return a reference to *this.
2 - Small differences A13-2-1
AV Rule 83 An assignment operator
shall assign all data members and
bases that affect the class invariant (a
data element representing a cache, for
example, would not need to be copied).
2 - Small differences A6-2-1
AV Rule 84 Operator overloading
will be used sparingly and in a
conventional manner.
4 - Rejected The rule is vague.
Design
principle; There is
no need for a new
rule.
AV Rule 85 When two operators are
opposites (such as == and !=), both will
be defined and one will be defined in
terms of the other.
2 - Small differences A13-5-4
AV Rule 86 Concrete types should be
used to represent simple independent
concepts.
4 - Rejected The rule is vague.
Design
principle; There is
no need for a new
rule.
AV Rule 87 Hierarchies should be
based on abstract classes.
2 - Small differences A10-4-1
AV Rule 88 Multiple inheritance shall
only be allowed in the following
restricted form: n interfaces plus m
private implementations, plus at most
one protected implementation.
3 - Significant differences A10-1-1
AV Rule 88.1 A stateful virtual base
shall be explicitly declared in each
derived class that accesses it.
4 - Rejected Virtual inheritance
should not be used,
see: M10-1-1.
AV Rule 89 A base class shall not be
both virtual and non-virtual in the same
hierarchy .
2 - Small differences M10-1-3
AV Rule 90 Heavily used
interfaces should be minimal, general
and abstract.
4 - Rejected The rule is vague.
Design
principle; There is
no need for a new
rule.
AV Rule 91 Public inheritance will be
used to implement “is-a” relationships.
2 - Small differences A10-0-1
AV Rule 92 A subtype (publicly
derived classes) will conform to the
following guidelines with respect to all
classes involved in the polymorphic
assignment of different subclass
instances to the same variable or
parameter during the execution of the
system: (1) Preconditions of derived
methods must be at least as weak as
the preconditions of the methods they
override. (2) Postconditions of derived
methods must be at least as strong
as the postconditions of the methods
they override. In other words, subclass
methods must expect less and deliver
more than the base class methods
they override. This rule implies that
subtypes will conform to the Liskov
Substitution Principle.
4 - Rejected The rule is vague.
Design
principle; There is
no need for a new
rule.
AV Rule 93 “has-a” or “is-implemented-
in-terms-of” relationships will be
modeled through membership or non-
public inheritance.
2 - Small differences A10-0-2
AV Rule 94 An inherited nonvirtual
function shall not be redefined in a
derived class.
2 - Small differences A10-2-1
AV Rule 95 An inherited default
parameter shall never be redefined.
2 - Small differences M8-3-1
AV Rule 96 Arrays shall not be treated
polymorphically .
2 - Small differences A5-0-4
AV Rule 97 Arrays shall not be used
in interfaces. Instead, the Array class
should be used.
2 - Small differences M5-2-12
AV Rule 97.1 Neither operand of an
equality operator (== or !=) shall be a
pointer to a virtual member function.
3 - Significant differences A5-10-1 Testing for equality
with null-
pointer-constant is
allowed.
AV Rule 98 Every nonlocal name,
except main(), should be placed in
some namespace.
2 - Small differences M7-3-1
AV Rule 99 Namespaces will not be
nested more than two levels deep.
4 - Rejected Not compliant with
the
AUTOSAR general
requirements.
AV Rule 100
Elements from a namespace should
be selected as follows: (a) using
declaration or explicit qualification for
few (approximately five) names, (b)
using directive for many names.
3 - Significant differences M7-3-4, M7-
3-6
AV Rule 101 Templates shall be
reviewed as follows: (1) with respect
to the template in isolation considering
assumptions or requirements placed
on its arguments, (2) with respect
to all functions instantiated by actual
arguments.
4 - Rejected Rule concerns
code review
process.
AV Rule 102 Template tests shall be
created to cover all actual template
instantiations.
4 - Rejected Rule concerns test
process.
AV Rule 103 Constraint checks should
be applied to template arguments.
2 - Small differences A14-1-1
AV Rule 104 A template specialization
shall be declared before its use.
2 - Small differences A14-7-2
AV Rule 105 A template definition’s
dependence
on its instantiation contexts should be
minimized.
4 - Rejected This rule is vague.
“Minimized” has no
technical meaning.
AV Rule 106 Specializations for pointer
types should be made where
appropriate.
4 - Rejected This rule is vague.
“Where
appropriate”
has no technical
meaning.
AV Rule 107 Functions shall always be
declared at file scope.
2 - Small differences M3-1-2
AV Rule 108 Functions with variable
numbers of arguments shall not be
used.
2 - Small differences A8-4-1
AV Rule 109 A function definition
should not be placed in a class
specification unless the function is
intended to be inlined.
3 - Significant differences A3-1-5 Also included
template methods
and methods of
template classes.
AV Rule 110 Functions with more than
7 arguments will not be used.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 111 A function shall not return
a pointer or reference to a non-static
local object.
2 - Small differences M7-5-2
AV Rule
112 Function return values should not
obscure resource ownership.
2 - Small differences M9-3-1, A9-
3-1, A20-8-
2, A20-8-3
AV Rule 113 Functions will have a
single exit point.
4 - Rejected See Single-
point-of-exit.
AV Rule 114 All exit points of value-
returning functions shall be through
return statements.
2 - Small differences A8-4-2
AV Rule 115 If a function returns error
information, then that error information
will be tested.
2 - Small differences A8-4-2
AV Rule 116 Small, concrete-type
arguments (two or three words in size)
should be passed by value if changes
made to formal parameters should not
be reflected in the calling function.
2 - Small differences A8-4-7
AV Rule 117 Arguments should be
passed by reference if NULL values
are not possible.
2 - Small differences A8-4-10
AV Rule 117.1 An object should be
passed as const T& if the function
should not change the value of the
object.
2 - Small differences A8-4-7
AV Rule 117.2 An object should be
passed as T& if the function may
change the value of the object.
2 - Small differences A8-4-9
AV Rule 118 Arguments should be
passed via pointers if NULL values are
possible.
3 - Significant differences A8-4-10
AV Rule 118.1 An object should be
passed as const T* if its value should
not be modified.
3 - Significant differences A8-4-10
AV Rule 118.2 An object should be
passed as T* if its value may be
modified.
3 - Significant differences A8-4-10
AV Rule 119 Functions shall not call
themselves, either directly or indirectly
(i.e. recursion shall not be allowed).
2 - Small differences A7-5-2
AV Rule 120 Overloaded operations
or methods should form families that
use the same semantics, share the
same name, have the same purpose,
and that are differentiated by formal
parameters.
4 - Rejected This rule is vague.
It is not a coding
rule.
AV Rule 121 Only functions with 1
or 2 statements should be considered
candidates for inline functions.
4 - Rejected Code metrics are
not covered
by AUTOSAR C++
Coding Guidelines.
AV Rule 122 Trivial accessor and
mutator functions should be inlined.
2 - Small differences A3-1-6
AV Rule 123 The number of accessor
and mutator functions should be
minimized.
4 - Rejected This rule is vague.
It is not a coding
rule.
AV Rule 124 Trivial forwarding
functions should be inlined.
4 - Rejected Forwarding
functions are
mostly
templates and they
most likely will be
inlined.
AV Rule 125 Unnecessary temporary
objects should be avoided.
2 - Small differences M0-1-9, A1-
4-3
AV Rule 126 Only valid C++ style
comments (//) shall be used.
2 - Small differences M2-7-1
AV Rule 127 Code that is not used
(commented out) shall be deleted.
2 - Small differences A2-7-2
AV Rule 128 Comments that document
actions or sources (e.g. tables, figures,
paragraphs, etc.) outside of the file
being documented will not be allowed.
2 - Small differences A2-7-5
AV Rule 129 Comments in header files
should describe the externally visible
behavior of the functions or classes
being documented.
3 - Significant differences A2-7-3
AV Rule 130 The purpose of every
line of executable code should be
explained by a comment, although one
comment may describe more than one
line of code.
4 - Rejected
AV Rule 131 One should avoid stating
in comments what is better stated in
code (i.e. do not simply repeat what
is in the code).
4 - Rejected
AV Rule 132 Each variable declaration,
typedef, enumeration value, and
structure member will be commented.
4 - Rejected
AV Rule 133 Every source file will
be documented with an introductory
comment that
provides information on the file name,
its contents, and any program-required
information (e.g. legal statements,
copyright information, etc).
4 - Rejected
AV Rule 134 Assumptions (limitations)
made by
functions should be documented in the
function’s preamble.
3 - Significant differences A2-7-3
AV Rule 135 Identifiers in an inner
scope shall not use the same name
as an identifier in an outer scope, and
therefore hide that identifier.
2 - Small differences A2-10-1
AV Rule 136 Declarations should be at
the smallest feasible scope.
2 - Small differences M3-4-1
AV Rule 137 All declarations at file
scope should be static where possible.
3 - Significant differences A3-3-1
AV Rule 138 Identifiers shall not
simultaneously have both internal and
external linkage in the same translation
unit.
2 - Small differences M3-3-2
AV Rule 139 External objects will not
be declared in more than one file.
2 - Small differences M3-2-3
AV Rule 140 The register storage class
specifier shall not be used.
2 - Small differences A7-1-4
AV Rule 141 A class, structure, or
enumeration will not be declared in the
definition of its type.
2 - Small differences A7-1-9
AV Rule 142 All variables shall be
initialized before use.
2 - Small differences A8-5-0
AV Rule 143 Variables will not be
introduced until they can be initialized
with meaningful values.
2 - Small differences M3-4-1
AV Rule 144 Braces shall be used
to indicate and match the structure in
the non-zero initialization of arrays and
structures.
2 - Small differences M8-5-2
AV Rule 145 In an enumerator list,
the “=” construct shall not be used to
explicitly initialize members other than
the first, unless all items are explicitly
initialized.
2 - Small differences A7-2-4
AV Rule 146
Floating point implementations shall
comply with a defined floating point
standard. The standard that will be
used is the ANSI/IEEE Std 754
2 - Small differences A0-4-1
AV Rule
147 The underlying bit representations
of floating point numbers shall not be
used in any way by the programmer.
2 - Small differences M3-9-3
AV Rule 148 Enumeration types shall
be used instead of integer types (and
constants) to select from a limited
series of choices.
2 - Small differences A7-2-5
AV Rule 149 Octal constants (other
than zero) shall not be used.
2 - Small differences M2-13-2
AV Rule 150 Hexadecimal constants
will be represented using all uppercase
letters.
2 - Small differences A2-13-5
AV Rule 151 Numeric values in code
will not be used; symbolic values will
be used instead.
2 - Small differences A5-1-1
AV Rule 151.1 A string literal shall not
be modified.
2 - Small differences A2-13-4
AV Rule
152 Multiple variable declarations shall
not be allowed on the same line.
2 - Small differences A7-1-7
AV Rule 153 Unions shall not be used. 2 - Small differences A9-5-1
AV Rule 154
Bit-fields shall have explicitly unsigned
integral or enumeration types only .
3 - Significant differences A9-6-1 Any
type with a defined
size is allowed to
be used for a bit-
field.
AV Rule 155 Bit-fields will not be used
to pack data into a word for the sole
purpose of saving space.
2 - Small differences A9-6-2
AV Rule 156 All the members of a
structure (or class) shall be named and
shall only be accessed via their names.
2 - Small differences A12-0-2
AV Rule 157 The right hand operand of
a && or ||operator shall not contain side
effects.
2 - Small differences M5-14-1
AV Rule 158 The operands of a logical
&& or ||shall be parenthesized if the
operands contain binary operators.
2 - Small differences A5-2-6
AV Rule 159 Operators ||, &&, and
unary & shall not be overloaded.
2 - Small differences M5-2-11,
M5-3-3
AV Rule 160 An assignment
expression shall be used only as the
expression in an expression statement.
2 - Small differences M6-2-1
AV Rule 162 Signed and unsigned
values shall not be mixed in arithmetic
or comparison operations.
2 - Small differences M5-0-4, M5-
0-9
AV Rule 163 Unsigned arithmetic shall
not be used.
2 - Small differences M5-0-4, M5-
0-9
AV Rule 164 The right hand operand of
a shift operator shall lie between zero
and one less than the width in bits of
the left-hand operand (inclusive).
2 - Small differences M5-8-1
AV Rule 164.1 The left-hand operand
of a right-shift operator shall not have a
negative value.
2 - Small differences M5-8-1
AV Rule 165 The unary minus operator
shall not be applied to an unsigned
expression.
2 - Small differences M5-3-2
AV Rule 166 The sizeof operator
will not be used on expressions that
contain side effects.
2 - Small differences M5-3-4
AV Rule 167 The implementation of
integer division in the chosen compiler
shall be determined, documented and
taken into account.
3 - Significant differences A0-4-2
AV Rule 168 The comma operator shall
not be used.
2 - Small differences M5-18-1
AV Rule 169 Pointers to pointers
should be avoided when possible.
3 - Significant differences A5-0-3
AV Rule 170 More than 2 levels of
pointer indirection shall not be used.
3 - Significant differences A5-0-3
AV Rule 171 Relational operators shall
not be applied to pointer types except
where both operands are of the same
type and point to: (a) the same object,
(b) the same function, (c) members of
the same object, or (d) elements of the
same array (including one past the end
of the same array).
2 - Small differences M5-0-18
AV Rule 173 The address of an object
with automatic storage shall not be
assigned to an object which persists
after the object has ceased to exist.
2 - Small differences M7-5-2
AV Rule 174 The null pointer shall not
be de-referenced.
2 - Small differences A5-3-2
AV Rule 175 A pointer shall not be
compared to NULL or be assigned
NULL; use plain 0 instead.
4 - Rejected Only nullptr
constant shall be
used, see: A4-10-
1.
AV Rule 176 A typedef will be
used to simplify program syntax when
declaring function pointers.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
AV Rule 177 User-defined conversion
functions should be avoided.
2 - Small differences A13-5-3
AV Rule 178 Down casting (casting
from base to derived class) shall only
be allowed through one of the following
mechanism: (a) Virtual functions that
act like dynamic casts (most likely
useful in relatively simple cases), (b)
Use of the visitor (or similar) pattern
(most likely useful in complicated
cases)
2 - Small differences M5-2-2, A5-
2-6
AV Rule 179 A pointer to a virtual
base class shall not be converted to a
pointer to a derived class.
2 - Small differences M5-2-3
AV Rule 180 Implicit conversions that
may result in a loss of information shall
not be used.
2 - Small differences A4-7-1
AV Rule 181 Redundant explicit casts
will not be used.
2 - Small differences M0-1-9
AV Rule 182 T ype casting from any
type to or from pointers shall not be
used.
3 - Significant differences M5-2-9 Not fully covered.
AV Rule 183 Every possible measure
should be taken to avoid type casting.
4 - Rejected It is not a coding
rule.
AV Rule 184 Floating
point numbers shall not be converted
to integers unless such a conversion is
a specified algorithmic requirement or
is necessary for a hardware interface.
2 - Small differences M5-0-5
AV
Rule 185 C++ style casts (const_cast,
reinterpret_cast, and static_cast) shall
be used instead of the traditional C-
style casts.
2 - Small differences A5-2-2
AV Rule 186 There shall be no
unreachable code.
2 - Small differences M0-1-1
AV Rule 187 All non-null statements
shall potentially have a side-effect.
2 - Small differences M0-1-9
AV Rule 188 Labels will not be used,
except in switch statements.
3 - Significant differences A6-6-1
AV Rule 189 The goto statement shall
not be used.
2 - Small differences A6-6-1
AV Rule 190 The continue statement
shall not be used.
4 - Rejected The continue
statement usage is
allowed within for-
loops, see: M6-6-3.
AV Rule 191 The break statement shall
not be used (except to terminate the
cases of a switch statement).
2 - Small differences M6-4-5
AV Rule 192 All if, else if constructs
will contain either a final else clause or
a comment indicating why a final else
clause is not necessary .
2 - Small differences M6-4-2
AV Rule 193 Every non-empty case
clause in a switch statement shall be
terminated with a break statement.
2 - Small differences M6-4-3, M6-
4-5
AV Rule 194 All switch statements
that do not intend to test for every
enumeration value shall contain a final
default clause.
2 - Small differences M6-4-6
AV Rule 195 A switch expression will
not represent a Boolean value.
2 - Small differences M6-4-7
AV Rule 196 Every switch statement
will have at least two cases and a
potential default.
2 - Small differences A6-4-1
AV Rule 197 Floating point variables
shall not be used as loop counters.
2 - Small differences M6-5-2
AV Rule 198 The initialization
expression in a for loop will perform no
actions other than to initialize the value
of a single for loop parameter.
2 - Small differences A6-5-4
AV Rule 199 The increment expression
in a for loop will perform no action other
than to change a single loop parameter
to the next value for the loop.
2 - Small differences A6-5-4
AV Rule 200 Null initialize or increment
expressions in for loops will not be
used; a while loop will be used instead.
3 - Significant differences A6-5-2
AV Rule 201 Numeric variables being
used within a for loop for iteration
counting shall not be modified in the
body of the loop.
2 - Small differences M6-5-3
AV Rule 202 Floating point variables
shall not be tested for exact equality or
inequality .
2 - Small differences M6-2-2
AV Rule 203 Evaluation of expressions
shall not lead to overflow/underflow
(unless required algorithmically and
then should be heavily documented).
2 - Small differences M5-19-1,
A7-1-2
AV Rule 204 A single operation with
side-effects shall only be used in the
following contexts: 1. by itself 2.
the right-hand side of an assignment
3. a condition 4. the only argument
expression with a side-effect in a
function call 5. condition of a loop 6.
switch condition 7. single part of a
chained operation.
3 - Significant differences M6-2-1 Some of presented
examples are
not misleading and
some of them are
already covered.
AV Rule 204.1 The value of an
expression shall be the same under
any order of evaluation that the
standard permits.
2 - Small differences A5-0-1
AV Rule 205 The volatile keyword shall
not be used unless directly interfacing
with hardware.
3 - Significant differences A2-11-1 Volatile keyword
forbidden.
AV Rule 206 Allocation/deallocation
from/to the free store (heap) shall not
occur after initialization.
2 - Small differences A18-5-3
AV Rule 207 Unencapsulated global
data will be avoided.
3 - Significant differences A3-3-2 Restriction to
constant-initialized
objects only .
AV Rule 208 C++ exceptions shall not
be used (i.e. throw, catch and try shall
not be used.)
4 - Rejected C++
exceptions may be
used conditionally .
AV Rule 209 The basic types of
int, short, long, float and double
shall not be used, but specific-
length equivalents should be typedef’d
accordingly for each compiler, and
these type names used in the code.
2 - Small differences A3-9-1
AV Rule 210 Algorithms shall not make
assumptions concerning how data is
represented in memory (e.g. big
endian
vs. little endian, base class subobject
ordering in derived classes, nonstatic
data member ordering across access
specifiers, etc.)
2 - Small differences A12-0-2
AV Rule 210.1 Algorithms shall not
make assumptions concerning the
order of allocation of nonstatic data
members separated by an access
specifier.
2 - Small differences A12-0-2
AV Rule 211 Algorithms shall not
assume that shorts, ints, longs, floats,
doubles or long doubles begin at
particular addresses.
2 - Small differences A12-0-2
AV Rule 212 Underflow or overflow
functioning shall not be depended on
in any special way .
2 - Small differences A4-7-1
AV Rule 213 No dependence shall be
placed on C++’s operator precedence
rules, below arithmetic operators, in
expressions.
2 - Small differences A5-0-1
AV Rule 214 Assuming that non-local
static objects, in separate translation
units, are initialized in a special order
shall not be done.
2 - Small differences A3-3-2 Intent
of the rule achieved
by restriction to
constant-initialized
objects.
AV Rule 215 Pointer arithmetic will not
be used.
3 - Significant differences M5-0-15 Pointer arithmetic
may be used for
array indexing.
AV Rule 216 Programmers should not
attempt to prematurely optimize code.
4 - Rejected It is not a coding
rule.
AV Rule 217 Compile-time and link-
time errors should be preferred over
run-time errors.
4 - Rejected A16-6-1,
A14-1-1, A1-
4-3
This rule is
too generic, some
cases are covered.
AV Rule 218 Compiler warning levels
will be set in compliance with project
policies.
3 - Significant differences A1-1-2
AV Rule 219 All tests applied to a
base class interface shall be applied
to all derived class interfaces as well.
If the derived class poses stronger
postconditions/invariants, then the new
postconditions /invariants shall be
substituted in the derived class tests.
4 - Rejected It is not a coding
rule.
AV Rule 220 Structural coverage
algorithms shall be applied against
flattened classes.
4 - Rejected It is not a coding
rule.
AV Rule 221 Structural coverage
of a class within an inheritance
hierarchy containing virtual functions
shall include testing every possible
resolution for each set of identical
polymorphic references.
4 - Rejected It is not a coding
rule.
Table B.3: JSF
B.4 Traceability to SEI CERT C++
The following table demonstrates the traceability to SEI CERT C++ Coding Standard
[10]. This is not considered as a reproduction, but a mean to compare the two
standards.
Note that the copyright of SEI CERT C++ Coding Standard allows an unlimited
distribution anyway .
SEI CERT Rule: Relation type: Related
rule:
Comment:
DCL30-C. Declare objects with
appropriate storage durations.
2 - Small differences M7-5-2
DCL40-C. Do not create incompatible
declarations of the same function or
object.
2 - Small differences M3-9-1
DCL50-CPP . Do not define a C-style
variadic function.
2 - Small differences A8-4-1
DCL51-CPP . Do not declare or define
a reserved identifier.
2 - Small differences A13-1-2,
A17-0-1
DCL52-CPP . Never qualify a reference
type with const or volatile.
2 - Small differences A1-1-1 Covered by a more
general rule.
DCL53-CPP . Do not write syntactically
ambiguous declarations.
2 - Small differences A8-5-2
DCL54-CPP . Overload allocation and
deallocation functions as a pair in the
same scope.
3 - Significant differences A18-5-3,
A18-5-4
DCL55-
CPP . Avoid information leakage when
passing a class object across a trust
boundary .
5 - Not yet analyzed The Security
chapter is not yet
covered, this will
be addressed in
future.
DCL56-CPP . Avoid cycles during
initialization of static objects.
2 - Small differences A3-3-2 Intent
of the rule achieved
by restriction to
constant-initialized
objects.
DCL57-CPP . Do not
let exceptions escape from destructors
or deallocation functions.
3 - Significant differences A15-5-1 AUTOSAR C++
Coding Guidelines
specify more
functions that need
to be noexcept.
DCL58-CPP . Do not modify the
standard namespaces.
2 - Small differences A17-6-1
DCL59-CPP . Do not define
an unnamed namespace in a header
file.
2 - Small differences M7-3-3
DCL60-CPP . Obey the one-definition
rule.
2 - Small differences M3-2-2
EXP34-C. Do not dereference null
pointers.
2 - Small differences A5-3-2
EXP35-C. Do not modify objects with
temporary lifetime.
4 - Rejected Not applicable to
C++. See EXP54-
CPP .
EXP36-C. Do not cast pointers into
more strictly aligned pointer types.
2 - Small differences A5-2-4, M5-
2-8
Direct and indirect
casting of pointer
types is prohibited
via existing rules.
EXP37-C. Call functions with the
correct number and type of arguments.
2 - Small differences M5-2-6 The
only case possible
in C++ is prohibited
via existing rule.
EXP39-C. Do not access a variable
through a pointer of an incompatible
type.
2 - Small differences A5-2-2, A5-
2-4
Effectively
prohibited by
existing rules.
EXP42-C. Do not compare padding
data.
2 - Small differences A12-0-2
EXP45-C. Do not perform assignments
in selection statements.
2 - Small differences A5-0-2, M6-
2-1
EXP46-C. Do not use a bitwise
operator with a Boolean-like operand.
4 - Rejected Use
of bitwise operators
restricted
to following cases:
M5-0-10, M5-0-20,
M5-0-21.
EXP47-C. Do not call va_arg with an
argument of the incorrect type.
4 - Rejected Use of
variable arguments
are prohibited, see:
A8-4-1.
EXP50-CPP . Do not depend on the
order of evaluation for side effects.
2 - Small differences A5-0-1
EXP51-CPP . Do not delete an array
through a pointer of the incorrect type.
2 - Small differences M5-2-12,
A18-1-1
Covered
by a combination of
existing rules.
EXP52-CPP . Do not rely on side effects
in unevaluated operands.
3 - Significant differences M5-3-4, A5-
3-1
EXP53-CPP . Do not read uninitialized
memory .
2 - Small differences A8-5-0
EXP54-CPP . Do not access an object
outside of its lifetime.
2 - Small differences A3-8-1, A5-
1-4, M7-5-1,
M7-5-2, A7-
5-1, M12-1-1
EXP55-CPP . Do not
access a cv-qualified object through a
cv-unqualified type.
2 - Small differences A5-2-3
EXP56-CPP . Do not call a function with
a mismatched language linkage.
2 - Small differences M5-2-6
EXP57-CPP . Do not cast or delete
pointers to incomplete classes.
3 - Significant differences A5-3-3, A5-
2-2, A5-2-4
The
first part of EXP57-
CPP is entirely
covered by A5-3-3,
the second part is
implicitly rule out by
A5-2-2 and A5-2-4.
EXP58-CPP . Pass an object of the
correct type to va_start.
4 - Rejected Use of
variable arguments
are prohibited, see:
A8-4-1.
EXP59-CPP . Use offsetof() on valid
types and members.
4 - Rejected Use of offsetof()
is prohibited, see:
M18-2-1.
EXP60-CPP .
Do not pass a nonstandard-layout type
object across execution boundaries.
2 - Small differences M1-0-2
EXP61-CPP . A lambda object must not
outlive any of its reference captured
objects.
2 - Small differences A5-1-4
EXP62-CPP . Do not access the bits of
an object
representation that are not part of the
object’s value representation.
2 - Small differences A12-0-2
EXP63-CPP . Do not rely on the value
of a moved-from object.
2 - Small differences A12-8-3
INT30-C. Ensure that unsigned integer
operations do not wrap.
2 - Small differences A4-7-1, M5-
19-1
INT31-C. Ensure
that integer conversions do not result
in lost or misinterpreted data.
3 - Significant differences A4-7-1, M5-
0-15
INT32-C. Ensure that operations on
signed integers do not result in
overflow.
2 - Small differences A4-7-1
INT33-C. Ensure that division and
remainder operations do not result in
divide-by-zero errors.
2 - Small differences A5-6-1
INT34-C. Do not shift an expression by
a negative number of bits or by greater
than or equal to the number of bits that
exist in the operand.
2 - Small differences M5-8-1
INT35-C. Use correct integer
precisions.
3 - Significant differences A3-9-1
INT36-C. Converting a pointer to
integer or integer to pointer.
2 - Small differences M5-2-8, M5-
2-9
INT50-CPP . Do not cast to an out-of-
range enumeration value.
2 - Small differences A7-2-1
CTR50-CPP . Guarantee that container
indices and iterators are within the
valid range.
2 - Small differences A5-2-5
CTR51-CPP . Use valid references,
pointers, and iterators to reference
elements of a container.
2 - Small differences A23-0-2
CTR52-CPP . Guarantee that library
functions do not overflow.
2 - Small differences A5-2-5
CTR53-CPP . Use valid iterator ranges. 3 - Significant differences M5-0-
16, M5-0-17,
A5-2-5
CTR54-CPP . Do not subtract iterators
that do not refer to the same container.
3 - Significant differences M5-0-16,
M5-0-17
CTR55-CPP . Do not use an additive
operator on an iterator if the result
would overflow.
3 - Significant differences M5-0-
16, M5-0-17,
A5-2-5
CTR56-CPP . Do not
use pointer arithmetic on polymorphic
objects.
2 - Small differences A5-0-4
CTR57-CPP . Provide a valid ordering
predicate.
2 - Small differences A25-4-1
CTR58-CPP . Predicate function
objects should not be mutable.
2 - Small differences A25-1-1
ARR30-C. Do not form or use out-of-
bounds pointers or array subscripts.
3 - Significant differences A5-2-5
ARR37-C. Do not add or subtract an
integer to a pointer to a non-array
object.
3 - Significant differences M5-0-15
ARR38-
C. Guarantee that library functions do
not form invalid pointers.
3 - Significant differences
RuleLinkM5-
0-16
ARR39-C. Do not add or subtract a
scaled integer to a pointer.
3 - Significant differences M5-0-15
STR30-C. Do not attempt to modify
string literals.
4 - Rejected Use of C-style
arrays, apart from
static constexpr
members,
is prohibited. See:
A18-1-1.
STR31-C. Guarantee that storage
for strings has sufficient space for
character data and the null terminator.
3 - Significant differences A5-2-5 Effectively covered
by prohibiting out-
of-range array
access.
STR32-C. Do not pass a non-null-
terminated character sequence to a
library function that expects a string
4 - Rejected Use of functions
from <cstring> is
prohibited by M18-
0-5.
STR34-C. Cast characters to unsigned
char before converting to larger integer
sizes.
3 - Significant differences M5-0-4
STR37-C. Arguments to
character-handling functions must be
representable as an unsigned char.
2 - Small differences A21-8-1
STR38-C. Do not confuse narrow and
wide character strings and functions.
3 - Significant differences A2-13-2, A2-
13-3
Use of wchar_t is
prohibited.
STR50-CPP . Guarantee that storage
for strings has sufficient space for
character data and the null terminator.
3 - Significant differences A5-2-5 Effectively covered
by prohibiting out-
of-range array
access.
STR51-CPP . Do not attempt to create
a std::string from a null pointer.
3 - Significant differences A5-3-2 This is a special
case of a more
general rule.
STR52-CPP . Use valid references,
pointers, and iterators to reference
elements of a basic_string.
2 - Small differences A23-0-2
STR53-CPP . Range check element
access.
3 - Significant differences A5-2-5 The specific case
of A5-2-5.
MEM31-C. Free dynamically allocated
memory when no longer needed.
3 - Significant differences A15-1-4,
A18-5-2
Intent of this rule is
covered by
effectively
demanding the use
of the RAII pattern.
MEM34-C. Only free memory allocated
dynamically .
4 - Rejected Use of
malloc, calloc and
realloc functions is
prohibited, see:
A18-5-1.
MEM35-C. Allocate sufficient memory
for an object.
4 - Rejected Use of
malloc, calloc and
realloc functions is
prohibited, see:
A18-5-1.
MEM36-C.
Do not modify the alignment of objects
by calling realloc().
4 - Rejected Use of
malloc, calloc and
realloc functions is
prohibited, see:
A18-5-1.
MEM50-CPP . Do not access freed
memory .
2 - Small differences A3-8-1
MEM51-CPP . Properly deallocate
dynamically allocated resources.
3 - Significant differences A18-5-3 Use of
memory allocation
and deallocation
operators
limited by A18-5-2,
A18-5-4.
MEM52-CPP .
Detect and handle memory allocation
errors.
3 - Significant differences A15-
0-2, A15-2-
2, A15-3-3,
A15-5-3
MEM53-CPP . Explicitly construct and
destruct objects when manually
managing object lifetime.
4 - Rejected A18-5-2 Explicit
use of operators
new and delete is
prohibited.
Managing
object lifetime also
covered by A18-5-
1, A18-5-3.
MEM54-CPP . Provide placement new
with properly aligned pointers to
sufficient storage capacity .
2 - Small differences A18-5-10
MEM55-CPP .
Honor replacement dynamic storage
management requirements.
2 - Small differences A18-5-9
MEM56-CPP . Do not store an already-
owned pointer value in an unrelated
smart pointer.
2 - Small differences A20-8-1
MEM57-CPP . Avoid using default
operator new for over-aligned types.
4 - Rejected Current approach
is to use managed
memory objects,
which does not
allow to work on
a raw storage, but
on a type storage,
thus no need for
this rule.
FIO50-CPP . Do not alternately input
and output from a file stream without
an intervening positioning call.
2 - Small differences A27-0-3
FIO51-CPP . Close files when they are
no longer needed.
4 - Rejected Usage of RAII
solves the problem
and is
recommended,
see: A15-1-4, A18-
5-2.
FIO30-C. Exclude user input from
format strings.
2 - Small differences A27-0-1
FIO32-C. Do not perform operations on
devices that are only appropriate for
files.
4 - Rejected Non-generic
rule affecting only
particular file types
on some operating
systems.
FIO34-C. Distinguish between
characters read from a file and EOF or
WEOF .
4 - Rejected M27-0-1 The C IO library is
not used.
FIO37-C. Do not assume that fgets()
or fgetws() returns a nonempty string
when successful.
4 - Rejected M27-0-1 The C IO library is
not used.
FIO38-C. Do not copy a FILE object. 4 - Rejected M27-0-1 The C IO library is
not used.
FIO39-C. Do not alternately input
and output from a stream without an
intervening flush or positioning call.
2 - Small differences A27-0-3
FIO40-C. Reset strings on fgets() or
fgetws() failure.
4 - Rejected M27-0-1 The C IO library is
not used.
FIO41-C. Do not call getc(), putc(),
getwc(), or putwc() with a stream
argument that has side effects.
4 - Rejected M27-0-1 The C IO library is
not used.
FIO42-C. Close files when they are no
longer needed.
4 - Rejected M27-0-1 The C IO library is
not used.
FIO44-C. Only use values for fsetpos()
that are returned from fgetpos().
4 - Rejected M27-0-1 The C IO library is
not used.
FIO45-C. Avoid TOCTOU race
conditions while accessing files.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future. See also
CP .2
FIO46-C. Do not access a closed file. 4 - Rejected M27-0-1 The C IO library is
not used.
FIO47-C. Use valid format strings. 4 - Rejected M27-0-1 The C IO library is
not used.
ERR30-C. Set errno to zero before
calling a library function known to
set errno, and check errno only after
the function returns a value indicating
failure.
4 - Rejected Use of the errno
is prohibited, see:
M19-3-1.
ERR32-C. Do not rely on indeterminate
values of errno.
4 - Rejected Use of the errno
is prohibited, see:
M19-3-1.
ERR33-C. Detect and handle standard
library errors.
3 - Small differences M0-3-2,
A15-0-3
ERR34-C. Detect errors when
converting a string to a number.
2 - Small differences A18-0-2
ERR50-CPP . Do not abruptly terminate
the program.
2 - Small differences A15-5-2,
A15-5-3
ERR51-CPP . Handle all exceptions. 2 - Small differences A15-3-3,
A15-5-3
ERR52-CPP . Do not use setjmp() or
longjmp().
2 - Small differences M17-0-5
ERR53-CPP . Do not reference base
classes or class data members in a
constructor or destructor function-try-
block handler.
3 - Significant differences M15-3-3 Use of function-try-
blocks is anyway
not recommended.
See: A15-3-5.
ERR54-CPP . Catch handlers should
order their parameter types from most
derived to least derived.
2 - Small differences M15-3-6,
M15-3-7
ERR55-CPP . Honor exception
specifications.
3 - Significant differences A15-4-2 Use of
dynamic exception
specification
is prohibited, see:
A15-
4-1. The noexcept
specifier should be
used instead.
ERR56-CPP . Guarantee exception
safety .
2 - Small differences A15-0-2
ERR57-CPP . Do not leak resources
when handling exceptions.
3 - Significant differences A15-
0-2, A15-1-
2, A15-1-4
ERR58-CPP . Handle all exceptions
thrown before main() begins executing.
2 - Small differences A15-2-1
ERR59-
CPP . Do not throw an exception across
execution boundaries.
2 - Small differences A15-1-5
ERR60-CPP . Exception objects must
be nothrow copy constructible.
3 - Significant differences A15-5-3
ERR61-CPP . Catch exceptions by
lvalue reference.
2 - Small differences A15-3-5
ERR62-
CPP . Detect errors when converting a
string to a number.
2 - Small differences A18-0-2
OOP50-CPP . Do not invoke
virtual functions from constructors or
destructors.
2 - Small differences M12-1-1
OOP51-CPP . Do not slice derived
objects.
2 - Small differences A12-8-6,
A15-3-5
OOP52-CPP . Do not
delete a polymorphic object without a
virtual destructor.
2 - Small differences A12-4-1,
A12-4-2
OOP53-CPP .
Write constructor member initializers in
the canonical order.
2 - Small differences A8-5-1
OOP54-CPP . Gracefully handle self-
copy assignment.
2 - Small differences A12-8-5
OOP55-CPP . Do not use
pointer-to-member operators to access
nonexistent members.
2 - Small differences A5-5-1
OOP56-CPP . Honor replacement
handler requirements.
3 - Significant differences A18-
5-5, A15-5-
2, A15-5-3,
A15-4-1
std::terminate and
std::unexpected
handler forbidden,
std::new_handler
comments added.
OOP57-CPP . Prefer special member
functions and overloaded operators to
C Standard Library functions.
2 - Small differences A12-0-2
OOP58-CPP . Copy operations must
not mutate the source object.
2 - Small differences A12-8-1
CON50-CPP . Do not destroy a mutex
while it is locked.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON51-CPP . Ensure actively held
locks are released on exceptional
conditions.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON52-CPP . Prevent data races
when accessing bit-fields from multiple
threads.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON53-CPP . Avoid deadlock by
locking in a predefined order.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON54-CPP . Wrap functions that can
spuriously wake up in a loop.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON55-CPP . Preserve thread safety
and liveness when using condition
variables.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON56-CPP . Do not speculatively lock
a non-recursive mutex that is already
owned by the calling thread.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON33-C. Avoid race conditions when
using library functions.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON37-C. Do not call signal() in a
multithreaded program
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
CON40-C. Do not refer to an atomic
variable twice in an expression.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON41-C. Wrap functions that can fail
spuriously in a loop.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CON43-C. Do not allow data races in
multithreaded code.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
MSC33-C. Do not pass invalid data to
the asctime() function.
4 - Rejected Use of time
handling functions
of <ctime>
is prohibited, see:
M18-0-4.
MSC38-C. Do not treat a predefined
identifier as an object if it might only be
implemented as a macro.
4 - Rejected Error indicator
errno, setjmp() and
variadic arguments
shall not be used,
see: M19-3-1,
M17-0-5, A8-4-1.
MSC39-C. Do not call va_arg() on a
va_list that has an indeterminate value.
4 - Rejected Use of
variadic arguments
is prohibited, see:
A8-4-1.
MSC40-C. Do not violate constraints. 2 - Small differences A1-1-1
MSC50-CPP . Do not use std::rand() for
generating pseudorandom numbers.
2 - Small differences A26-5-1
MSC51-CPP . Ensure your random
number generator is properly seeded.
2 - Small differences A26-5-2
MSC52-CPP . Value-returning functions
must return a value from all exit paths.
2 - Small differences A8-4-2
MSC53-CPP . Do not return from a
function declared [[noreturn]].
2 - Small differences A7-6-1
MSC54-CPP . A signal handler must be
a plain old function.
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
FLP30-C. Do not use floating-point
variables as loop counters.
2 - Small differences A6-5-2
FLP32-C. Prevent or detect domain
and range errors in math functions.
2 - Small differences A0-4-4
FLP34-C. Ensure that floating-point
conversions are within range of the
new type.
3 - Significant differences M5-0-5, M5-
0-6, M5-0-7
FLP36-C. Preserve precision when
converting integral values to floating-
point type.
3 - Significant differences M5-0-5, M5-
0-6, M5-0-7
FLP37-C. Do not
use object representations to compare
floating-point values.
2 - Small differences M3-9-3
ENV30-C. Do not modify the object
referenced by the return value of
certain functions.
2 - Small differences M18-
0-3, M18-0-
4, A18-0-3,
A17-1-1
Listed functions
are prohibited by
separate rules.
ENV31-C. Do not rely
on an environment pointer following an
operation that may invalidate it.
4 - Rejected In
general, a project
shall not rely on
environment-
specific
implementations.
ENV32-C. All exit handlers must return
normally .
3 - Significant differences A15-5-2,
A15-5-3
ENV33-C. Do not call system(). 2 - Small differences Covered by M18-0-
3
ENV34-C. Do
not store pointers returned by certain
functions.
3 - Significant differences A18-0-3,
M19-3-1
SIG31-C. Do not access shared
objects in signal handlers.
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
SIG34-C. Do not call signal() from
within interruptible signal handlers.
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
SIG35-C. Do not
return from a computational exception
signal handler.
4 - Rejected Use of signal
handling facilities
of <csignal>
is prohibited, see:
M18-7-1.
PRE30-C. Do
not create a universal character name
through concatenation.
4 - Rejected Forbidden by A2-3-
1.
PRE31-
C. Avoid side effects in arguments to
unsafe macros.
3 - Significant differences Defining function-
like macros
is prohibited, see:
A16-0-1.
PRE32-C. Do not use preprocessor
directives in invocations of function-like
macros.
Defining function-
like macros
is prohibited, see:
A16-0-1.
Table B.4: SEI CERT C++
B.5 Traceability to C++ Core Guidelines
The following table demonstrates the traceability to C++ Core Guidelines [11]. This is
not considered as a reproduction, but a mean to compare the two standards.
Note that the copyright of C++ Core Guidelines allows a derivative work anyway .
C++ Core Guidelines Rule: Relation type: Related
rule:
Comment:
P .1: Express ideas directly in code. 4 - Rejected The rule is vague.
P .2: Write in ISO Standard C++. 2 - Small differences A0-4-3
P .3: Express intent. 4 - Rejected The rule is vague.
P .4: Ideally , a program should be
statically type safe.
3 - Significant differences The rule is covered
by: A5-2-1, A5-2-
2, A5-2-4, M5-2-
12, A8-5-2, A9-5-1
P .5: Prefer compile-time checking to
run-time checking.
3 - Significant differences M0-3-1
P .6: What cannot be checked at
compile time should be checkable at
run time.
3 - Significant differences A0-1-2, M0-
3-2
P .7: Catch run-time errors early . 3 - Significant differences A0-
1-2, M0-3-2,
A5-2-5, A15-
0-4, A15-0-5
P .8: Don’t leak any resources. 3 - Significant differences A18-
5-1, A18-5-
2, A15-1-4
P .9: Don’t waste time or space. 3 - Significant differences M0-1-1, A0-
1-1, M0-1-8,
M0-1-9
P .10: Prefer immutable data to mutable
data.
2 - Small differences A7-1-1
P .11: Encapsulate messy constructs,
rather than spreading through the
code.
4 - Rejected The rule is vague.
I.1: Make interfaces explicit. 4 - Rejected The rule is vague.
I.2 Avoid global variables. 3 - Significant differences A3-3-2 A3-3-2 covers only
the initialization of
global objects.
I.3: Avoid singletons. 3 - Significant differences A3-3-2 A3-3-2 covers only
the initialization of
static objects.
I.4: Make interfaces precisely and
strongly typed.
2 - Small differences A8-4-14 -
I.5: State preconditions (if any). 4 - Rejected The rule is vague.
I.6: Prefer Expects() for expressing
preconditions.
4 - Rejected Expects() is not
part of Language
Standard.
I.7: State postconditions. 4 - Rejected The rule is vague.
I.8: Prefer Ensures() for expressing
postconditions.
4 - Rejected Ensures() is not
part of Language
Standard.
I.9:
If an interface is a template, document
its parameters using concepts.
3 - Significant differences A14-1-1
I.10: Use exceptions to signal a failure
to perform a required task.
2 - Small differences A15-0-1
I.11: Never transfer ownership by a raw
pointer (T*).
2 - Small differences A8-4-12
I.12: Declare a pointer that must not be
null as not_null.
4 - Rejected The not_null is not
part of Language
Standard.
I.13: Do not pass an array as a single
pointer.
2 - Small differences M5-2-12
I.22: Avoid complex initialization of
global objects.
2 - Small differences A3-3-2 Intent
of the rule achieved
by restriction to
constant-initialized
objects.
I.23: Keep the number of function
arguments low.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
code metrics, see:
A1-4-1.
I.24: Avoid adjacent unrelated
parameters of the same type.
4 - Rejected Design rule,
requiring case-by-
case reasoning to
apply .
I.25: Prefer abstract classes as
interfaces to class hierarchies.
2 - Small differences A10-4-1
I.26: If you want a cross-compiler ABI,
use a C-style subset.
2 - Small differences M1-0-2 -
F .1: “Package” meaningful operations
as carefully named functions.
5 - Not yet analyzed - -
F .2: A function should perform a single
logical operation.
5 - Not yet analyzed - -
F .3: Keep functions short and simple. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
code metrics, see:
A1-4-1.
F .4: If a function may have to be
evaluated at compile time, declare it
constexpr.
2 - Small differences A7-1-2
F .5: If a function is very small and time-
critical, declare it inline.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
code metrics, see:
A1-4-1.
F .6: If your function may not throw,
declare it noexcept.
2 - Small differences A15-4-4
F .7: For general use, take T* or T&
arguments rather than smart pointers.
2 - Small differences A8-4-11 Added as a
reference.
F .8: Prefer pure functions. 4 - Rejected - There is no need
for a new rule.
F .9: Unused parameters should be
unnamed.
2 - Small differences A0-1-4, A0-
1-5
F .15: Prefer simple and conventional
ways of passing information.
2 - Small differences A8-4-3
F .16: For “in” parameters, pass
cheaply-copied types by value and
others by reference to const.
2 - Small differences A8-4-7
F .17: For “in-out” parameters, pass by
reference to non-const.
2 - Small differences A8-4-9
F .18: For “consume” parameters, pass
by X&& and std::move the parameter.
2 - Small differences A8-4-5
F .19: For “forward” parameters, pass
by TP&& and only std::forward the
parameter.
2 - Small differences A8-4-6
F .20: For “out” output values, prefer
return values to output parameters.
2 - Small differences A8-4-8
F .21: T o return multiple “out” values,
prefer returning a tuple or struct.
3 - Significant differences A8-4-4 Prefer to return as
a tuple.
F .22: Use T* or owner<T*> to
designate a single object.
3 - Significant differences M5-2-12 The owner<T*> is
not
part of Language
Standard.
F .23: Use a not_null<T> to indicate that
“null” is not a valid value.
4 - Rejected The not_null<T> is
not
part of Language
Standard.
F .24: Use a span<T> or a span_p<T>
to designate a half-open sequence.
4 - Rejected Neither
the span<T> nor
the span_p<T> are
part of Language
Standard.
F .25:
Use a zstring or a not_null<zstring> to
designate a C-style string.
4 - Rejected Neither
the zstring nor the
not_null<zstring>
are
part of Language
Standard.
F .26: Use a unique_ptr<T> to transfer
ownership where a pointer is needed.
2 - Small differences A20-8-2
F .27: Use a shared_ptr<T> to share
ownership.
2 - Small differences A20-8-3
F .60: Prefer T* over T& when no
argument is a valid option.
3 - Significant differences A8-4-10
F .42: Return a T* to indicate a position
(only).
3 - Significant differences M5-
0-15, M5-0-
16, M5-0-17,
M5-0-18
F .43: Never (directly or indirectly)
return a pointer or a reference to a local
object.
2 - Small differences M7-5-2 Added as a note to
this rule.
F .44: Return a T& when copy is
undesirable and returning no object
isn’t needed.
3 - Significant differences A9-3-1 Do not return non-
const reference to
private fields.
F .45: Don’t return a T&&. 2 - Small differences M7-5-2 Added as
a reference to this
rule.
F .46: int is the return type for main(). 2 - Small differences A0-4-3 Added as
a reference to this
rule.
F .47: Return T& from assignment
operators.
2 - Small differences A13-2-1 Added as
a reference to this
rule.
F .50: Use a lambda when a function
won’t do (to capture local variables, or
to write a local function).
4 - Rejected Design
principle. Prefer
using lambda over
functions while
variables capture is
required or it is
defined in a local
scope.
F .51: Where there is a choice, prefer
default arguments over overloading.
4 - Rejected Design
principle. Prefer
default arguments
over overloading.
F .52: Prefer capturing by reference
in lambdas that will be used locally ,
including passed to algorithms.
4 - Rejected This rule
is too specific and
this is a matter of
ownership, not only
lambda.
F .53: Avoid capturing by reference in
lambdas that will be used nonlocally ,
including returned, stored on the heap,
or passed to another thread.
2 - Small differences A5-1-4
F .54: If you capture this, capture all
variables explicitly (no default capture).
3 - Significant differences A5-1-2 AUTOSAR C++
Coding Guidelines
prohibits implicit
variables capturing
into a lambda
expression.
F .55: Don’t use va_arg arguments. 2 - Small differences A8-4-1 Added as
a reference to this
rule.
C.1: Organize related data into
structures (structs or classes).
4 - Rejected Design
principle. There is
no need for a new
rule..
C.2: Use class if the class has
an invariant; use struct if the data
members can vary independently .
3 - Significant differences Class shall be used
for all non-POD
types (see: A11-
0-1), and a struct
for types defined in
A11-0-2.
C.3: Represent the distinction between
an interface and an implementation
using a class.
4 - Rejected This rule is vague.
C.4: Make a function a member
only if it needs direct access to the
representation of a class.
2 - Small differences M9-3-3
C.5: Place helper functions in the same
namespace as the class they support.
5 - Not yet analyzed - -
C.7: Don’t define a class or enum and
declare a variable of its type in the
same statement.
2 - Small differences A7-1-9
C.8: Use class rather than struct if any
member is non-public.
2 - Small differences M11-0-1,
A11-0-1
C.9: Minimize exposure of members. 3 - Significant differences M9-3-1, A9-
3-1, M11-0-1
C.10 Prefer concrete types over class
hierarchies.
4 - Rejected This rule is vague.
Concrete types
and class
hierarchies
are highly context
dependent.
C.11: Make concrete types regular. 4 - Rejected This rule is vague.
“Concrete types”
has no technical
meaning.
C.20: If you can avoid defining default
operations, do.
2 - Small differences A12-0-1 Following “the rule
of
zero” is permitted if
no special member
functions need to
be defined.
C.21: If you define or =delete any
default operation, define or =delete
them all.
2 - Small differences A12-0-1
C.22: Make default operations
consistent.
2 - Small differences A12-1-1,
A12-8-1
C.30: Define a destructor if a class
needs an explicit action at object
destruction.
4 - Rejected Design principle.
Destructor shall be
defined only if a
class needs
an explicit action at
object destruction.
C.31: All resources acquired by a
class must be released by the class’s
destructor.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
C.32: If a class has a raw pointer (T*)
or reference (T&), consider whether it
might be owning.
4 - Rejected Memory managing
objects are
recommended.
C.33: If a class has an owning pointer
member, define a destructor.
4 - Rejected Memory managing
objects are
recommended.
C.34: If a class has an owning
reference member, define a destructor.
4 - Rejected Memory managing
objects are
recommended.
C.35: A base class destructor
should be either public and virtual, or
protected and nonvirtual.
2 - Small differences A12-4-1
C.36: A destructor may not fail. 2 - Small differences A15-5-1
C.37: Make destructors noexcept. 2 - Small differences A15-5-1
C.40: Define a constructor if a class
has an invariant.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.41: A constructor should create a
fully initialized object.
2 - Small differences A15-2-2,
A12-1-1, A8-
5-0
C.42: If a constructor cannot construct
a valid object, throw an exception.
2 - Small differences A15-2-2
C.43: Ensure that a class has a default
constructor.
4 - Rejected This rule is vague.
C.44: Prefer default constructors to be
simple and non-throwing.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.45:
Don’t define a default constructor that
only initializes data members; use in-
class member initializers instead.
2 - Small differences A12-1-3,
A12-7-1
C.46: By default, declare single-
argument constructors explicit.
2 - Small differences A12-1-4
C.47: Define and initialize member
variables in the order of member
declaration.
2 - Small differences A8-5-1
C.48: Prefer in-class initializers to
member initializers in constructors for
constant initializers.
3 - Significant differences A12-1-3 AUTOSAR C++
Coding Guidelines
states that NSDMI
shall not be mixed
with
member initializer
list of constructors,
see: A12-1-2.
C.49: Prefer initialization to
assignment in constructors.
2 - Small differences A12-6-1
C.50: Use a factory function if
you need “virtual behavior” during
initialization.
3 - Significant differences M12-1-1 Added
as a reference to
this rule, as it has
a good example
of virtual behaviour
during initialization.
C.51: Use delegating constructors
to represent common actions for all
constructors of a class.
2 - Small differences A12-1-5
C.52: Use inheriting constructors to
import constructors into a derived class
that does not need further explicit
initialization.
2 - Small differences A12-1-6
C.60: Make copy assignment non-
virtual, take the parameter by const&,
and return by non-const&.
2 - Small differences A10-3-5,
A13-2-1
C.61: A copy operation should copy . 2 - Small differences A12-8-1,
A12-8-2
C.62: Make copy assignment safe for
self-assignment.
2 - Small differences A12-8-5
C.63: Make move assignment non-
virtual, take the parameter by &&, and
return by non-const&.
2 - Small differences A10-3-5,
A13-2-1
C.64: A move operation should move
and leave its source in a valid state.
2 - Small differences A12-8-1,
A12-8-4
C.65: Make move assignment safe for
self-assignment.
2 - Small differences A12-8-5
C.66: Make move operations
noexcept.
2 - Small differences A15-5-1
C.67: A base class should suppress
copying, and provide a virtual clone
instead if copying” is desired.
2 - Small differences A12-8-6
C.80: Use =default if you have to
be explicit about using the default
semantics.
2 - Small differences A12-7-1
C.81: Use =delete when you want
to disable default behavior (without
wanting an alternative).
2 - Small differences A12-0-1,
A12-8-6
C.82: Don’t call virtual functions in
constructors and destructors.
2 - Small differences M12-1-1
C.83: For value-like types, consider
providing a noexcept swap function.
3 - Significant differences A12-8-2 The swap
function is explicitly
recommended
for copy and move
assignment
operators only .
C.84: A swap function may not fail. 2 - Small differences A15-5-1
C.85: Make swap noexcept. 2 - Small differences A15-5-1
C.86: Make
== symmetric with respect to operand
types and noexcept.
2 - Small differences A13-5-5 -
C.87: Beware of == on base classes. 2 - Small differences A13-5-5 This rule
is implicitly covered
by adhering to A13-
5-5.
C.89: Make a hash noexcept. 2 - Small differences A18-1-6
C.120: Use class
hierarchies to represent concepts with
inherent hierarchical structure (only).
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.121: If a base class is used as an
interface, make it a pure abstract class.
2 - Small differences AUTOSAR C++
Coding
Guidelines defines
an interface class
definition,
see: Interface-
Class.
C.122: Use abstract classes as
interfaces when complete separation
of interface and implementation is
needed.
2 - Small differences A10-4-1
C.126: An abstract class typically
doesn’t need a constructor.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.127: A class with a virtual function
should have a virtual or protected
destructor.
2 - Small differences A12-4-1
C.128: Virtual functions should specify
exactly one of virtual, override, or final.
2 - Small differences A10-3-1
C.129: When
designing a class hierarchy , distinguish
between implementation inheritance
and interface inheritance.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.130: Redefine or prohibit copying
for a base class; prefer a virtual clone
function instead.
2 - Small differences A12-8-6
C.131: Avoid trivial getters and setters. 4 - Rejected All members
in non-POD types
shall be private.
C.132: Don’t make a function virtual
without reason.
4 - Rejected Non-generic
design
principle; There is
no need for a new
rule.
C.133: Avoid protected data. 3 - Significant differences M11-0-1 All members
in non-POD types
shall be private.
C.134: Ensure all non-const data
members have the same access level.
2 - Small differences M11-0-1,
A11-0-2
C.135: Use multiple inheritance to
represent multiple distinct interfaces.
2 - Small differences A10-1-1
C.136: Use multiple inheritance to
represent the union of implementation
attributes.
4 - Rejected Multiple
implementation
inheritance is
prohibited
by AUTOSAR C++
Coding Guidelines,
it allows only
multiple interface
inheritance.
C.137: Use virtual bases to avoid
overly general base classes.
4 - Rejected It is allowed to use
virtual inheritance
only in a diamond
hierarchy , see:
M10-1-1, M10-1-2.
C.138: Create an overload set for a
derived class and its bases with using.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.139: Use final sparingly . 3 - Significant differences A12-4-2 Class shall
be declared final if
it has a non-virtual
destructor.
C.140: Do not provide different default
arguments for a virtual function and an
overrider.
2 - Small differences M8-3-1
C.145: Access polymorphic objects
through pointers and references.
3 - Significant differences A12-8-6,
A15-3-5
Functionalities that
could lead to slicing
are prohibited.
C.146: Use dynamic_cast where class
hierarchy navigation is unavoidable.
2 - Small differences A5-2-1
C.147: Use dynamic_cast to a
reference type when failure to find the
required class is considered an error.
4 - Rejected The dynamic_cast
should not be used,
see: A5-2-1.
C.148: Use dynamic_cast to a pointer
type when failure to find the required
class is considered a valid alternative.
4 - Rejected The dynamic_cast
should not be used,
see: A5-2-1.
C.149: Use unique_ptr or shared_ptr
to avoid forgetting to delete objects
created using new.
2 - Small differences A18-5-2
C.150: Use
make_unique() to construct objects
owned by unique_ptrs.
2 - Small differences A20-8-5
C.151: Use
make_shared() to construct objects
owned by shared_ptrs.
2 - Small differences A20-8-6
C.152: Never assign a pointer to an
array of derived class objects to a
pointer to its base.
2 - Small differences M5-2-12
C.153: Prefer virtual function to
casting.
3 - Significant differences M5-2-2, M5-
2-3, A5-2-1
C.160: Define operators primarily to
mimic conventional usage.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.161: Use nonmember functions for
symmetric operators.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.162: Overload operations that are
roughly equivalent.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.163: Overload only for operations
that are roughly equivalent.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.164: Avoid conversion operators. 2 - Small differences A13-5-3
C.165: Use using for customization
points.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
C.166: Overload unary & only as part
of a system of smart pointers and
references.
3 - Significant differences M5-3-3 The unary
& operator shall not
be overloaded.
C.167:
Use an operator for an operation with
its conventional meaning.
4 - Rejected Design
principle; There is
no need for a new
rule.
C.168: Define overloaded operators in
the namespace of their operands.
4 - Rejected Design
principle. There is
no need for a new
rule.
C.170: If you feel like overloading a
lambda, use a generic lambda.
4 - Rejected Design
principle; There is
no need for a
new rule. Creating
generic lambda
expressions is
allowed, see: A7-1-
5.
C.180: Use unions to save memory . 4 - Rejected Unions shall not be
used, see: A9-5-1.
C.181: Avoid “naked” unions. 2 - Small differences A9-5-1
C.182: Use anonymous unions to
implement tagged unions.
2 - Small differences A9-5-1 Tagged
unions allowed as
an exception, but
only as POD.
C.183: Don’t use a union for type
punning.
4 - Rejected Unions shall not be
used, see: A9-5-1.
Enum.1: Prefer enumerations over
macros.
3 - Significant differences A16-0-1 Usage of macros is
prohibited.
Enum.2:
Use enumerations to represent sets of
related named constants.
2 - Small differences A7-2-5
Enum.3: Prefer class enums over
“plain” enums.
2 - Small differences A7-2-3
Enum.4: Define operations on
enumerations for safe and simple use.
4 - Rejected Design
principle. There is
no need for a new
rule.
Enum.5: Don’t use ALL_CAPS for
enumerators.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
Enum.6: Avoid unnamed
enumerations.
3 - Significant differences A7-2-3 Enum classes shall
be used instead of
enums; it is not
allowed to declare
unnamed enum
class.
Enum.7: Specify the underlying type of
an enumeration only when necessary .
4 - Rejected AUTOSAR C++
Coding Guidelines
forces
a programmer to
specify the
underlying
base type explicitly ,
as only fixed-width
numeric types shall
be used. See: A3-
9-1.
Enum.8: Specify enumerator values
only when necessary .
3 - Significant differences A7-2-4 It is defined how
enumerators
values should be
specified.
R.1: Manage resources automatically
using resource handles and RAII
(Resource Acquisition Is Initialization).
4 - Rejected AUTOSAR C++
Coding Guidelines
does not define
rules for coding
patterns. Note that
usage of RAII is
recommended,
see: A15-1-4, A18-
5-2.
R.2: In interfaces, use raw pointers to
denote individual objects (only).
2 - Small differences M5-2-12
R.3: A raw pointer (a T*) is non-
owning.
4 - Rejected Ownership is
covered by
memory managing
objects, see: A18-
5-2.
R.4: A raw reference (a T&) is non-
owning.
4 - Rejected Ownership is
covered by
memory managing
objects, see: A18-
5-2.
R.5: Don’t heap-allocate
unnecessarily .
2 - Small differences A18-5-8
R.6: Avoid non-const global variables. 3 - Significant differences A3-3-2 A3-3-2 covers only
the initialization of
global objects.
R.10: Avoid malloc() and free(). 2 - Small differences A18-5-1
R.11: Avoid calling new and delete
explicitly .
2 - Small differences A18-5-2
R.12: Immediately give the result of
an explicit resource allocation to a
manager object.
2 - Small differences A18-5-2
R.13: Perform at most one
explicit resource allocation in a single
expression statement.
2 - Small differences A5-0-1
R.14: ??? array vs. pointer parameter. 2 - Small differences M5-2-12
R.15: Always overload matched
allocation/deallocation pairs.
3 - Significant differences A18-5-3
R.20: Use unique_ptr or shared_ptr to
represent ownership.
2 - Small differences A20-8-2,
A20-8-3
R.21: Prefer
unique_ptr over shared_ptr unless you
need to share ownership.
2 - Small differences A20-8-4
R.22: Use make_shared() to make
shared_ptrs.
2 - Small differences A20-8-6
R.23: Use make_unique() to make
unique_ptrs.
2 - Small differences A20-8-5
R.24: Use std::weak_ptr to break
cycles of shared_ptrs.
2 - Small differences A20-8-7
R.30: T ake
smart pointers as parameters only to
explicitly express lifetime semantics.
2 - Small differences A8-4-11
R.31: If you have non-std smart
pointers, follow the basic pattern from
std.
4 - Rejected There is no need
for a new rule.
Smart pointers are
a part of Language
Standard.
R.32: T ake a unique_ptr<widget>
parameter to express that a function
assumes ownership of a widget.
2 - Small differences A8-4-12
R.33: T ake a unique_ptr<widget>&
parameter to express that a function
reseats thewidget.
2 - Small differences A8-4-12
R.34: T ake a shared_ptr<widget>
parameter to express that a function is
part owner.
2 - Small differences A8-4-13
R.35: T ake a shared_ptr<widget>&
parameter to express that a function
might reseat the shared pointer.
2 - Small differences A8-4-13
R.36: T ake a
const shared_ptr<widget>& parameter
to express that it might retain a
reference count to the object ???.
2 - Small differences A8-4-13
R.37: Do not pass a pointer or
reference obtained from an aliased
smart pointer.
2 - Small differences A8-4-11,
A18-5-2
Added as a
reference in these
rules and a note in
A8-4-11.
ES.1: Prefer the standard library to
other libraries and to “handcrafted
code”.
4 - Rejected Design
principle; There is
no need for a new
rule.
ES.2: Prefer suitable abstractions to
direct use of language features.
4 - Rejected Design
principle; There is
no need for a new
rule.
ES.5: Keep scopes small. 2 - Small differences M3-4-1
ES.6: Declare names in for-statement
initializers and conditions to limit
scope.
2 - Small differences M3-4-1 As an exeception
from the A7-
1-7, it is allowed to
declare variables in
for-statement
initializer.
ES.7: Keep common and local names
short, and keep uncommon and
nonlocal names longer.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
ES.8: Avoid similar-looking names. 2 - Small differences M2-10-1
ES.9: Avoid ALL_CAPS names. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
ES.10: Declare one name (only) per
declaration.
2 - Small differences A7-1-7
ES.11: Use auto to avoid redundant
repetition of type names.
3 - Significant differences A7-1-5 It is
not recommended
to use the auto
specifier, but it is
allowed.
ES.12: Do not reuse names in nested
scopes.
2 - Small differences A2-10-1
ES.20: Always initialize an object. 2 - Small differences A8-5-0
ES.21: Don’t introduce a variable (or
constant) before you need to use it.
2 - Small differences M3-4-1
ES.22: Don’t declare a variable until
you have a value to initialize it with.
2 - Small differences M3-4-1, A8-
5-0
ES.23: Prefer the {} initializer syntax. 2 - Small differences A8-5-2
ES.24: Use a unique_ptr<T> to hold
pointers.
3 - Significant differences A18-
5-2, A15-1-
4, A18-1-3
AUTOSAR C++
Coding Guidelines
does not force a
programmer to use
std::unique_ptr, it is
just highly
recommended
within examples
and rationales.
ES.25: Declare an object const or
constexpr unless you want to modify its
value later on.
2 - Small differences A7-1-1
ES.26: Don’t use a variable for two
unrelated purposes.
4 - Rejected This rule is vague.
“Unrelated” is
highly context
dependent.
ES.27: Use std::array or stack_array
for arrays on the stack.
3 - Significant differences A18-1-1 C-style arrays shall
not be used, and
it is recommended
to use std::array
instead.
ES.28: Use lambdas
for complex initialization, especially of
const variables.
4 - Rejected Design
principle. There is
no need for a new
rule.
ES.30: Don’t use macros for program
text manipulation.
2 - Small differences A16-0-1 Usage of macros is
prohibited.
ES.31: Don’t use macros for constants
or “functions”.
2 - Small differences A16-0-1 Usage of macros is
prohibited.
ES.32: Use ALL_CAPS for all macro
names.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
ES.33: If you must use macros, give
them unique names.
2 - Small differences M2-10-1
ES.34: Don’t define a (C-style) variadic
function.
2 - Small differences A8-4-1
ES.70: Prefer a switch-statement to an
if-statement when there is a choice.
4 - Rejected Design principle;
The switch
statement
shall have at least
two case-clauses,
distinct from the
default label. See:
A6-4-1.
ES.71: Prefer a range-for-statement to
a for-statement when there is a choice.
3 - Significant differences A6-5-1 It is recommended
to use range-based
for statement to
replace equivalent
for-statements.
ES.72: Prefer a for-statement to
a while-statement when there is an
obvious loop variable.
2 - Small differences A6-5-2
ES.73: Prefer a while-statement to a
for-statement when there is no obvious
loop variable.
3 - Significant differences A6-5-2 It is required that a
for-loop contains a
loop-counter.
ES.74: Prefer to declare a loop
variable in the initializer part of a for-
statement.
3 - Significant differences M3-4-1 It is required that
each identifier is
defined in a block
that minimizes its
visibility .
ES.75: Avoid do-statements. 2 - Small differences A6-5-3
ES.76: Avoid goto. 2 - Small differences A6-6-1
ES.78: Always end a non-empty case
with a break.
2 - Small differences M6-4-5
ES.79: Use default to handle common
cases (only).
4 - Rejected There is no need
for a new rule.
ES.84: Don’t (try to) declare a local
variable with no name.
2 - Small differences A6-2-2 -
ES.85: Make empty statements visible. 2 - Small differences M6-3-1, M6-
4-1, M6-4-1
ES.86: Avoid modifying loop control
variables inside the body of raw for-
loops.
2 - Small differences M6-5-3
ES.40: Avoid complicated expressions. 4 - Rejected This rule is vague.
Order of evaluation
is covered by A5-0-
1.
ES.41: If in doubt about operator
precedence, parenthesize.
2 - Small differences A5-2-6, M5-
0-2
ES.42: Keep use of pointers simple
and straightforward.
3 - Significant differences M5-0-
15, M5-0-16,
A5-2-5
’span’
is not covered as it
is not part of the
language standard.
ES.43: Avoid expressions with
undefined order of evaluation.
2 - Small differences A5-0-1
ES.44: Don’t depend on order of
evaluation of function arguments.
2 - Small differences A5-0-1
ES.45: Avoid "magic constants"; use
symbolic constants.
2 - Small differences A5-1-1
ES.46: Avoid lossy (narrowing,
truncating) arithmetic conversions.
2 - Small differences A4-7-1, M5-
0-6
ES.47: Use nullptr rather than 0 or
NULL.
2 - Small differences A4-10-1
ES.48: Avoid casts. 2 - Small differences A5-2-1, A5-
2-2, A5-2-3,
A5-2-4
ES.49: If you must use a cast, use a
named cast.
2 - Small differences A5-2-2
ES.50: Don’t cast away const. 2 - Small differences A5-2-3
ES.55: Avoid the need for range
checking.
3 - Significant differences A6-5-1 A6-5-1 only covers
for-loops
ES.56: Write std::move() only when
you need to explicitly move an object
to another scope.
3 - Significant differences A12-
8-3, A18-9-
2, A18-9-3
Vulnerabilities
of std::move() are
explained.
ES.60: Avoid new and delete outside
resource management functions.
2 - Small differences A18-5-2
ES.61: Delete arrays using delete[]
and non-arrays using delete.
2 - Small differences A18-5-3
ES.62: Don’t compare pointers into
different arrays.
2 - Small differences M5-0-16
ES.63: Don’t slice. 3 - Significant differences A12-8-6,
A15-3-5
The functionalities
that could
lead to slicing were
prohibited.
ES.64: Use the T{e} notation for
construction.
2 - Small differences A8-5-2
ES.65: Don’t dereference an invalid
pointer.
2 - Small differences A5-3-2
ES.100: Don’t mix signed and
unsigned arithmetic.
2 - Small differences M5-0-4, M5-
0-9
ES.101: Use unsigned types for bit
manipulation.
2 - Small differences M5-0-21
ES.102: Use signed types for
arithmetic.
3 - Significant differences A4-7-1, M5-
19-1
ES.103: Don’t overflow. 2 - Small differences A4-7-1
ES.104: Don’t underflow. 2 - Small differences A4-7-1
ES.105: Don’t divide by zero. 2 - Small differences A5-6-1
Per.1: Don’t optimize without reason. 4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.2: Don’t optimize prematurely . 4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.3: Don’t optimize something that’s
not performance critical.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.4: Don’t assume that complicated
code is necessarily faster than simple
code.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.5: Don’t assume that low-level
code is necessarily faster than high-
level code.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.6: Don’t make claims about
performance without measurements.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.7: Design to enable optimization. 4 - Rejected Design
principle; There is
no need for a new
rule.
Per.10: Rely on the static type system. 4 - Rejected Implementation
principle; There is
no need for a new
rule.
Per.11: Move computation from run
time to compile time
2 - Small differences A3-3-2, A7-
1-1, A7-1-2
Per.12: Eliminate redundant aliases 4 - Rejected This rule is
incomplete.
Per.13: Eliminate redundant
indirections
4 - Rejected This rule is
incomplete.
Per.14: Minimize the number of
allocations and deallocations
4 - Rejected This rule is
incomplete.
Per.15: Do not allocate on a critical
branch
4 - Rejected This rule is
incomplete.
Per.16: Use compact data structures 4 - Rejected This rule is
incomplete.
Per.18: Space is time 4 - Rejected This rule is
incomplete.
Per.19: Access memory predictably . 4 - Rejected Implementation
principle. There is
no need for a new
rule.
CP .1: Assume that your code will run
as part of a multi-threaded program.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .2: Avoid data races. 5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .3: Minimize explicit sharing of
writable data.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .4: Think in terms of tasks, rather
than threads.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .8: Don’t try to use volatile for
synchronization.
3 - Significant differences A2-11-1 Volatile keyword
forbidden.
CP .20: Use RAII, never plain
lock()/unlock().
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .21: Use std::lock() to acquire
multiple mutexes.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .22: Never call unknown code while
holding a lock (e.g., a callback).
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .23: Think of a joining thread as a
scoped container.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .24: Think of a detached thread as a
global container.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .25: Prefer gsl::raii_thread over
std::thread unless you plan to detach().
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .26: Prefer gsl::detached_thread
over std::thread if you plan to detach().
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .27: Use plain std::thread for
threads that detach based on a run-
time condition (only).
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .28: Remember to join scoped
threads that are not detach()ed.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .30: Do not pass pointers to local
variables to non-raii_threads.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .31: Pass small amounts of data
between threads by value, rather than
by reference or pointer.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
[CP .32: T o share ownership between
unrelated threads use shared_ptr.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .40: Minimize context switching. 5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .41: Minimize thread creation and
destruction.
55 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .42: Don’t wait without a condition. 5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .43: Minimize time spent in a critical
section.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .44: Remember to name your
lock_guards and unique_locks.
2 - Small differences A6-2-2 This is a special
case of the more
generic rule.
P .50: Define a mutex together with the
data it guards.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .60: Use a future to return a value
from a concurrent task.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .61: Use a async() to spawn a
concurrent task.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .100: Don’t
use lock-free programming unless you
absolutely have to.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .101: Distrust your
hardware/compiler combination.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .102: Carefully study the literature. 5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .110: Do not write your own double-
checked locking for initialization.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .111: Use a conventional pattern
if you really need double-checked
locking.
5 - Not yet analyzed The “Concurrency
and Parallelism”
chapter is not yet
covered, this will
be addressed in
future.
CP .200: Use volatile only to talk to non-
C++ memory .
3 - Significant differences A2-11-1 Volatile keyword
forbidden.
E.1: Develop an error-handling
strategy early in a design.
4 - Rejected Design
principle; There is
no need for a new
rule.
E.2: Throw an exception to signal that
a function can’t perform its assigned
task.
2 - Small differences A15-0-1
E.3: Use exceptions for error handling
only .
2 - Small differences A15-0-1
E.4: Design your error-handling
strategy around invariants.
4 - Rejected Design
principle; There is
no need for a new
rule.
E.5: Let a constructor establish an
invariant, and throw if it cannot.
2 - Small differences A15-2-2
E.6: Use RAII to prevent leaks. 4 - Rejected Design
principle; There is
no need for a new
rule.
E.7: State your preconditions. 4 - Rejected Design
principle; There is
no need for a new
rule.
E.8: State your postconditions. 4 - Rejected Design
principle; There is
no need for a new
rule.
E.12: Use noexcept when exiting
a function because of a throw is
impossible or unacceptable.
2 - Small differences A15-4-4
E.13: Never throw while being the
direct owner of an object.
3 - Significant differences A15-1-4 It is required to
release all
acquired resources
and objects before
a throw or a return
statement.
E.14: Use purpose-designed user-
defined types as exceptions (not built-
in types).
3 - Significant differences A15-1-1 It is
required that user-
defined exceptions
inherit
from std::exception
class.
E.15:
Catch exceptions from a hierarchy by
reference.
2 - Small differences A15-3-5
E.16: Destructors, deallocation, and
swap must never fail.
2 - Small differences A15-5-1
E.17: Don’t try to catch every
exception in every function.
2 - Small differences A15-3-2 AUTOSAR C++
Coding Guidelines
introduces checked
and unchecked
exceptions.
Whether an
exception should
be caught depends
if meaningful action
can be performed
in a given context.
E.18: Minimize the use of explicit
try/catch.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
E.19: Use a final_action object to
express cleanup if no suitable resource
handle is available.
4 - Rejected The
finally is not part of
the C++ Language
Standard.
E.25: If you can’t throw
exceptions, simulate RAII for resource
management.
3 - Rejected the RAII is a coding
pattern; There is no
need for
a new rule. On the
other hand, usage
of RAII
is recommended in
the example of the
A15-1-4.
E.26: If you can’t throw exceptions,
consider failing fast.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
E.27: If you can’t throw exceptions, use
error codes systematically .
4 - Rejected AUTOSAR C++
Coding Guidelines
does not force any
specific error
handling
mechanism. It
requires that every
error information
will be tested, see:
M0-3-2.
E.28: Avoid error handling based on
global state (e.g. errno).
2 - Small differences M19-3-1
Con.1: By default, make objects
immutable.
2 - Small differences A7-1-1
Con.2: By default, make member
functions const.
2 - Small differences M9-3-3
Con.3: By default, pass pointers and
references to consts.
2 - Small differences M7-1-2
Con.4: Use const to define objects
with values that do not change after
construction.
2 - Small differences A7-1-1
Con.5: Use constexpr for values that
can be computed at compile time.
2 - Small differences A7-1-2
T .1: Use templates to raise the level of
abstraction of code.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .2: Use templates to
express algorithms that apply to many
argument types.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .3: Use templates to express
containers and ranges.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .4: Use templates to express syntax
tree manipulation.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .5: Combine
generic and OO techniques to amplify
their strengths, not their costs.
4 - Rejected Design
principle; There is
no need for a new
rule.
T .10: Specify concepts for all template
arguments.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .11: Whenever possible use standard
concepts.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .12: Prefer concept names over auto
for local variables.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .13: Prefer the shorthand notation for
simple, single-type argument
concepts.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .20: Avoid “concepts” without
meaningful semantics.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .21: Require a complete set of
operations for a concept.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .22: Specify axioms for concepts. 4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .23: Differentiate a refined concept
from its more general case by adding
new use patterns..
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .24: Use tag classes or traits to
differentiate concepts that differ only in
semantics..
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .25: Avoid complementary
constraints.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .26: Prefer to define concepts in
terms of use-patterns rather than
simple syntax.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .40: Use function objects to pass
operations to algorithms.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .41: Require only essential properties
in a template’s concepts.
4 - Rejected Concepts are not
part of the C++14
Language
Standard.
T .42: Use template aliases to simplify
notation and hide implementation
details.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .43: Prefer using over typedef for
defining aliases.
2 - Small differences A7-1-6
T .44: Use function templates to deduce
class template argument types (where
feasible).
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .46: Require template arguments to
be at least Regular or SemiRegular.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .47: Avoid
highly visible unconstrained templates
with common names.
4 - Rejected M17-0-2,
M17-0-3
This rule is vague.
"Highly visible" and
"common names"
have no technical
meaning.
T .48: If your compiler does not support
concepts, fake them with enable_if.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .49: Where possible, avoid type-
erasure.
4 - Rejected This rule
is incomplete. This
rule
is vague. "Where
possible" has no
technical meaning.
T .60: Minimize a template’s context
dependencies.
4 - Rejected This rule is vague.
T .61: Do not over-parameterize
members (SCARY).
2 - Small differences A14-1-1,
A14-7-1
T .62: Place non-dependent class
template members in a non-templated
base class.
2 - Small differences A14-5-2 -
T .65:
Use tag dispatch to provide alternative
implementations of a function.
4 - Rejected Implementation
principle; There is
no need for a new
rule.
T .68: Use rather than () within
templates to avoid ambiguities.
2 - Small differences A8-5-2
T .69: Inside a template, don’t make
an unqualified nonmember function
call unless you intend it to be a
customization point.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .80: Do not naively templatize a class
hierarchy .
5 - Not yet analyzed - -
T .81: Do not mix hierarchies and
arrays.
2 - Small differences A5-0-4
T .83: Do not declare a member
function template virtual.
4 - Rejected There is
no need for a new
rule. Handled by a
compiler.
T .84: Use
a non-template core implementation to
provide an ABI-stable interface.
4 - Rejected Design
principle. There is
no need for a new
rule.
T .100: Use variadic templates when
you need a function that takes a
variable number of arguments of a
variety of types.
2 - Small differences A8-4-1
T .101: How to pass arguments to a
variadic template.
4 - Rejected This rule is
incomplete.
T .102: How to process arguments to a
variadic template.
4 - Rejected There is no need
for a new rule.
T .103: Don’t use variadic templates for
homogeneous argument lists.
4 - Rejected There is no need
for a new rule.
T .120: Use
template metaprogramming only when
you really need to.
4 - Rejected This rule is vague.
"When you really
need to" has no
technical meaning.
T .121: Use template
metaprogramming primarily to emulate
concepts.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .122: Use templates (usually template
aliases) to compute types at compile
time.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .123: Use constexpr functions to
compute values at compile time.
4 - Rejected Implementation
principle. There is
no need for a new
rule.
T .124: Prefer to use standard-library
TMP facilities.
4 - Rejected There is no need
for a new rule.
T .125: If you need to go beyond the
standard-library TMP facilities, use an
existing library .
4 - Rejected This rule is vague.
"beyond the
standard-library
TMP facilities" has
no technical
meaning.
T .140: Name all operations with
potential for reuse.
4 - Rejected
T .141: Use an unnamed lambda if you
need a simple function object in one
place only .
3 - Significant differences A5-1-9 Only
forbids duplication
of identical lambda
expressions.
T .142: Use template variables to
simplify notation.
4 - Rejected This rule is
incomplete.
T .143: Don’t write unintentionally
nongeneric code.
5 - Not yet analyzed - -
T .144: Don’t specialize function
templates.
2 - Small differences A14-8-2
T .150: Check that a class matches a
concept using static_assert.
2 - Small differences A14-1-1
CPL.1: Prefer C++ to C. 2 - Small differences A17-1-1,
A18-0-1
CPL.2: If you must use C, use the
common subset of C and C++, and
compile the C code as C++.
4 - Rejected There is no need
for a new rule.
CPL.3: If you must use C for interfaces,
use C++ in the calling code using such
interfaces.
5 - Not yet analyzed - -
SF .1: Use a .cpp suffix for code
files and .h for interface files if your
project doesn’t already follow another
convention.
3 - Significant differences A3-1-2, A3-
1-3
For header file
names, AUTOSAR
C++ Coding
Guidelines allows
either “.h”, “.hpp” or
“.hxx” extension.
SF .2: A .h file may not contain
object definitions or non-inline function
definitions.
2 - Small differences A3-1-1
SF .3: Use .h files for all declarations
used in multiple source files.
2 - Small differences M3-2-2, A3-
3-1
SF .4: Include .h files before other
declarations in a file.
2 - Small differences M16-0-1
SF .5: A .cpp file must include the .h
file(s) that defines its interface.
5 - Not yet analyzed - -
SF .7: Don’t write using namespace in
a header file.
2 - Small differences M7-3-6
SF .8: Use #include guards for all .h
files.
2 - Small differences M16-2-3
SF .9: Avoid cyclic dependencies
among source files.
5 - Not yet analyzed - -
SF .21: Don’t use an
unnamed (anonymous) namespace in
a header.
2 - Small differences M7-3-3
SF .22: Use
an unnamed (anonymous) namespace
for all internal/nonexported entities.
5 - Not yet analyzed - -
SL.1: Use libraries wherever possible. 4 - Rejected Design
principle; There is
no need for a new
rule.
SL.2: Prefer the standard library to
other libraries.
4 - Rejected Design
principle; There is
no need for a new
rule.
SL.3: Do not add non-standard entities
to namespace std.
2 - Small differences A17-6-1
SL.con.1: Prefer using STL array or
vector instead of a C array .
2 - Small differences A18-1-1
SL.con.2: Prefer using STL vector by
default unless you have a reason to
use a different container.
4 - Rejected This rule is vague.
“have a reason to”
has no technical
meaning.
SL.str.1: Use std::string to own
character sequences
2 - Small differences A27-0-4
SL.io.50: Avoid endl. 5 - Not yet analyzed - -
T ype.1: Don’t use reinterpret_cast. 2 - Small differences A5-2-4
T ype.2:
Don’t use static_cast downcasts. Use
dynamic_cast instead.
2 - Small differences M5-2-2
T ype.3: Don’t use const_cast to cast
away const (i.e., at all).
2 - Small differences A5-2-3
T ype.4: Don’t
use C-style (T) expression casts that
would perform a static_cast downcast,
const_cast, or reinterpret_cast.
2 - Small differences A5-2-2
T ype.5: Don’t use a variable before it
has been initialized.
2 - Small differences A8-5-0
T ype.6: Always initialize a member
variable.
2 - Small differences A12-1-1
T ype.7: Avoid accessing members of
raw unions. Prefer variant instead.
2 - Small differences A9-5-1
T ype.8: Avoid reading from varargs
or passing vararg arguments. Prefer
variadic template parameters instead.
2 - Small differences A8-4-1
Bounds.1: Don’t use pointer arithmetic.
Use span instead.
2 - Small differences M5-0-15
Bounds.2: Only index into arrays using
constant expressions.
2 - Small differences A5-2-5
Bounds.3: No array-to-pointer decay . 2 - Small differences M5-2-12
Bounds.4: Don’t use standard library
functions and types that are not
bounds-checked.
5 - Not yet analyzed - -
NL.1: Don’t say in comments what can
be clearly stated in code.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.2: State intent in comments. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.3: Keep comments crisp. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.4: Maintain a consistent indentation
style.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.5 Don’t encode type information in
names.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.7: Make the length of a name
roughly proportional to the length of its
scope.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.8: Use a consistent naming style. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.9: Use ALL_CAPS for macro
names only .
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.10: Avoid CamelCase. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.15: Use spaces sparingly . 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.16: Use a conventional class
member declaration order.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.17: Use K&R-derived layout. 4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.18: Use C++-style declarator
layout.
4 - Rejected AUTOSAR C++
Coding Guidelines
does not introduce
rules related
to coding style or
naming
convention.
NL.19: Avoid names that are easily
misread.
2 - Small differences M2-10-1
NL.20: Don’t place two statements on
the same line.
3 - Significant differences A7-1-7 It is required for
declarations only .
NL.21: Declare one name (only) per
declaration.
2 - Small differences A7-1-7
NL.25: Don’t use void as an argument
type.
5 - Not yet analyzed - -
NL.26: Use conventional const
notation.
5 - Not yet analyzed - -
Table B.5: C++ Core Guidelines
B.6 Traceability to ISO 26262
Each method in the tables referenced from the ISO 26262 standard is an entry that is
one of the following:
• consecutive – all methods shall be applied as recommended, but with different
recommendation level that depends on the ASIL level.
• alternative – an appropriate combination of methods shall be applied.
Consecutive methods are marked by a sequence number, e.g. 1, 2, 3. Alternative
entries are marked by a number followed by a letter, e.g. 1a, 1b, 1c.
This chapter traces mostly principles and recommendations from Section 8 (Software
unit design and implementation) of the Part 6 of the ISO 26262. The rest of the
document is not applicable to the AUTOSAR C++14 Coding Guidelines. Although
AUTOSAR C++14 Coding Guidelines contain multiple rules allocated to other work
products (e.g. software architectural design, verification), those are considered as
recommendations for doing review of such work products, not as a direct fulfillment of
ISO 26262 requirements.
Part 6: Product development at the software level
5: Initiation of product development at the software level
5.4: Requirements and recommendations
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1 an unambiguous definition 6 - Implemented [3, ISO/IEC
14882:2014],
A2-13-2,
A1-1-1
Syntax and semantics of the
language unambiguously
defined. Restrictions on
using conditionally-supported
or deprecated features.
2 the support for
embedded real time software
and runtime error handling
6 - Implemented A15-0-1,
A15-0-4,
A15-0-5,
A15-0-6,
A15-0-7,
A15-0-8,
A18-5-5,
A18-5-6,
A18-5-7
Introduction of Checked and
Unchecked Exceptions.
Usage of exceptions
limited only to error handling.
Additional requirements on
toolchain support for memory
management and exceptions
handling.
3 the support for modularity ,
abstraction and structured
constructs
6 - Implemented A8-4-14,
A10-0-1,
A10-0-2,
A10-4-1
Recommendations on which
constructs to use to increase
software reusability and hide
implementation details.
Table B.6: The criteria that shall be considered when selecting a suitable modeling or
programming language. Paragraph 5.4.6 from [5].
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1a Enforcement of low
complexity
6 - Implemented A1-4-1 Requirements on code metrics.
Plenty of AUTOSAR
C++14 Coding Guidelines rules
forbid constructs that introduce
unnecessary complexity and
are error-prone, e.g. A9-6-2,
M10-2-1, A10-2-1.
1b Use of language subsets 6 - Implemented 3.1 Plenty of AUTOSAR C++14
Coding Guidelines rules forbid
constructs that are allowed from
the C++ language perspective,
but (1) lead to unstructured
designs, (2)
are misleading for a developer,
(3) are implementation defined.
In case some features are to
be used in a particular project
nonetheless, see chapter 5.4.
1c Enforcement of strong typing 6 - Implemented M5-2-2,
M5-2-3,
A5-2-2,
A5-2-3,
M5-2-6,
A5-2-4,
M5-2-9,
A8-4-14,
A7-2-3
Restrictions on type casting.
Recommendations on strongly-
typed interfaces and scoped
enums.
1d Use of defensive
implementation techniques
6 - Implemented A0-4-4,
A4-7-1,
A5-2-5,
A6-5-1,
A14-1-1,
A15-3-4
Error checking
required for math functions,
integer expressions, array
access. Limitations on iteration
statements. Recommendations
on how to cope with external
code failures.
1e Use of established design
principles
6 - Implemented 6.18.5,
A18-5-2,
A0-1-4
Recommendation on RAII,
exception in rules that facilitate
correct usage of SFINAE and
Concepts. Multiple
rules contain references to
corresponding rules
from multiple standards, which
confirms that the provided rule
set reflects widely approved
coding techniques.
1f Use of unambiguous
graphical representation
8 - Not applicable Recommendations on graphical
representation is out of scope
of AUTOSAR C++14 Coding
Guidelines.
1g Use of style guides 8 - Not applicable AUTOSAR C++14 Coding
Guidelines does not introduce
rules related to coding style.
1h Use of naming conventions 8 - Not applicable AUTOSAR
C++14 Coding Guidelines does
not introduce rules related to
naming convention.
Table B.7: Topics to be covered by modelling and coding guidelines. Table 1 from [5].
8: Software unit design and implementation
8.4: Requirements and recommendations
ISO 26262 requirement: Relation type: Related rule: Comment:
1a Natural language 7 - Partially
implemented
A2-7-3, A2-7-5 Requirements on: providing
documentation for user-defined
types, content and structure of
the documentation.
1b Informal notations
1c Semi-formal notations
1d Formal notations
Table B.8: Notations for software unit design. Table 7 from [5].
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1a One entry and one exit
point in subprograms
and functions
6 - Implemented See Single-point-of-exit. All
the benefits from this approach are
handled by different measures. Code
modularity aspects are also ensured
by techniques and limitations that
fulfill other ISO26262 requirements,
see: Enforcement of low complexity,
Readability and comprehensibility,
Suitability for modifications.
1b No dynamic objects
or variables, or else
online test during their
creation
6 - Implemented A18-5-5,
A18-5-6,
A18-5-7,
A18-5-2,
A18-5-9,
A18-5-10
Dynamic memory allowed, but under
multiple constraints affecting memory
management. Allocated objects
lifetime maintenance delegated to
shared
pointers and memory management
objects. Restrictions set for custom
implementations of dynamic memory
allocation and placement new.
1c Initialization of
variables
6 - Implemented A8-5-0,
A3-3-2,
A6-5-4,
A8-5-1,
A8-5-3,
A8-5-4,
A12-1-1,
A12-1-2,
A12-1-6
Required is: memory initialization
before access, constant initialization
of static and thread–local objects, loop
counters initialization. Defined are
requirements
for: initialization lists, initialization of
type auto, user-declared constructors,
NSDMI, delegating constructors.
1d No multiple use of
variable names
6 - Implemented M2-10-1,
A2-10-1,
A2-10-6,
A2-10-4,
A2-10-5,
M3-4-1
Limitations on
identifier hiding and requirements on
typographical unambiguity .
1e Avoid global variables
or else justify their
usage
7 - Partially
implemented
A3-3-2 Global variables shall be constant-
initialized.
1f Limited use of pointers 6 - Implemented A8-4-11,
A8-4-10,
M5-0-15,
M5-0-16,
M5-0-17,
M5-0-18,
A5-0-4,
A5-0-3
Lifetime semantics is to be handled
using smart pointers and usage of
raw pointers is limited only to passing
parameters that are not owned by
the pointer (as currently no constructs
from C++14 Standard could replace
it), which resolves problems with
possible memory leaks. Restrictions
on pointers arithmetic, no more
than two levels of pointer indirection,
pointers usage limited only to single
objects. Listed rule set fulfills also
all the requirements described in
[19], chapter C.2.6.6 “Limited use of
pointers”, apart from “Data exchange
should be done via the operating
system”, which is out of scope of this
document.
1g No implicit type
conversions
6 - Implemented A4-5-1,
A4-7-1,
M4-10-1,
M5-0-4,
M5-0-5,
M5-0-6,
A7-2-3,
A8-5-2,
A13-5-2,
A13-5-3,
A23-0-1
It is
forbidden to use: enums in arithmetic
contexts, integer conversions that lead
to data loss, NULL as an integer value,
non-scoped enumerations, conversion
from iterator to const_iterator.
It is additionally protected by forcing:
braced initialization
of variables and restrictions on user-
defined conversion operators.
1h No hidden data or
control flow
7 - Partially
implemented
A15-0-6,
A15-0-7,
A15-0-8,
6.15
Usage of exceptions as a method
for error handling is not enforced
by the AUTOSAR Coding Guidelines.
However, if it is to be used in a
particular project, it (1) is allowed
only if strict requirements on a
toolchain are fulfilled, e.g. analysis of
failure modes of exception handling,
deterministic worst-
case execution time. (2) is forbidden
as part of the typical program flow
and is limited only for handling errors
where a function failed to perform
its assigned task. (3) requires
analysis of maximum execution time
constraints for a particular software
project. Using Checked Exceptions
for signaling recoverable errors brings
benefits to completeness of error
handling procedure, as it enforces
developers to provide a dedicated
handling hook for each type of such
errors. Rules for stack unwinding are
unambiguously defined by [3, ISO/IEC
14882:2014], thus it is possible to
establish a matching catch clause
for each exception thrown in the
software, to which the control flow
will jump after exception is thrown.
By default, handling of Unchecked
Exceptions should lead to proper
program termination, therefore stack
unwinding ensures correct invocation
of destructors for all objects with
automatic storage duration,
which prevents from possible memory
leaks in case of errors (considering
no violations of available rules for
memory management). However,
usage of exceptions still introduces
a hidden control flow into a program
execution, thus such an approach only
partially implements this requirement
from the ISO26262-6 [5].
1i No unconditional
jumps
6 - Implemented A6-6-1,
M17-0-2
Lack of
exact definition of “unconditional jump”
in ISO 26262 [5] and C++14 Standard
[3], therefore the statement from IEC
61508 Annex C [19] was assumed:
“avoid unconditional jumps (goto) in
higher level languages”.
1j No recursions 6 - Implemented A7-5-2
Table B.9: Design principles for software unit design and implementation. Table 8 from
[5].
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1a correct order of execution of
subprograms and
functions within the software
units, based on the software
architectural design
6 - Implemented A15-4-1,
A15-4-2,
A15-5-2,
A15-5-3
Restrictions on constructs that
may lead
to program termination without
calling proper exit handlers and
destructors.
1b consistency of the interfaces
between the software units
6 - Implemented M1-0-2,
A15-1-5
Restrictions on: passing non-
standard layout type
objects and exceptions across
execution boundaries.
1c correctness of data flow and
control flow between and
within the software units
6 - Implemented M0-3-1
A15-0-1,
A15-0-4,
A15-0-5,
A15-3-2,
A15-3-3,
A15-3-4,
M15-0-3,
A6-6-1
Checked and Unchecked
exceptions are to be used
only for error handling, they
are forbidden for handling the
normal control flow. Additional
explanation of this property
from [19]: “The software design
shall include, commensurate
with the required safety integrity
level, self-monitoring of control
flow and data flow. On failure
detection, appropriate actions
shall be taken. ”
1d simplicity 6 - Implemented A1-4-1,
A8-4-3,
A10-1-1,
A14-7-2
Forcing limitations for cases
that limit maintainability and
readability .
1e readability and
comprehensibility
6 - Implemented A1-4-1,
A1-4-3,
A5-1-1,
A5-1-9,
A10-2-1,
M10-2-1,
A12-7-1,
A14-7-2
Enforcing code
metrics, forbidding constructs
that are confusing, lead to
code duplication or introduce
unnecessary complexity .
1f robustness 6 - Implemented M0-3-1,
M0-3-2,
A1-1-1,
A15-0-2,
A15-0-3,
A15-0-6,
A15-0-7,
A18-5-6
Checked exceptions concept
which facilitates tracking if a
particular error type is handled.
Recommendations on how to
report errors in an application.
Requirements on analysis of
failure modes and worst-case
execution
time for exception handling and
memory management.
1g suitability for software
modification
6 - Implemented A8-4-14,
A10-0-1,
A10-0-2,
A10-4-1
Recommending constructs that
increase software reusability ,
eliminate redundancy and hide
implementation details.
1h testability 6 - Implemented A1-2-1,
A1-4-1,
A3-3-2
Requirements on: testing error
information if this is generated,
using code metrics
which will increase code quality
and modularity . Restrictions on
constructs that obscure code
maintainability . Suggestions
on how to perform extensive
testing.
Table B.10: Properties to be achieved by applying design principles from Table 8.
Paragraph 8.4.4 from [5].
ISO 26262 requirement: Relation type: Related
rule:
Comment:
1a Walk-through 8 - Not applicable Process of system examination
to reveal discrepancies
between a specification and
implementation is out of scope
of AUTOSAR C++14 Coding
Guidelines.
1b Inspection 8 - Not applicable Structured processes (at any
level of rigour) of revealing
defects in developed software
components are out of scope
of AUTOSAR C++14 Coding
Guidelines.
1c Semi-formal verification 8 - Not applicable Aspects
of proving the correctness
of a program basing on an
abstract model are out of
scope of AUTOSAR C++14
Coding Guidelines.
1d Formal verification
1e Control flow analysis 7 - Partially
implemented
M0-1-1,
M0-1-2,
M0-1-8,
M0-1-9,
M0-1-10,
A0-1-3
Available are rules oriented
on finding suspect areas of
code (e.g. inaccessible code,
infeasible paths), but analysis
of directed program graph (from
the definition from paragraph
C.5.9 [19]) is out of scope
of AUTOSAR C++14 Coding
Guidelines.
1f Data flow analysis 6 - Implemented M0-1-3,
M0-1-4,
A0-1-1,
A0-1-4,
A0-1-5,
A0-1-6,
A8-5-0
Available are rules oriented on
analysis of sequences
of creating, referencing and
deleting variables.
1g Static code analysis 6 - Implemented All automated rules included
in AUTOSAR C++14 Coding
Guidelines are enforceable by
means of static code analysis.
1h Semantic code analysis 8 - Not applicable Mathematical
source code analysis by use
of an abstract representation of
possible values is out of scope
of AUTOSAR C++14 Coding
Guidelines.
Table B.11: Methods for the verification of software unit design and implementation.
Table 9 from [5].
C Glossary
Abbreviation / Acronym: Description:
Real-time application (RT A) A real-time application is a program that guarantees response
within defined time constraints. The latency must be less than
a defined value, usually measured in seconds or milliseconds.
Whether or not a given application program qualifies as an
RT A depends on the worst-case execution time (WCET) - the
maximum length of time a defined task requires on a given
hardware platform.
MISRA Motor Industry Software Reliability Association.
HIC++ High Integrity C++ Coding Standard.
cvalue expression An expression that should not undergo further conversions, either
implicitly or explicitly , is called a cvalue expression.
Ownership Ownership of a resource means that the resource’s lifetime is
fully managed by the single class instance or tied with the class
instance lifetime. See also: chapter 6.18.5
One definition rule The rule states that:
• There shall be one and only one definition of any variable,
function, class type, enumeration type, or template in
a translation unit. Some of these may have multiple
declarations, but only one definition is allowed.
• There shall be one and only one definition of every non-
inline function or variable that is odr-used in the entire
program.
• An inline function definition is required in every translation
unit where it is odr-used.
• There shall be one and only one definition of a class in
any translation unit where the class is used in a way that
requires it to be complete.
• There can be more than one definition of any class,
enumeration type, inline function with external linkage,
class template, non-static function template, static data
member of a class template, member function of a class
template, partial template specialization in a program, as
long as all of the following is true:
– each definition consists of the same sequence of
tokens (typically , appears in the same header file)
– name lookup from within each definition finds the
same entities (after overload-resolution), except that
constants with internal or no linkage may refer to
different objects as long as they are not ODR-used
and have the same values in every definition.
– overloaded operators, including conversion,
allocation, and deallocation functions refer to the
same function from each definition (unless referring
to one defined within the definition)
– the language linkage is the same (e.g. the include
file isn’t inside an extern “C” block)
– the three rules above apply to every default
argument used in each definition
– if the definition is for a class with an implicitly-
declared constructor, every translation unit where it
is odr-used must call the same constructor for the
base and members
– if the definition is for a template, then all these
requirements apply to both names at the point of
definition and dependent names at the point of
instantiation
If all these requirements are satisfied, the program
behaves as if there is only one definition in the entire
program. Otherwise, the behavior is undefined.
ODR-use An object is odr-used if its address is taken, or a reference is
bound to it. A function is odr-used if a function call to it is made
or its address is taken.
POD T ype POD (Plain Old Data) type is the type that is compatible with
types used in the C programming language, can be manipulated
using C library functions, and can be exchanged with C libraries
directly in its binary form.
Trivially Copyable Class A class (C++ Language Standard [3], chapter 9):
• where each copy constructor, move constructor, copy
assignment operator, move assigment operator is either
deleted or trivial
• that has at least one non-deleted copy constructor,
move constructor, copy assignment operator, or move
assignment operator, and
• that has a trivial, non-deleted destructor
Standard-Layout Class A class that (C++ Language Standard [3], chapter 9):
• has no non-static data members of type non-standard-
layout class (or array of such types) or reference
• has no virtual functions and no virtual base classes
• has the same access control for all non-static data
members
• has no non-standard-layout base classes
• has at most one base class subobject of any given type
• has all non-static data members and bit-fields in the class
and its base classes first declared in the same class
• has no element of the set M(X) of types as a base class
where M(X) is defined as follows:
– If X is a non-union class type, the set M(X) is
empty if X has no (possibly inherited) non-static
data members; otherwise, it consists of the type of
the first non-static data member of X (where said
member may be an anonymous union), X0, and the
elements of M(X0).
– If X is a union type, the set M(X) is the union of all
M(Ui) and the set containing all Ui, where each Ui is
the type of the i-th non-static data member of X.
– If X is a non-class type, the set M(X) is empty .
Dataflow Anomaly The state of a variable at a point in a program can be described
using the following terms:
• Undefined (U): The value of the variable is indeterminate.
• Referenced (R): The variable is used in some way (e.g. in
an expression).
• Defined (D): The variable is explicitly initialized or assigned
a value.
Given the above, the following dataflow anomalies can be
defined:
• UR dataflow anomaly: Variable not assigned a value
before the specified use (this may result in undefined
behavior).
• DU dataflow anomaly: Variable is assigned a value that is
never subsequently used.
• DD dataflow anomaly: Variable is assigned a value twice
with no intermediate use.
Dead Code Dead code (also known as redundant code) consists of evaluated
expressions whose removal would not affect the output program.
Unreachable Code Unreachable code is code to which there is no syntactic (control
flow) path, e.g. a function which is never called, either directly or
indirectly .
Diamond Problem The “diamond problem” is an ambiguity that arises when two
classes B and C inherit from A, and class D inherits from both B
and C. If there is a method provided by class A, that is overriden
in both B and C and D does not override it, then there is an
ambiguity which version of the method does D actually inherit.
See: Wikipedia.org for more details.
Interface class An interface class is a class which has following properties:
• if there are any , all member functions are public pure
virtual
• if there are any , all data members are public static
constexpr
Extended precision format The IEEE Standard for Floating-Point Arithmetic (IEEE 754)
specifies extended precision formats, that are recommended for
allowing a greater precision format than that provided by the
basic formats.
For an extended format the exponent range must be as great
as that of the next wider basic format. For instance, 64-bit
extended precision binary number must have an “exponent max”
of at least 16383, which is equal to “exponent max” of 128-
bit binary floating-point. The 80-bit extended format meets this
requirement.
Fundamental types C++ built-in types defined in C++ Language Standard [3] in
chapter 3.9.1, e.g. char, signed char, unsigned char, int, long
long int, wchar_t, bool, float, double, void, std::nullptr_t, etc.
Scalar types The following types are scalar types:
• integral types
• floating point types
• pointers and pointers to members
• enumerations
• std::nullptr_t
glvalue A glvalue is an expression whose evaluation determines the
identity of an object, bit-field, or function.
xvalue An xvalue refers to an object, usually near the end of its lifetime,
so that its resources may be moved.
prvalue A prvalue is an expression whose evaluation initializes an object
or a bit-field, or computes the value of the operand of an operator.
rvalue An rvalue is an xvalue or a prvalue.
lvalue An lvalue is a glvalue that is not an xvalue.
Implicitly-defined default
constructor
Implicitly-defined default constructor calls default constructors of
its base classes and non-static data members. It has exactly the
same effect as a user-defined constructor with empty body and
empty initializer list.
Implicitly-defined copy
constructor
Implicitly-defined copy constructor of a class type (class or struct)
performs full member-wise copy of the object’s bases and non-
static data members, in their initialization order, using direct
initialization.
Implicitly-defined move
constructor
Implicitly-defined move constructor of a class type (class or
struct) performs full member-wise move of the object’s bases
and non-static members, in their initialization order, using direct
initialization with an xvalue argument.
Implicitly-defined copy
assignment operator
Implicitly-defined copy assignment operator of a class type
(class or struct) performs full member-wise copy assignment
of the object’s bases and non-static data members, in their
initialization order, using built-in assignment for the scalars and
copy assignment operator for class types.
Implicitly-defined move
assignment operator
Implicitly-defined move assignment operator of a class type
(class or struct) performs full member-wise move assignment
of the object’s direct bases and immediate non-static data
members, in their initialization order, using built-in assignment
for the scalars, member-wise move-assignment for arrays, and
move assignment operator for class types (called non-virtually).
Implicitly-defined destructor Implicitly-defined destructor has an empty body . After the body of
the destructor is executed, the destructors for all non-static non-
variant data members of the class are called, in reverse order
of declaration. Then it calls destructors of all direct non-virtual
base classes, in reverse order of construction, and then it calls
the destructors of all virtual bases.
Is-a relationship Subsumption relationship between types. If one class B is a
subclass of another class A (i.e. B is a more specialized concept
than A), then B class specification implies A class specification
and a B class object can be used for any expression that requires
an A class object.
Has-a relationship Composition relationship where one object is a part or member
of another object with respect to the rules of ownership.
Table C.1: Acronyms
Definition: Description:
Single point of exit Approach background:
• IEC 61508 [19], as one of methods for providing modular
approach
• ISO26262 part 6 [5] with the requirement for ASIL A-D.
• MISRA-C++ 2008 with the rule M6-6-5.
AUTOSAR Coding Guidelines consider that the only reason for
such an approach is improving robustness of resource handling,
e.g. ensuring that resources are properly released in case of an
early exit from the function. However, it is fully ensured by other
rules existing in the document that:
• enforce usage of smart
pointers and memory management objects for expressing
lifetime semantics (A18-5-2)
• enforce allocate local objects on stack (A18-5-8)
• recommend usage of RAII (A15-1-4, A18-5-2)
Single point of exit is considered to decrease code readability
and will not bring any additional benefits for improving coding
standards, thus it is not enforced by the AUTOSAR Coding
Guidelines.
Table C.2: Definitions
D Changelog
This section shows changes done between document releases.
D.1 Release 17-10
Type of change: Modified rules:
Title, example, exceptions A7-1-7, A15-0-4, A15-0-5, A15-3-1, A18-5-2
Rule classification A9-3-1
References A0-4-3, M3-4-1, M5-2-12, A5-0-1, A5-1-2, A5-1-4, A6-5-2, M7-
1-2, M7-5-2, A7-1-1, A7-1-7, A8-4-1, M9-3-3, A12-0-1, A12-8-6,
A18-5-2, A18-9-2
New rule A0-1-4, A0-1-5, A6-5-3, A8-4-4, A9-5-1, A12-1-5, A12-1-6, A13-
5-2, A18-1-6, A18-5-8
MISRA review changes A0-1-3, A2-10-5, A5-1-7, M10-1-2
Other Traceability updated for HIC (see B.2), CERT (see B.4), C++
Core Guidelines (see B.5). Added changelog appendix chapter.
Table D.1: Changelog for release 17-10.
D.2 Release 18-03
Type of change: Modified rules:
Title, example, exceptions A1-4-1, A2-3-1, A2-7-3, A2-8-1, A3-3-2, A5-2-5, A12-0-1, A12-8-
1, A13-3-1, A15-0-5, A15-3-2, A15-3-3, A15-4-5, A15-5-1, A18-
0-2, A18-1-1, A18-1-4, A18-1-6, A18-5-8
Rule classification, numbering A5-6-1, A2-13-1, A2-13-2, A2-13-3, 6.2.5 (A2-5-2), 6.2.8 (A2-8-1)
6.2.10 (A2-10-1, A2-10-4, A2-10-5), A15-0-6, A15-0-7, A15-0-8,
A15-1-1, A15-3-3, A18-1-1
Chapter numbering 6.2.3 (A2-3-1), 6.2.5 (A2-5-2), 6.2.8 (A2-8-1) 6.2.10 (A2-10-1,
A2-10-4, A2-10-5)
References, notes M0-1-9, A2-7-3, A2-8-1, A3-3-2, A4-7-1, A5-0-1, M5-0-2, A5-2-1,
A5-2-5, M5-2-2, A6-5-1, A7-1-7, A8-5-2, A9-3-1, A12-1-1, A12-4-
1, A12-4-2, A13-5-2, A14-1-1, A15-0-4, A15-0-5, A15-4-1, A15-
5-2, A15-5-3, M18-0-4, M18-0-5, A18-5-5
New rule A0-1-6, A0-4-4, A1-4-3, M2-7-1, A2-7-5, A2-8-2, A2-10-6, A2-11-
1, A2-13-4, A2-13-5, A2-13-6, A3-1-5, A3-1-6, A3-8-1, A5-0-4,
A5-1-9, A5-2-6, A5-3-2, A5-3-3, A5-5-1, A6-2-1, A6-5-4, A7-1-9,
A7-2-5, A7-3-1, A7-6-1, A8-4-5, A8-4-6, A8-4-8, A8-4-9, A8-4-10,
A8-4-11, A8-4-12, A8-4-13, A8-5-0, A10-0-1, A10-0-2, A10-4-1,
A12-0-2, A13-5-3, A13-5-4, A14-5-1, A14-7-2, A14-8-2, A17-6-1,
A18-5-9, A18-5-10, A20-8-1, A20-8-2, A20-8-3, A20-8-4, A20-8-
5, A20-8-6, A20-8-7, A21-8-1, A23-0-2, A25-1-1, A25-4-1, A26-
5-1, A26-5-2, A27-0-3, A27-0-4
Removed rule M0-1-5, A1-4-2, A2-7-4, A2-10-2, A2-10-3, M2-10-6, A5-1-5, M5-
2-1, M7-3-5, M8-5-1, A13-1-1, M14-5-2, M14-7-3, A14-8-1, M14-
8-1, A15-3-1, A15-4-6, A18-1-5
Definitions Is-a-relationship, Has-a-relationship
Other Traceability updated for MISRA (see B.1), HIC++ (see B.2), JSF
(see B.3), CERT (see B.4), C++ Core Guidelines (see B.5)
Table D.2: Changelog for release 18-03.
D.3 Release 18-10
Type of change: Modified rules:
Title, example, exceptions A8-5-2, A8-5-4, A9-6-1, A10-2-1, A11-3-1, A13-5-4, A15-4-3,
A16-2-2, A16-2-3, A18-5-2, A18-5-3
References, notes A5-0-4
New rule A6-2-2, A8-4-14, M9-6-4, A13-5-5, A14-5-2, A14-5-3, A18-5-11
Other Traceability updated for MISRA (see B.1), C++ Core Guidelines
(see B.5), HIC++ (see B.2). Traceability added for ISO 26262
(see B.6).
Table D.3: Changelog for release 18-10.
See also:
• SEI CERT C++ Coding Standard [10]: FIO39-C: Do not alternately input and
output from a stream without an intervening flush or positioning call
• SEI CERT C++ Coding Standard [10]: FIO50-CPP: Do not alternately input and
output from a file stream without an intervening positioning call
7 References
Bibliography
[1] ISO/IEC 14882:2003, The C++ Standard Incorporating Technical Corrigendum 1 ,
International Organization for Standardization, 2003.
[2] ISO/IEC 14882:2011, ISO International Standard ISO/IEC 14882:2011(E) -
Programming Language C++ , International Organization of Standardization, 2011.
[3] ISO/IEC 14882:2014, ISO International Standard ISO/IEC 14882:2014(E) -
Programming Language C++, International Organization for Standardization, 2016.
[4] ISO 26262-6, Road vehicles - Functional safety - Part 6: Product development at
the software level, International Organization for Standardization, 2011.
[5] ISO 26262-6, Road vehicles - Functional safety - Part 6: Product development at
the software level, International Organization for Standardization, 2011.
[6] ISO 26262-8, Road vehicles - Functional safety - Part 8: Supporting processes ,
International Organization for Standardization, 2011.
[7] MISRA C++:2008 Guidelines for the use of the C++ language in critical systems ,
The Motor Industry Software Reliability Association, 2008.
[8] Joint Strike Fighter Air Vehicle C++ Coding Standards for the System Development
and Demonstration Program , Document Number 2RDU00001 Rev C, Lockheed
Martin Corporation, 2005.
[9] High Integrity C++ Coding Standard Version 4.0, Programming Research Ltd, 2013.
[10] Software Engineering Institute CERT C++ Coding Standard , Software
Engineering Institute Division at Carnegie Mellon University , 2016.
[11] Bjarne Stroustrup, Herb Sutter, C++ Core Guidelines , 2017.
[12] Google C++ Style Guide , Google, 2017.
[13] Scott Meyers, Effective Modern C++ , ISBN: 978-1-491-90399-5, O’Reilly , 2015.
[14] Bjarne Stroustrup, The C++ Programming Language, Fourth Edition , ISBN: 978-
0-321-56384-2, Addison-Wesley , 2013.
[15] Joshua Bloch, Effective Java, Second Edition , ISBN: 978-0321356680, Addison-
Wesley , 2008
[16] cppreference.com, online reference for the C and C++ languages and standard
libraries, 2017
[17] stackoverflow.com, community of programmers, 2017
[18] open-std.org, site holding a number of web pages for groups producing open
standards, 2017
[19] IEC 61508-3, Functional safety of electrical/electronic/programmable electronic
safety-related systems – Annex C, Overview of techniques and measures for
achieving software safety integrity , International Electrotechnical Commission,
2010.
A Allocation of rules to work products
This chapter lists the rules that are allocated to ISO 26262 work products or activities
that are impacted by the usage of C++ (in particular for software architectural design
specification, software unit design specification, toolchain and others).
The rules listed below can be used as guidelines for peforming those activities or as
checklists for performing reviews. For example, it can be used for performing the review
of software architectural design specification.
A.1 Rules allocated to architecture
A2-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A2-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
A2-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
M2-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
A2-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
A2-13-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
A2-13-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
M2-13-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A2-13-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A2-13-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A3-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
A3-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
A3-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A4-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
A15-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
A15-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
A15-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
A15-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
A.2 Rules allocated to design
A2-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A2-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
A2-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
M2-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
A2-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
A2-10-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
A2-11-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
A2-13-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
A2-13-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
M2-13-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A2-13-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A2-13-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A3-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
A3-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
A3-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A3-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A3-1-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A3-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
A4-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
A7-2-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
A8-4-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .156
A8-4-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .157
A8-4-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158
A8-4-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159
A8-4-7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
A8-4-8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .162
A8-4-9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .163
A8-4-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
A8-4-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
A8-4-12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
A8-4-13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
A8-4-14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
A9-6-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .184
A9-6-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .185
A10-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
A10-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
A10-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
A14-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
A14-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
A15-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
A15-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
A15-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
A15-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
A.3 Rules allocated to toolchain
A0-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A0-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
M1-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A1-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A1-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A1-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
A15-0-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
A15-0-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
A15-0-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
A18-5-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
A18-5-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
A.4 Rules allocated to infrastructure
A0-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A.5 Rules allocated to analysis
A.6 Rules allocated to hardware
A.7 Rules allocated to management
A.8 Rules allocated to verification
M0-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
A1-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
A15-0-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
A15-0-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
A15-0-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
A18-5-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
A.9 Rules allocated to implementation
M0-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
M0-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
M0-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
M0-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
A0-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
A0-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
M0-1-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
M0-1-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
M0-1-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A0-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A0-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
A0-1-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
A0-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
M0-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
M0-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
M0-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
M0-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
M0-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A0-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
A0-4-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
A1-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
A1-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A1-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
A1-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A2-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A2-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
A2-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
M2-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
A2-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
A2-7-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
A2-7-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
A2-7-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
A2-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
A2-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
M2-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
A2-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
A2-10-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
A2-10-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47
A2-10-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
A2-11-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
A2-13-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
A2-13-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
A2-13-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
M2-13-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
M2-13-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A2-13-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .52
A2-13-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A2-13-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
A3-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
A3-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
A3-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
M3-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A3-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
M3-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
M3-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
M3-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
M3-2-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
A3-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
A3-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
M3-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
M3-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
A3-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
M3-9-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
A3-9-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
M3-9-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
M4-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
A4-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
M4-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
A4-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
M4-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
A4-10-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
M4-10-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
A5-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
M5-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
M5-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
M5-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
M5-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
M5-0-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
M5-0-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
M5-0-12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
A5-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
M5-0-14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
M5-0-15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
M5-0-16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
M5-0-17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
A5-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
M5-0-18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
A5-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
M5-0-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
M5-0-21 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
A5-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
A5-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
A5-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
A5-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
A5-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
A5-1-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
A5-1-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
A5-1-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
M5-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
M5-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
A5-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
A5-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
A5-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
M5-2-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
A5-2-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
A5-2-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100
M5-2-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
M5-2-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
M5-2-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
M5-2-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
A5-2-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102
M5-2-12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
M5-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
M5-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
M5-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
M5-3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
A5-3-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105
A5-3-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .106
A5-3-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107
A5-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109
A5-6-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .110
M5-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
A5-10-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
M5-14-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
A5-16-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
M5-17-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
M5-18-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
M5-19-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
M6-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
A6-2-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .114
A6-2-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .116
M6-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
M6-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
M6-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
M6-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
M6-4-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
A6-4-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
A6-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .120
A6-5-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
M6-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
M6-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
M6-5-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
M6-5-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
M6-5-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
A6-5-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .124
A6-5-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .125
A6-6-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .126
M6-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
M6-6-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
M6-6-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
A7-1-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .127
A7-1-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .128
M7-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
A7-1-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
A7-1-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
A7-1-5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
A7-1-6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .133
A7-1-7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .134
A7-1-8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .135
A7-1-9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .136
A7-2-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
A7-2-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .139
A7-2-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .140
A7-2-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
M7-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
M7-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
M7-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
M7-3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
A7-3-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
M7-3-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
A7-4-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .146
M7-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
M7-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
M7-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
M7-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
M7-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
A7-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .147
A7-5-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149
A7-6-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .151
M8-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
A8-2-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .152
M8-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
A8-4-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
M8-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
A8-4-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155
M8-4-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
A8-5-0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
A8-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173
M8-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
A8-5-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
A8-5-3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .177
A8-5-4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .178
M9-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
A9-3-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .180
M9-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
A9-5-1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .182
M9-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
M9-6-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
A10-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
M10-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
M10-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
M10-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
M10-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
A10-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
A10-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
A10-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
A10-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
A10-3-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
M10-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
M11-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
A11-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
A11-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
A11-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
A12-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
A12-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
A12-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
M12-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
A12-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
A12-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
A12-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
A12-1-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
A12-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
A12-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
A12-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
A12-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
A12-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
A12-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
A12-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
A12-8-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
A12-8-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
A12-8-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
A12-8-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
A12-8-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
A13-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
A13-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
A13-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
A13-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
A13-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
A13-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
A13-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
A13-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
A13-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
A13-5-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
A13-5-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
A13-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
A14-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
A14-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
M14-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
M14-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
A14-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
A14-7-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
A14-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
A15-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
A15-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
A15-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
A15-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
A15-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
A15-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
A15-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
M15-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
M15-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
M15-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
M15-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
A15-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
A15-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
A15-1-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
A15-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
A15-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
M15-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
A15-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
A15-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
A15-3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
M15-3-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
M15-3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
A15-3-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
M15-3-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
M15-3-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
A15-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
A15-4-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
A15-4-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
A15-4-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
A15-4-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
A15-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
A15-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
A15-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
A16-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
M16-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
M16-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
M16-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
M16-0-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
M16-0-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
M16-0-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
M16-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
M16-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
M16-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
A16-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
A16-2-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
A16-2-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
M16-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
M16-3-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
A16-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
A16-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
A17-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
M17-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
M17-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
A17-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
M17-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
A17-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
A17-6-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
A18-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
A18-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
M18-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
M18-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
M18-0-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
A18-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
A18-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
A18-1-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
A18-1-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
A18-1-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
A18-1-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
M18-2-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
A18-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
A18-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
A18-5-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
A18-5-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
A18-5-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
A18-5-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
A18-5-9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
A18-5-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
A18-5-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
M18-7-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
A18-9-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
A18-9-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
A18-9-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
A18-9-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
M19-3-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
A20-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
A20-8-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
A20-8-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
A20-8-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
A20-8-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
A20-8-6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
A20-8-7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
A21-8-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
A23-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
A23-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
A25-1-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
A25-4-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
A26-5-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
A26-5-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
M27-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
A27-0-1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
A27-0-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
A27-0-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
A27-0-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
B Traceability to existing standards
This section demonstrates the traceability of AUTOSAR C++14 rules to existing
important C++ coding standards and to ISO 26262.
For each rule, the relation is identified:
1. Identical (only for MISRA C++): the rule text, rationale, exceptions, code example
are identical. Only the rule classification can be different. There can be also an
additional note with clarifications.
2. Small differences: the content of the rule is included by AUTOSAR C++14 rules
with minor differences.
3. Significant differences: the content of the rule is included by AUTOSAR C++14
rules with significant differences.
4. Rejected: the rule in the referred document is rejected by AUTOSAR C++14
guidelines.
5. Not yet analyzed: The rule is not yet analyzed in the current release.
6. Implemented (only for ISO 26262): A clause is implemented by the AUTOSAR
C++14 rules.
7. Partially implemented (only for ISO 26262): A clause covered to some extent that
is in scope of this document.
8. Not applicable (only for ISO 26262): A clause that is out of scope of this
document.
B.1 Traceability to MISRA C++:2008
MISRA C++:2008 [7] is a required prerequisite for readers of the document. MISRA
C++:2008 can be purchased over MISRA web store.
The following table demonstrates the traceability to MISRA C++:2008. This is not
considered as a reproduction of a part of MISRA C++:2008, but a mean to compare
the two standards.
MISRA Rule: Relation type: Related
rule:
Comment:
0-1-1 (Required) A project shall not
contain unreachable code.
1 - Identical M0-1-1 -
0-1-2 (Required) A project shall not
contain infeasible paths.
2 - Small differences M0-1-2 Note about
constexpr functions
added.
0-1-3 (Required) A project shall not
contain unused variables.
1 - Identical M0-1-3 -
0-1-4 (Required) A project shall not
contain non-volatile POD variables
having only one use.
1 - Identical M0-1-4 -
0-1-5 (Required) A project shall not
contain unused type declarations.
3 - Significant differences A0-1-6 Obligation
level changed to
“Advisory”.
0-1-6 (Required) A project shall
not contain instances of non-volatile
variables being given values that are
never subsequently used.
2 - Small differences A0-1-1 Example reworked.
0-1-7 (Required) The value returned
by a function having a non-void return
type that is not an overloaded operator
shall always be used.
2 - Small differences A0-1-2 Rationale
reformulated.
0-1-8 (Required) All functions with void
return type shall have external side
effect(s).
1 - Identical M0-1-8 -
0-1-9 (Required) There shall be no
dead code.
1 - Identical M0-1-9 -
0-1-10 (Required)
Every defined function shall be called
at least once.
3 - Significant differences M0-1-10,
A0-1-2
Rule divided into:
(1) Identical rule
with obligation level
“Advisory”, (2) Rule
with obligation level
“Required”
which applies to
static functions and
private methods.
0-1-11 (Required) There shall be
no unused parameters (named or
unnamed) in non-virtual functions.
3 - Significant differences A0-1-4 Unused
parameters
are allowed to be
unnamed.
0-1-12 (Required) There shall be
no unused parameters (named or
unnamed) in the set of parameters for
a virtual function and all the functions
that override it.
3 - Significant differences A0-1-5 Unused
parameters
are allowed to be
unnamed.
0-2-1 (Required) An object shall not be
assigned to an overlapping object.
1 - Identical M0-2-1 -
0-3-1 (Document) Minimization of run-
time failures shall be ensured by the
use of at least one of: (a) static
analysis tools/techniques; (b) dynamic
analysis tools/techniques; (c) explicit
coding of checks to handle run-time
faults.
1 - Identical M0-3-1 -
0-3-2 (Required) If a function
generates error information, then that
error information shall be tested.
1 - Identical M0-3-2 -
0-4-1 (Document) Use of scaled-
integer or fixed-point arithmetic shall
be documented.
1 - Identical M0-4-1 -
0-4-2 (Document) Use of floating-point
arithmetic shall be documented.
1 - Identical M0-4-2 -
0-4-3 (Document) Floating-point
implementations shall comply with a
defined floating-point standard.
3 - Significant differences A0-4-1 Specified that
floating-point
implementations
need to
comply with IEEE
754 standard.
1-0-1 (Required) All code shall
conform to ISO/IEC 14882:2003 “The
C++ Standard Incorporating Technical
Corrigendum 1”.
2 - Small differences A1-1-1 Specified that the
code shall conform
to ISO/IEC
14882:2014.
1-0-2 (Document) Multiple compilers
shall only be used if they have a
common, defined interface.
1 - Identical M1-0-2 -
1-0-3 (Document) The implementation
of integer division in the chosen
compiler shall be determined and
documented.
3 - Significant differences A0-4-2 Specified that
the implementation
of integer division
shall comply with
the C++ Language
Standard.
2-2-1 (Document) The character set
and the corresponding encoding shall
be documented.
3 - Significant differences A2-3-1
2-3-1 (Required) Trigraphs shall not be
used.
2 - Small differences A2-5-1 All trigraphs listed
in rationale.
Example extended.
2-5-1 (Advisory) Digraphs should not
be used.
3 - Significant differences A2-5-2 Obligation
level changed to
“Required”.
2-7-1 (Required)
The character sequence /* shall not be
used within a C-style comment.
1 - Identical M2-7-1 -
2-7-2 (Required) Sections of code shall
not be commented out using C-style
comments.
2 - Small differences A2-7-1 Commenting-
out code sections
is not allowed.
2-7-3 (Advisory) Sections of code
should not be “commented out” using
C++ comments.
2 - Small differences A2-7-1 Obligation
level changed to
“Required”.
Commenting-
out code sections
is not allowed.
2-10-1 (Required) Different identifiers
shall be typographically unambiguous.
1 - Identical M2-10-1 -
2-10-2 (Required) Identifiers declared
in an inner scope shall not hide an
identifier declared in an outer scope.
2 - Small differences A2-10-1 Added a note to
rationale. Example
extended.
2-10-3 (Required) A typedef name
(including qualification, if any) shall be
a unique identifier.
4 - Rejected This rule is
considered as too
restrictive.
2-10-4 (Required) A class, union or
enum name (including qualification, if
any) shall be a unique identifier.
4 - Rejected This rule is
considered as too
restrictive.
2-10-5 (Advisory) The identifier name
of a non-member object or function
with static storage duration should not
be reused.
3 - Significant differences A2-10-4 Obligation
level changed to
“Required”. Scope
of the rule
changed.
2-10-6 (Required) If an identifier refers
to a type, it shall not also refer to an
object or a function in the same scope.
2 - Small differences A2-10-6
2-13-1 (Required) Only those escape
sequences that are defined in ISO/IEC
14882:2003 shall be used.
2 - Small differences A2-13-1 Standard changed
to ISO/IEC
14882:2014.
2-13-2 (Required) Octal constants
(other than zero) and octal escape
sequences (other than “\0” ) shall not
be used.
1 - Identical M2-13-2 -
2-13-3 (Required) A “U” suffix shall
be applied to all octal or hexadecimal
integer literals of unsigned type.
1 - Identical M2-13-3 -
2-13-4 (Required) Literal suffixes shall
be upper case.
1 - Identical M2-13-4 -
2-13-5 (Required)
Narrow and wide string literals shall not
be concatenated.
2 - Small differences A2-13-2 Example extended.
3-1-1 (Required) It shall be possible
to include any header file in multiple
translation units without violating the
One Definition Rule.
3 - Significant differences A3-1-1 Rationale
reformulated.
Example extended.
3-1-2 (Required) Functions shall not be
declared at block scope.
1 - Identical M3-1-2 -
3-1-3 (Required) When an array is
declared, its size shall either be
stated explicitly or defined implicitly by
initialization.
2 - Small differences A3-1-4 Specified that
this rule applies to
arrays with external
linkage only .
3-2-1 (Required) All declarations of
an object or function shall have
compatible types.
1 - Identical M3-2-1 -
3-2-2 (Required) The One Definition
Rule shall not be violated.
1 - Identical M3-2-2 -
3-2-3 (Required) A type, object or
function that is used in multiple
translation units shall be declared in
one and only one file.
1 - Identical M3-2-3 -
3-2-4 (Required) An identifier with
external linkage shall have exactly one
definition.
1 - Identical M3-2-4 -
3-3-1 (Required) Objects or functions
with external linkage shall be declared
in a header file.
2 - Small differences A3-3-1 Added a note to
rationale. Example
extended.
3-3-2 (Required) If a function has
internal linkage then all re-declarations
shall include the static storage class
specifier.
1 - Identical M3-3-2 -
3-4-1 (Required) An identifier declared
to be an object or type shall be defined
in a block that minimizes its visibility .
1 - Identical M3-4-1 -
3-9-1 (Required) The types used for
an object, a function return type, or a
function parameter shall be token-for-
token identical in all declarations and
re-declarations.
1 - Identical M3-9-1 -
3-9-2 (Advisory) typedefs that indicate
size and signedness should be used in
place of the basic numerical types.
3 - Significant differences M3-9-1 Rule
title and rationale
reformulated to use
types from
<cstdint> header
file. All types that
should be
used were listed.
Example changed.
3-9-3 (Required) The underlying bit
representations of floating-point values
shall not be used.
1 - Identical M3-9-3 -
4-5-1 (Required) Expressions with type
bool shall not be used as operands
to built-in operators other than the
assignment operator =, the logical
operators &&, ||, !, the equality
operators == and !=, the unary &
operator, and the conditional operator.
1 - Identical M4-5-1 -
4-5-2 (Required) Expressions with type
enum shall not be used as operands
to built-in operators other than the
subscript operator [ ], the assignment
operator =, the equality operators ==
and !=, the unary & operator, and the
relational operators <, <=, >, >=.
3 - Significant differences A4-5-1 Changed the rule
so it applies to
enum classes too.
M10M10 (MISRA 유래)M10 (MISRA-origin)
M10-1-1Advisory · Automated✓ compilable
비인터페이스 클래스를 둘 이상 상속하지 않는다Classes should not be derived from more than one base class that is not an interface class
❌ 위반 예시Non-compliant example
#include <iostream>
struct Engine { void run() { std::cout << "run\n"; } int rpm = 0; }; // 구현+데이터
struct Logger { void log() { std::cout << "log\n"; } int level = 0; }; // 구현+데이터
struct Car : public Engine, public Logger {}; // 다중 구현 상속 — 결합·모호성
int main() { Car c; c.run(); c.log(); }✅ 준수 예시Compliant example
#include <iostream>
struct Engine { void run() { std::cout << "run\n"; } int rpm = 0; };
struct ILogger { virtual void log() = 0; virtual ~ILogger() = default; }; // 순수 인터페이스
struct Car : public ILogger { // 인터페이스만 상속
Engine engine_; // 구현은 구성(composition)으로 보유
void run() { engine_.run(); }
void log() override { std::cout << "log\n"; }
};
int main() { Car c; c.run(); c.log(); }⚠️ 근거: 데이터·구현을 가진 클래스를 둘 이상 상속하면, 두 기반의 멤버·이름이 한 파생 클래스에 합쳐져 이름 모호성과 강한 결합이 생기고, 공통 조상이 있으면 다이아몬드 문제로 기반 서브오브젝트가 중복된다. 영향: 어떤 기반의 멤버인지 모호해 잘못된 멤버를 참조하거나, 한 기반의 변경이 무관한 기능까지 깨뜨리고, 초기화·레이아웃이 복잡해져 추론이 어렵다. 대응: 다중 상속은 데이터 없는 순수 가상 인터페이스에 한정하고, 구현 재사용은 멤버로 보유하는 구성(composition)으로 해결한다.Rationale: deriving from more than one class that carries data and implementation merges both bases members and names into one derived class, creating name ambiguity and tight coupling, and with a common ancestor the diamond problem duplicates the base subobject. Impact: it becomes ambiguous which base a member belongs to (referencing the wrong one), a change in one base breaks unrelated functionality, and initialization and layout grow complex and hard to reason about. Fix: limit multiple inheritance to data-free pure-virtual interfaces and reuse implementation through composition by holding members.
M10-1-2Required · Automated✓ compilable
가상 기반 클래스는 데이터 없는 추상 인터페이스로만 둔다A base class shall only be declared virtual if it is used in a diamond hierarchy
❌ 위반 예시Non-compliant example
#include <iostream>
struct Base { int data_ = 0; }; // 데이터를 가진 클래스를
struct D : virtual public Base { // 가상 기반으로 — 초기화 책임이 최파생으로 이동
void set() { data_ = 1; }
};
int main() { D d; d.set(); std::cout << d.data_ << '\n'; }✅ 준수 예시Compliant example
#include <iostream>
struct IBase { // 데이터 없는 추상 인터페이스
virtual void f() = 0;
virtual ~IBase() = default;
};
struct D : virtual public IBase {
void f() override { std::cout << "f\n"; }
};
int main() { D d; d.f(); }⚠️ 근거: 가상 상속에서는 가상 기반 서브오브젝트가 최종 파생 클래스에 의해 한 번만 생성·초기화되는데, 그 기반이 데이터 멤버를 가지면 초기화 책임과 레이아웃이 계층 전체로 퍼져 복잡해진다. 영향: 데이터를 가진 가상 기반은 어느 생성자가 그 멤버를 초기화하는지 추적하기 어렵게 만들고, 가상 기반 포인터 조정(virtual base offset)으로 성능·디버깅 부담이 커진다. 대응: 가상 기반(다이아몬드 구조의 공유 기반)은 데이터 없는 순수 가상 인터페이스로 한정하고, 공유해야 할 상태는 별도 설계로 분리한다.Rationale: in virtual inheritance the virtual base subobject is constructed and initialized exactly once by the most-derived class, and if that base has data members the initialization responsibility and layout spread across the whole hierarchy, growing complex. Impact: a virtual base with data makes it hard to track which constructor initializes those members, and virtual-base pointer adjustment adds performance and debugging burden. Fix: limit a virtual base (the shared base of a diamond) to a data-free pure-virtual interface, and separate any shared state through a different design.
M10-1-3Required · Automated✓ compilable📄 공식 예제Official example
An accessible base class shall not be both virtual and non-virtual in the same hierarchy.An accessible base class shall not be both virtual and non-virtual in the same hierarchy.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M10-1-3: An accessible base class shall not be both virtual and non-virtual in the same hierarchy. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.10.2 Member name lookupSee MISRA C++ 2008 [7]
6.10.2 Member name lookup
M10-2-1Advisory · Automated✓ compilable📄 공식 예제Official example
All accessible entity names within a multiple inheritance hierarchy should be unique.All accessible entity names within a multiple inheritance hierarchy should be unique.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M10-2-1: All accessible entity names within a multiple inheritance hierarchy should be unique. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M10-3-3Required · Automated✓ compilable📄 공식 예제Official example
A virtual function shall only be overridden by a pure virtual function if it is itself declared as pure virtual.A virtual function shall only be overridden by a pure virtual function if it is itself declared as pure virtual.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M10-3-3: A virtual function shall only be overridden by a pure virtual function if it is itself declared as pure virtual. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
See: A10-3-2 for pure virtual function overriders declaration.
6.10.4 Abstract ClassesSee MISRA C++ 2008 [7]
See: A10-3-2 for pure virtual function overriders declaration.
6.10.4 Abstract Classes
M12M12 (MISRA 유래)M12 (MISRA-origin)
M12-1-1Required · Automated✓ compilable
생성자/소멸자 안에서 객체의 동적 타입에 의존하지 않는다An object dynamic type shall not be used from the body of its constructor or destructor
❌ 위반 예시Non-compliant example
#include <iostream>
struct Base {
Base(); // 정의는 Derived 가 완전해진 뒤로
virtual ~Base() = default;
};
struct Derived : Base { void f() { std::cout << "f\n"; } };
Base::Base() {
// 생성 중 동적 타입은 Base — dynamic_cast 가 파생(Derived)을 인식하지 못함
if (dynamic_cast<Derived*>(this) == nullptr)
std::cout << "ctor sees Base only (not Derived)\n";
}
int main() { Derived d; } // Base() 는 d 를 Derived 로 보지 못함✅ 준수 예시Compliant example
#include <iostream>
struct Base {
Base() = default;
virtual ~Base() = default;
};
struct Derived : Base {
void f() { std::cout << "f\n"; }
void start() { f(); } // 생성 완료 후 별도 단계에서 파생 동작 호출
};
int main() { Derived d; d.start(); }⚠️ 근거: 객체가 생성·소멸되는 동안에는 동적 타입이 현재 실행 중인 생성자/소멸자의 클래스로 고정되므로, 그 안에서의 dynamic_cast 나 가상 디스패치는 아직(또는 이미) 존재하지 않는 파생 부분을 인식하지 못한다. 영향: 생성자에서 dynamic_cast<Derived*>(this) 가 nullptr 을 돌려주거나 가상 호출이 기반 버전으로 가, 파생 초기화를 기대한 코드가 조용히 잘못 동작한다. 대응: 파생 타입에 의존하는 동작은 생성이 완전히 끝난 뒤 별도의 초기화 메서드(start() 등)에서 수행한다.Rationale: while an object is being constructed or destroyed, its dynamic type is fixed to the class of the currently running constructor/destructor, so a dynamic_cast or virtual dispatch inside does not recognize the derived part that does not yet (or no longer) exist. Impact: a dynamic_cast<Derived*>(this) in a constructor returns nullptr or a virtual call goes to the base version, so code expecting derived initialization silently misbehaves. Fix: perform behaviour that depends on the derived type in a separate initialization method (such as start()) after construction fully completes.
M15M15 (MISRA 유래)M15 (MISRA-origin)
M15-1-2Required · Automated✓ compilable
NULL(널 포인터 상수)을 throw 하지 않는다NULL shall not be thrown explicitly
❌ 위반 예시Non-compliant example
#include <iostream>
struct ResourceError {};
int main() {
try {
throw NULL; // 포인터가 아니라 정수 0 으로 해석되어 던져짐
}
catch (ResourceError*) { std::cout << "as pointer\n"; } // 잡지 못함
catch (...) { std::cout << "caught as integer, not a pointer\n"; } // 이쪽으로 감
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
int main() {
try {
throw std::runtime_error("null result"); // 의미 있는 예외 객체
}
catch (const std::exception& e) { std::cout << e.what() << '\n'; }
}⚠️ 근거: NULL 은 널 포인터처럼 보이지만 실제로는 정수 상수(0 또는 구현정의 정수형)라, throw NULL 은 포인터가 아니라 정수 값을 던진다. 영향: 던진 측은 널 포인터 예외를 의도했는데 catch(SomeType*) 같은 포인터 핸들러는 이를 잡지 못하고, 정수 핸들러나 catch(...) 로만 잡혀 의도와 다른 처리가 되거나 잡히지 않아 terminate 로 간다. 대응: 오류는 std::exception 에서 파생된 의미 있는 예외 객체로 던져, 타입과 메시지로 일관되게 처리되게 한다.Rationale: NULL looks like a null pointer but is actually an integer constant (0 or an implementation-defined integer type), so throw NULL throws an integer value, not a pointer. Impact: the thrower intends a null-pointer exception, but a pointer handler like catch(SomeType*) does not catch it — only an integer handler or catch(...) does — leading to handling that differs from intent or going uncaught to terminate. Fix: throw a meaningful exception object derived from std::exception so it is handled consistently by type and message.
M15-3-4Required · Automated✓ compilable
발생할 수 있는 모든 예외는 어딘가에서 catch 되어야 한다Each exception explicitly thrown in the code shall have a handler of a compatible type
❌ 위반 예시Non-compliant example
#include <stdexcept>
static void run(int argc) { if (argc >= 0) throw std::runtime_error("boom"); } // 가드: 항상 참
int main(int argc, char**) {
run(argc); // 어떤 try 로도 감싸지 않음 → 예외가 main 밖으로 → std::terminate
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
static void run() { throw std::runtime_error("boom"); }
int main() {
try { run(); }
catch (const std::exception& e) { std::cout << "handled: " << e.what() << '\n'; return 1; }
catch (...) { std::cout << "unknown error\n"; return 1; }
}⚠️ 근거: 던져진 예외가 호환되는 타입의 핸들러를 만나지 못하고 호출 스택을 끝까지(즉 main 밖으로) 빠져나가면, 표준은 std::terminate 를 호출하도록 규정한다. 영향: 처리되지 않은 예외는 진단 메시지 없이 프로그램을 비정상 종료시키고, 스택 풀기 수행 여부조차 구현 정의라 소멸자가 안 불려 자원이 남을 수 있다. 대응: 최상위 진입점(main 과 각 스레드 함수)에서 std::exception 과 catch(...) 로 모든 예외를 포착해 로깅·정의된 종료 코드로 처리한다.Rationale: if a thrown exception finds no handler of a compatible type and escapes the call stack all the way out of main, the standard mandates a call to std::terminate. Impact: an unhandled exception aborts the program with no diagnostic, and whether stack unwinding even runs is implementation-defined, so destructors may not be called and resources can leak. Fix: at the top-level entry points (main and each thread function) catch all exceptions with std::exception and catch(...) and handle them with logging and a defined exit code.
M15-3-6Required · Automated✓ compilable
catch 핸들러는 가장 파생된 것부터 기본 순으로 배치한다Where multiple handlers are provided, they shall be ordered most-derived to base class
❌ 위반 예시Non-compliant example
#include <iostream>
#include <stdexcept>
int main() {
try { throw std::logic_error("bad arg"); }
catch (const std::exception& e) { // 기반 먼저 — 파생도 여기서 잡힘
std::cout << "generic: " << e.what() << '\n';
}
catch (const std::logic_error& e) { // 도달 불가 — 컴파일러 경고
std::cout << "specific: " << e.what() << '\n';
}
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
int main() {
try { throw std::logic_error("bad arg"); }
catch (const std::logic_error& e) { // 파생(구체적) 먼저
std::cout << "specific: " << e.what() << '\n';
}
catch (const std::exception& e) { // 기반(일반) 나중
std::cout << "generic: " << e.what() << '\n';
}
}⚠️ 근거: catch 핸들러는 선언된 순서대로 검사되며 던져진 예외와 호환되는 첫 핸들러가 선택된다(가상 디스패치가 아니라 순차 매칭). 영향: 기반 클래스 핸들러를 먼저 두면 모든 파생 예외가 거기서 잡혀, 뒤에 둔 더 구체적인 핸들러는 영영 도달하지 못해 의도한 세분화 처리가 사라진다. 대응: 핸들러를 가장 파생된 타입부터 기반 타입 순으로 배치해 구체적 예외가 먼저 잡히게 한다.Rationale: catch handlers are examined in declaration order and the first one compatible with the thrown exception is chosen (sequential matching, not virtual dispatch). Impact: placing a base-class handler first catches all derived exceptions there, so a more specific handler placed afterwards is never reached and the intended fine-grained handling is lost. Fix: order handlers from the most derived type down to the base type so specific exceptions are caught first.
M15-3-7Required · Automated
catch-all(...) 핸들러는 마지막에 둔다Where multiple handlers are provided, any ellipsis (catch-all) handler shall occur last
❌ 위반 예시Non-compliant example
try { f(); }
catch (...) { ... } // catch-all 이 먼저 — 모든 예외를 흡수
catch (const std::exception& e) { ... } // 도달 불가
// gcc 는 이를 하드 에러로 거부: "'...' handler must be the last handler" — 컴파일 불가✅ 준수 예시Compliant example
try { f(); }
catch (const std::exception& e) { ... } // 구체 핸들러 먼저
catch (...) { ... } // catch-all 은 마지막⚠️ 근거: catch(...) 는 모든 타입의 예외와 호환되므로, 핸들러 목록에서 그 앞의 어떤 구체 핸들러보다 먼저 두면 모든 예외를 가장 먼저 흡수해 버린다. 영향: catch-all 을 앞에 두면 뒤따르는 std::exception 등 구체 핸들러가 도달 불가가 되어, 타입별 정보를 활용한 세분화된 처리가 모두 무력화된다. 대응: 구체적인 타입 핸들러들을 먼저 나열하고, 마지막에 남은 모든 예외를 위한 catch(...) 를 둔다.Rationale: catch(...) is compatible with exceptions of every type, so placing it before any specific handler in the list makes it absorb all exceptions first. Impact: a leading catch-all renders the following specific handlers (like std::exception) unreachable, disabling all fine-grained handling that uses type information. Fix: list specific-type handlers first and place catch(...) last for any remaining exceptions.
M15-0-3Required · Automated✓ compilable📄 공식 예제Official example
Control shall not be transferred into a try or catch block using a goto or a switch statement.Control shall not be transferred into a try or catch block using a goto or a switch statement.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M15-0-3: Control shall not be transferred into a try or catch block using a goto or a switch statement. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M15-1-1Required · Automated✓ compilable📄 공식 예제Official example
The assignment-expression of a throw statement shall not itself cause an exception to be thrown.The assignment-expression of a throw statement shall not itself cause an exception to be thrown.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M15-1-1: The assignment-expression of a throw statement shall not itself cause an exception to be thrown. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M15-1-3Required · Automated✓ compilable📄 공식 예제Official example
An empty throw (throw;) shall only be used in the compound statement of a catch handler.An empty throw (throw;) shall only be used in the compound statement of a catch handler.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M15-1-3: An empty throw (throw;) shall only be used in the compound statement of a catch handler. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M15-3-3Required · Automated✓ compilable📄 공식 예제Official example
Handlers of a function-try-block implementation of a class constructor or destructor shall not reference non-static members from this class or its bases.Handlers of a function-try-block implementation of a class constructor or destructor shall not reference non-static members from this class or its bases.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M15-3-3: Handlers of a function-try-block implementation of a class constructor or destructor shall not reference non-static members from this class or its bases. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M16M16 (MISRA 유래)M16 (MISRA-origin)
M16-0-6Required · Automated✓ compilable
함수형 매크로의 매개변수와 전체를 괄호로 감싼다In the definition of a function-like macro, each instance of a parameter shall be enclosed in parentheses
❌ 위반 예시Non-compliant example
#include <iostream>
#define DOUBLE(x) x + x // 매개변수·전체에 괄호 없음
int main() {
int a = 3;
int r = DOUBLE(a) * 2; // 3 + 3 * 2 = 9 (의도는 (3+3)*2 = 12)
std::cout << r << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#define DOUBLE(x) ((x) + (x)) // 매개변수와 전체를 괄호로 보호
int main() {
int a = 3;
int r = DOUBLE(a) * 2; // ((3)+(3)) * 2 = 12
std::cout << r << '\n';
}⚠️ 근거: 함수형 매크로는 토큰을 그대로 치환할 뿐 함수처럼 인자를 평가하지 않으므로, 매개변수와 전체 식을 괄호로 보호하지 않으면 호출 문맥의 연산자 우선순위가 치환 결과에 끼어든다. 영향: DOUBLE(a) * 2 가 a + a * 2 로 전개되어 의도한 (a+a)*2 와 다른 값을 내는 등, 인자가 복합 식일 때 조용한 계산 오류가 발생한다. 대응: 가능하면 매크로 대신 inline 함수·템플릿을 쓰고, 불가피한 함수형 매크로는 각 매개변수 사용처와 전체 본문을 괄호로 감싼다.Rationale: a function-like macro merely substitutes tokens rather than evaluating arguments like a function, so without parenthesizing the parameters and the whole expression, the operator precedence of the call context bleeds into the substituted result. Impact: DOUBLE(a) * 2 expands to a + a * 2, producing a value different from the intended (a+a)*2 — a silent computation error when the argument is a compound expression. Fix: prefer inline functions or templates over macros, and for unavoidable function-like macros wrap each parameter use and the whole body in parentheses.
M16-3-2Advisory · Automated✓ compilable
전처리기 # 와 ## 연산자를 사용하지 않는다The # and ## operators should not be used
❌ 위반 예시Non-compliant example
#include <iostream>
#define MAKE(name) int value_##name = 0 // ## 토큰 붙이기 — 디버깅·검색 어려움
int main() {
MAKE(alpha); // int value_alpha = 0; 로 전개 — grep 으로 찾기 힘든 이름 생성
std::cout << value_alpha << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
int main() {
int value_alpha = 0; // 명시적 코드 — 이름이 그대로 드러나 검색·디버깅 용이
std::cout << value_alpha << '\n';
}⚠️ 근거: 전처리기 # (문자열화)와 ## (토큰 결합)는 평가·치환 순서 규칙이 까다롭고, 결과로 만들어진 식별자나 문자열이 소스 코드에 그대로 나타나지 않는다. 영향: ## 로 합성한 이름(value_##name)은 grep·IDE 검색으로 찾기 어렵고, 디버거가 매크로 전개 후 코드를 보여주지 못해 추적이 힘들며, 중첩 매크로에서는 전개 결과가 직관과 달라 미묘한 버그가 생긴다. 대응: 가능한 한 # / ## 를 피하고 명시적 코드나 타입 안전한 템플릿·constexpr 로 대체하며, 불가피하면 한 곳에 격리해 문서화한다.Rationale: the preprocessor # (stringize) and ## (token paste) operators have tricky evaluation and substitution ordering rules, and the resulting identifiers or strings do not appear literally in the source. Impact: a name synthesized with ## (value_##name) is hard to find with grep or IDE search, debuggers cannot show post-expansion code, and in nested macros the expansion result differs from intuition, creating subtle bugs. Fix: avoid # / ## where possible, replacing them with explicit code or type-safe templates and constexpr, and isolate and document any unavoidable use.
M16-0-1Required · Automated✓ compilable📄 공식 예제Official example
#include directives in a file shall only be preceded by other pre-processor directives or comments.#include directives in a file shall only be preceded by other pre-processor directives or comments.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-0-1: #include directives in a file shall only be preceded by other pre-processor directives or comments. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M16-0-2Required · Automated✓ compilable📄 공식 예제Official example
Macros shall only be #define’d or #undef’d in the global namespace.Macros shall only be #define’d or #undef’d in the global namespace.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-0-2: Macros shall only be #define'd or #undef'd in the global namespace. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M16-0-5Required · Automated✓ compilable📄 공식 예제Official example
Arguments to a function-like macro shall not contain tokens that look like pre-processing directives.Arguments to a function-like macro shall not contain tokens that look like pre-processing directives.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-0-5: Arguments to a function-like macro shall not contain tokens that look like pre-processing directives. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Function-like macros are anyway not allowed, see A16-0-1. This rule is kept in
case A16-0-1 is disabled in a project.See MISRA C++ 2008 [7]
Note: Function-like macros are anyway not allowed, see A16-0-1. This rule is kept in
case A16-0-1 is disabled in a project.
M16-0-7Required · Automated✓ compilable📄 공식 예제Official example
Undefined macro identifiers shall not be used in #if or #elif pre-processor directives, except as operands to the defined operator.Undefined macro identifiers shall not be used in #if or #elif pre-processor directives, except as operands to the defined operator.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-0-7: Undefined macro identifiers shall not be used in #if or #elif pre-processor directives, except as operands to the defined operator. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: “#if” and “#elif” are anyway only allowed for conditional file inclusion, see A16-0-
1. This rule is kept in case A16-0-1 is disabled in a project.See MISRA C++ 2008 [7]
Note: “#if” and “#elif” are anyway only allowed for conditional file inclusion, see A16-0-
1. This rule is kept in case A16-0-1 is disabled in a project.
M16-0-8Required · Automated✓ compilable📄 공식 예제Official example
If the # token appears as the first token on a line, then it shall be immediately followed by a pre-processing token.If the # token appears as the first token on a line, then it shall be immediately followed by a pre-processing token.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-0-8: If the # token appears as the first token on a line, then it shall be immediately followed by a pre-processing token. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.16.1 Conditional inclusionSee MISRA C++ 2008 [7]
6.16.1 Conditional inclusion
M16-1-1Required · Automated✓ compilable📄 공식 예제Official example
The defined pre-processor operator shall only be used in one of the two standard forms.The defined pre-processor operator shall only be used in one of the two standard forms.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-1-1: The defined pre-processor operator shall only be used in one of the two standard forms. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: “#if defined” is anyway only allowed for conditional file inclusion, see A16-0-1.
This rule is kept in case A16-0-1 is disabled in a project.See MISRA C++ 2008 [7]
Note: “#if defined” is anyway only allowed for conditional file inclusion, see A16-0-1.
This rule is kept in case A16-0-1 is disabled in a project.
M16-1-2Required · Automated✓ compilable📄 공식 예제Official example
All #else, #elif and #endif pre-processor directives shall reside in the same file as the #if or #ifdef directive to which they are related.All #else, #elif and #endif pre-processor directives shall reside in the same file as the #if or #ifdef directive to which they are related.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-1-2: All #else, #elif and #endif pre-processor directives shall reside in the same file as the #if or #ifdef directive to which they are related. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: “#if”, “#elif”, “#else” and “#ifded” are anyway only allowed for conditional file
inclusion, see A16-0-1. This rule is kept in case A16-0-1 is disabled in a project.
6.16.2 Source file inclusionSee MISRA C++ 2008 [7]
Note: “#if”, “#elif”, “#else” and “#ifded” are anyway only allowed for conditional file
inclusion, see A16-0-1. This rule is kept in case A16-0-1 is disabled in a project.
6.16.2 Source file inclusion
M16-2-3Required · Automated✓ compilable📄 공식 예제Official example
Include guards shall be provided.Include guards shall be provided.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-2-3: Include guards shall be provided. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M16-3-1Required · Automated✓ compilable📄 공식 예제Official example
There shall be at most one occurrence of the # or ## operators in a single macro definition.There shall be at most one occurrence of the # or ## operators in a single macro definition.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M16-3-1: There shall be at most one occurrence of the # or ## operators in a single macro definition. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Operators # and ## are anyway not allowed, see M16-3-2. This rule is kept in
case M16-3-2 is disabled in a project.See MISRA C++ 2008 [7]
Note: Operators # and ## are anyway not allowed, see M16-3-2. This rule is kept in
case M16-3-2 is disabled in a project.
M17M17 (MISRA 유래)M17 (MISRA-origin)
M17-0-5Required · Automated✓ compilable
setjmp / longjmp 를 사용하지 않는다The setjmp macro and the longjmp function shall not be used
❌ 위반 예시Non-compliant example
#include <csetjmp>
#include <iostream>
static std::jmp_buf env;
struct Guard { ~Guard() { std::cout << "cleanup\n"; } }; // longjmp 시 호출 안 됨
static void work() {
Guard g;
std::longjmp(env, 1); // g 의 소멸자를 건너뛰고 점프 — 자원 누수
}
int main() {
if (setjmp(env) == 0) work();
else std::cout << "recovered (but cleanup skipped)\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <stdexcept>
struct Guard { ~Guard() { std::cout << "cleanup\n"; } };
static void work() {
Guard g;
throw std::runtime_error("fail"); // 예외 — 스택 풀기로 g 정상 소멸
}
int main() {
try { work(); }
catch (const std::exception&) { std::cout << "recovered\n"; }
}⚠️ 근거: longjmp 는 C 의 비지역 점프로, 스택을 되감을 때 그 사이에 살아 있던 C++ 자동 객체의 소멸자를 전혀 호출하지 않으며, 비trivial 객체가 있는 스코프를 건너뛰는 longjmp 자체가 미정의 동작이다. 영향: RAII 로 잠금·메모리·파일을 관리하던 객체가 정리되지 않아 누수·교착이 발생하고, C++ 객체 모델과 예외 안전성이 깨진다. 대응: 비지역 제어 이동과 오류 복구는 예외 처리(throw/catch)로 구현해 스택 풀기 중 소멸자가 항상 실행되게 한다.Rationale: longjmp is C non-local jump that, when rewinding the stack, does not call destructors of any C++ automatic objects alive in between, and a longjmp that skips a scope containing non-trivial objects is itself undefined behaviour. Impact: objects managing locks, memory, or files via RAII are not cleaned up, causing leaks or deadlock and breaking the C++ object model and exception safety. Fix: implement non-local control transfer and error recovery with exception handling (throw/catch) so destructors always run during unwinding.
M17-0-2Required · Automated✓ compilable📄 공식 예제Official example
The names of standard library macros and objects shall not be reused.The names of standard library macros and objects shall not be reused.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M17-0-2: The names of standard library macros and objects shall not be reused. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M17-0-3Required · Automated✓ compilable📄 공식 예제Official example
The names of standard library functions shall not be overridden.The names of standard library functions shall not be overridden.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M17-0-3: The names of standard library functions shall not be overridden. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M18M18 (MISRA 유래)M18 (MISRA-origin)
M18-0-3Required · Automated✓ compilable
<cstdlib> 의 abort/exit/getenv/system 을 사용하지 않는다The library functions abort, exit, getenv and system from <cstdlib> shall not be used
❌ 위반 예시Non-compliant example
#include <cstdlib>
#include <iostream>
static int g_runtime_false = 0; // 검증 시 실제 호출은 회피(패턴만 시연)
int main() {
if (g_runtime_false) {
std::system("rm -rf /tmp/x"); // 셸 인젝션·이식성 위험
std::exit(1); // 스택 풀기·소멸자 건너뜀
}
std::cout << "shows forbidden calls, guarded\n";
}✅ 준수 예시Compliant example
#include <iostream>
enum class Status { Ok, Error };
static Status run() { return Status::Error; }
int main() {
Status s = run();
if (s == Status::Error) { std::cout << "error path\n"; return 1; } // 정상 반환 경로
std::cout << "ok\n";
return 0;
}⚠️ 근거: std::system 은 인자를 셸에 넘겨 실행하므로 입력이 섞이면 셸 인젝션 취약점이 되고 동작이 환경(셸·OS)에 의존하며, std::exit/abort 는 스택 풀기 없이 프로세스를 끝내 활성 객체의 소멸자를 건너뛴다. 영향: system 으로 외부 명령을 부르면 보안·이식성이 무너지고, exit/abort 로 갑자기 종료하면 열린 파일·잠금·버퍼가 정리되지 않아 데이터 손상·누수가 남는다. 대응: 외부 작업은 셸을 거치지 않는 안전한 내부 API 로, 종료는 예외나 반환 코드로 정상 흐름을 통해 처리한다.Rationale: std::system passes its argument to a shell, so mixed-in input becomes a shell-injection vulnerability and behaviour depends on the environment (shell, OS), while std::exit/abort end the process without stack unwinding, skipping destructors of active objects. Impact: calling external commands via system breaks security and portability, and abruptly terminating with exit/abort leaves open files, locks, and buffers uncleaned, causing corruption and leaks. Fix: perform external work through safe internal APIs that do not go through a shell, and handle termination via exceptions or return codes through the normal flow.
M18-0-5Required · Automated✓ compilable
<cstring> 의 경계 없는(unbounded) 함수를 사용하지 않는다The unbounded functions of library <cstring> shall not be used
❌ 위반 예시Non-compliant example
#include <cstring>
#include <iostream>
int main() {
char dst[32];
const char* src = "fits here";
std::strcpy(dst, src); // 경계 없는 복사 — src 가 dst 보다 길면 오버플로우
std::cout << dst << '\n'; // (여기선 들어맞지만 strcpy 자체가 검사 없는 위험 API)
}✅ 준수 예시Compliant example
#include <string>
#include <iostream>
int main() {
std::string dst = "fits here"; // 길이를 자동 관리 — 경계 초과 불가
std::cout << dst << '\n';
}⚠️ 근거: strcpy·strcat·strlen·gets 등 <cstring> 의 경계 없는 함수는 대상 버퍼의 크기를 인자로 받지 않아, 원본이 대상보다 길어도 검사 없이 계속 기록·탐색한다. 영향: 입력 길이를 통제할 수 없는 상황에서 이런 함수를 쓰면 버퍼 오버플로우로 인접 메모리·반환 주소가 덮여 크래시·코드 실행 공격으로 이어지며, 이는 가장 흔한 메모리 취약점 부류다. 대응: 길이를 스스로 관리하는 std::string 을 쓰거나, 불가피하면 크기를 받는 경계 있는 연산(strncpy 의 올바른 사용·std::snprintf·std::copy_n)으로 대체한다.Rationale: unbounded functions in <cstring> such as strcpy, strcat, strlen, and gets take no destination buffer size, so they keep writing or scanning unchecked even when the source is longer than the destination. Impact: using them where input length is not controlled causes buffer overflows that overwrite adjacent memory and return addresses, leading to crashes and code-execution attacks — the most common class of memory vulnerability. Fix: use std::string, which manages length itself, or when unavoidable use size-taking bounded operations (correct use of strncpy, std::snprintf, std::copy_n).
M18-7-1Required · Automated✓ compilable
<csignal> 의 시그널 처리를 사용하지 않는다The signal handling facilities of <csignal> shall not be used
❌ 위반 예시Non-compliant example
#include <csignal>
#include <iostream>
static volatile std::sig_atomic_t g_stop = 0;
extern "C" void on_sigint(int) { g_stop = 1; } // 비동기·구현정의 제약이 큰 핸들러
int main() {
std::signal(SIGINT, on_sigint); // 시그널 기반 제어 — 안전필수에 부적합
std::cout << "signal handler installed\n";
}✅ 준수 예시Compliant example
#include <iostream>
#include <atomic>
static std::atomic<bool> g_stop{false};
static bool stop_requested() { return g_stop.load(); }
int main() {
// 결정적 이벤트/플래그 폴링으로 종료 요청 처리(여기선 즉시 종료)
int steps = 0;
while (!stop_requested() && steps < 3) { ++steps; }
std::cout << "cooperative loop done, steps=" << steps << '\n';
}⚠️ 근거: 시그널은 프로그램 흐름과 비동기적으로 끼어들고, 핸들러 안에서 호출 가능한 함수가 async-signal-safe 한 극소수로 제한되며 그 동작 상당 부분이 구현정의다. 영향: 핸들러에서 비안전 함수(동적 할당·예외·비POD 입출력)를 부르면 락·힙이 일관되지 않은 순간에 진입해 교착·손상·크래시가 나고, 제어 흐름이 비결정적이 되어 안전필수 시스템의 검증을 어렵게 한다. 대응: 종료·중단 요청 같은 비동기 이벤트는 시그널 대신 결정적 메커니즘(원자적 플래그 폴링, 이벤트 루프, OS 의 동기적 통지)으로 처리한다.Rationale: signals interrupt program flow asynchronously, the set of functions callable in a handler is restricted to a tiny async-signal-safe subset, and much of the behaviour is implementation-defined. Impact: calling unsafe functions (dynamic allocation, exceptions, non-POD I/O) in a handler enters while locks or the heap are inconsistent, causing deadlock, corruption, or crashes, and makes control flow nondeterministic, hindering verification of safety-critical systems. Fix: handle asynchronous events like stop/abort requests with deterministic mechanisms instead of signals — atomic-flag polling, an event loop, or synchronous OS notifications.
M18-0-4Required · Automated✓ compilable📄 공식 예제Official example
The time handling functions of library <ctime> shall not be used.The time handling functions of library <ctime> shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M18-0-4: The time handling functions of library <ctime> shall not be used. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Facilities from <chrono> shall be used instead.See MISRA C++ 2008 [7]
Note: Facilities from <chrono> shall be used instead.
M18-2-1Required · Automated✓ compilable📄 공식 예제Official example
The macro offsetof shall not be used.The macro offsetof shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M18-2-1: The macro offsetof shall not be used. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.18.5 Dynamic memory management
The dynamic memory management provides flexible mechanism of allocating and
deallocating blocks of memory during run-time phase of the program. The application
is allowed to acquire as much memory as it needs in its current state, and return it once
the memory is not used.
Moreover, this is a convenient way of extending lifetime of objects outside the functions
where the objects were created. In other words, a function can create objects on
dynamic memory and then exit and the objects that were created in the dynamic
memory are preserved and can be used subsequently by other functions.
The dynamic memory management uses the Operating System routines to
allocate and deallocate memory , what introduces several issues. Therefore, the
AUTOSAR C++14 Coding Guidelines defines specific rules for appropriate usage and
implementation of dynamic memory management.
Challenges arising due to dynamic memory usage
Issue: Solution:
Memory leaks RAII design pattern usage is highly recommended
for managing resource and memory acquisition and
release (A18-5-2). It is prohibited to make calls
to new and delete operators explicitly , to force
programmers to assign each allocated memory
block to manager object which deallocates the
memory automatically on leaving its scope. Also,
the form of delete operator used for memory
deallocation needs to match the form of new
operator used for memory allocation (A18-5-3).
Memory fragmentation Memory allocator used in the project needs to
guarantee that no memory fragmentation occurs
(A18-5-5).
Invalid memory access C-style functions malloc/calloc/realloc must not be
used in the project, so memory block can not be
accessed as it would be of another type. Memory
allocator used in the project needs to guarantee that
objects do not overlap in the physical storage (A18-
5-5).
Erroneous memory allocations The application program needs to define the
maximum amount of dynamic memory it needs,
so running out of memory must not occur during
faultless execution. The memory would be pre-
allocated before run-time phase of the program
(A18-5-5).
Not deterministic execution time of memory
allocation and deallocation
Memory allocator used in the project needs to
guarantee that memory allocation and deallocation
are executed within defined time constraints that
are appropriate for the response time constraints
defined for the real-time system and its programs
(A18-5-7).
Table 6.2: Challenged of dynamic memory usage
Ownership and smart pointers
Memory allocated dynamically requires strict control of objects or functions that are
responsible for deallocating it when it is no longer needed. Such lifetime manipulation
and maintenance of managing dynamically allocated memory is called Ownership.
Ownership has the following features:
• if it is exclusive, then it is possible to transfer it from one scope to another.
• if it is shared, then memory deletion is typically responsibility of the last owner
that releases that ownership.
• if it is temporary , then a non-owning/weak reference has to be converted to
shared ownership before accessing the object.
Since C++11, management of Ownership is done by smart pointer types. Smart
pointers are allocated on stack, which guarantees destructor execution and possible
object deallocation (if that is the last or sole owner) at the end of the scope. Pointer-like
behavior is done by overloading operator-> and operator* methods.
The following standard smart pointer classes are available since C++11:
• std::unique_ptr wraps a pointer to an object in an exclusive way . Such std::
unique_ptr object guarantees that only one pointer to the underlying object exists
at a time, as std::unique_ptr is not copyable. It is movable and such an operation
represents ownership transfer. When the std::unique_ptr instance is goes out of
scope, the underlying pointer is deleted and memory is deallocated.
• std::shared_ptr wraps a pointer to an object in a shared way . Multiple std::
shared_ptr are capable to point at the same object, as std::shared_ptr is copyable
and it contains a reference counting mechanism. When the last std::shared_ptr
instance goes out of scope (and the reference counter drops to 0), the underlying
pointer is deleted and memory is deallocated.
• std::weak_ptr wraps a pointer to an object, but it has to be converted to a std
::shared_ptr in order to access the referenced object. The main purpose of
the std::weak_ptr is to break potential circular references among multiple std
::shared_ptr objects, which would prevent reference counting from dropping to 0
and removing the underlying pointer. If only std::weak_ptr objects exist at a time,
then conversion to std::shared_ptr will return an empty std::shared_ptr.
The main purpose of smart pointers is prevent from possible memory leaks to provide
limited garbage-collection feature:
• with almost no overhead over raw pointers for std::unique_ptr, unless user-
specified deleter is used.
• with possibility of sharing ownership among multiple std::shared_ptr objects.
However, this solution bases purely on the reference-counting and smart pointers
destructors calling and it does not involve independent process that periodically cleans
up memory that is no longer referenced.
Usage of smart pointers makes Ownership matters unambiguous and self-
documenting. It also facilitates memory management issues and eliminates multiple
error types that can be made by developers.
There are also other types of memory managing objects that follow RAII design pattern,
e.g. std::string and std::vector.See MISRA C++ 2008 [7]
6.18.5 Dynamic memory management
The dynamic memory management provides flexible mechanism of allocating and
deallocating blocks of memory during run-time phase of the program. The application
is allowed to acquire as much memory as it needs in its current state, and return it once
the memory is not used.
Moreover, this is a convenient way of extending lifetime of objects outside the functions
where the objects were created. In other words, a function can create objects on
dynamic memory and then exit and the objects that were created in the dynamic
memory are preserved and can be used subsequently by other functions.
The dynamic memory management uses the Operating System routines to
allocate and deallocate memory , what introduces several issues. Therefore, the
AUTOSAR C++14 Coding Guidelines defines specific rules for appropriate usage and
implementation of dynamic memory management.
Challenges arising due to dynamic memory usage
Issue: Solution:
Memory leaks RAII design pattern usage is highly recommended
for managing resource and memory acquisition and
release (A18-5-2). It is prohibited to make calls
to new and delete operators explicitly , to force
programmers to assign each allocated memory
block to manager object which deallocates the
memory automatically on leaving its scope. Also,
the form of delete operator used for memory
deallocation needs to match the form of new
operator used for memory allocation (A18-5-3).
Memory fragmentation Memory allocator used in the project needs to
guarantee that no memory fragmentation occurs
(A18-5-5).
Invalid memory access C-style functions malloc/calloc/realloc must not be
used in the project, so memory block can not be
accessed as it would be of another type. Memory
allocator used in the project needs to guarantee that
objects do not overlap in the physical storage (A18-
5-5).
Erroneous memory allocations The application program needs to define the
maximum amount of dynamic memory it needs,
so running out of memory must not occur during
faultless execution. The memory would be pre-
allocated before run-time phase of the program
(A18-5-5).
Not deterministic execution time of memory
allocation and deallocation
Memory allocator used in the project needs to
guarantee that memory allocation and deallocation
are executed within defined time constraints that
are appropriate for the response time constraints
defined for the real-time system and its programs
(A18-5-7).
Table 6.2: Challenged of dynamic memory usage
Ownership and smart pointers
Memory allocated dynamically requires strict control of objects or functions that are
responsible for deallocating it when it is no longer needed. Such lifetime manipulation
and maintenance of managing dynamically allocated memory is called Ownership.
Ownership has the following features:
• if it is exclusive, then it is possible to transfer it from one scope to another.
• if it is shared, then memory deletion is typically responsibility of the last owner
that releases that ownership.
• if it is temporary , then a non-owning/weak reference has to be converted to
shared ownership before accessing the object.
Since C++11, management of Ownership is done by smart pointer types. Smart
pointers are allocated on stack, which guarantees destructor execution and possible
object deallocation (if that is the last or sole owner) at the end of the scope. Pointer-like
behavior is done by overloading operator-> and operator* methods.
The following standard smart pointer classes are available since C++11:
• std::unique_ptr wraps a pointer to an object in an exclusive way . Such std::
unique_ptr object guarantees that only one pointer to the underlying object exists
at a time, as std::unique_ptr is not copyable. It is movable and such an operation
represents ownership transfer. When the std::unique_ptr instance is goes out of
scope, the underlying pointer is deleted and memory is deallocated.
• std::shared_ptr wraps a pointer to an object in a shared way . Multiple std::
shared_ptr are capable to point at the same object, as std::shared_ptr is copyable
and it contains a reference counting mechanism. When the last std::shared_ptr
instance goes out of scope (and the reference counter drops to 0), the underlying
pointer is deleted and memory is deallocated.
• std::weak_ptr wraps a pointer to an object, but it has to be converted to a std
::shared_ptr in order to access the referenced object. The main purpose of
the std::weak_ptr is to break potential circular references among multiple std
::shared_ptr objects, which would prevent reference counting from dropping to 0
and removing the underlying pointer. If only std::weak_ptr objects exist at a time,
then conversion to std::shared_ptr will return an empty std::shared_ptr.
The main purpose of smart pointers is prevent from possible memory leaks to provide
limited garbage-collection feature:
• with almost no overhead over raw pointers for std::unique_ptr, unless user-
specified deleter is used.
• with possibility of sharing ownership among multiple std::shared_ptr objects.
However, this solution bases purely on the reference-counting and smart pointers
destructors calling and it does not involve independent process that periodically cleans
up memory that is no longer referenced.
Usage of smart pointers makes Ownership matters unambiguous and self-
documenting. It also facilitates memory management issues and eliminates multiple
error types that can be made by developers.
There are also other types of memory managing objects that follow RAII design pattern,
e.g. std::string and std::vector.
M19M19 (MISRA 유래)M19 (MISRA-origin)
M19-3-1Required · Automated✓ compilable
errno 를 직접 사용하지 않는다The error indicator errno shall not be used
❌ 위반 예시Non-compliant example
#include <cerrno>
#include <cstdlib>
#include <iostream>
int main() {
errno = 0;
double v = std::strtod("not-a-number", nullptr); // 실패 시 errno 설정
if (errno != 0) std::cout << "conversion failed via errno\n"; // 전역 errno 의존
else std::cout << "v=" << v << '\n';
}✅ 준수 예시Compliant example
#include <iostream>
#include <optional>
#include <string>
static std::optional<double> parse_double(const std::string& s) {
try { std::size_t pos; double v = std::stod(s, &pos);
return pos == s.size() ? std::optional<double>(v) : std::nullopt; }
catch (...) { return std::nullopt; }
}
int main() {
auto r = parse_double("not-a-number");
std::cout << (r ? "ok" : "conversion failed") << '\n'; // 결과에 오류가 함께 담김
}⚠️ 근거: errno 는 함수가 오류를 알리려고 설정하는 전역(스레드 로컬) 상태라, 오류 발생과 검사 사이가 떨어져 있고 그 사이 다른 호출이 errno 를 덮어쓸 수 있으며 사용 전 0 으로 초기화하는 규약을 사람이 지켜야 한다. 영향: errno 검사를 빠뜨리거나 초기화를 잊으면 오류가 조용히 무시되거나 엉뚱한 호출의 오류로 오인되어, 실패 처리 로직이 신뢰할 수 없게 된다. 대응: 오류를 반환값·예외·std::optional·std::expected 처럼 결과와 함께 명시적으로 전달하는 인터페이스를 사용해, 오류 검사가 호출 지점에 묶이게 한다.Rationale: errno is a global (thread-local) state that functions set to signal errors, so the error and its check are separated, another call in between can overwrite errno, and the convention of zeroing it before use must be upheld by a human. Impact: forgetting to check errno or to reset it lets errors be silently ignored or mistaken for the error of an unrelated call, making failure-handling logic unreliable. Fix: use interfaces that carry the error together with the result explicitly — return values, exceptions, std::optional, or std::expected — so the error check is bound to the call site.
A1A1 (AUTOSAR)A1 (AUTOSAR-original)
A1-1-1Required · Automated✓ compilable📄 공식 예제Official example
All code shall conform to ISO/IEC 14882:2014 - Programming Language C++ and shall not use deprecated features.All code shall conform to ISO/IEC 14882:2014 - Programming Language C++ and shall not use deprecated features.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
//% $Id: A1-1-1.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <stdexcept>
void F(std::int32_t i)
{
std::int32_t* a = nullptr;
// __try // Non-compliant - __try is a part of Visual Studio extension
try // Compliant - try keyword is a part of C++ Language Standard
{
a = new std::int32_t[i];
// ...
}
// __finally // Non-compliant - __finally is a part of Visual Studio
// extension
catch (
std::exception&) // Compliant - C++ Language Standard does not define
// finally block, only try and catch blocks
{
delete[] a;
a = nullptr;
}
}⚠️ The current version of the C++ language is as defined by the ISO International
Standard ISO/IEC 14822:2014(E) "Information technology - Programming languages -
C++".
The C++14 is the improved version of the C++11. It is also “the state of the art” of C++
development that is required by ISO 26262 standard [6].
Any reference in this document to “C++ Language Standard” refers to the ISO/IEC
14822:2014 standard.
Note that all of the deprecated features of C++ Language Standard are defined in
ISO/IEC 14882:2014 - Programming Language C++ Annexes C “Compatibility” and D
“Compatibility features”.
See also:
• MISRA C++ 2008 [7]: 1-0-1 All code shall conform to ISO/IEC 14882:2003 “The
C++ Standard Incorporating Technical Corrigendum 1”
• JSF December 2005 [8]: 4.4.1 All code shall conform to ISO/IEC 14882:2002(E)
standard C++.
• HIC++ v4.0 [9]: 1.1.1 Ensure that code complies with the 2011 ISO C++
Language Standard.
• HIC++ v4.0 [9]: 1.3.4 Do not use deprecated STL library features.The current version of the C++ language is as defined by the ISO International
Standard ISO/IEC 14822:2014(E) "Information technology - Programming languages -
C++".
The C++14 is the improved version of the C++11. It is also “the state of the art” of C++
development that is required by ISO 26262 standard [6].
Any reference in this document to “C++ Language Standard” refers to the ISO/IEC
14822:2014 standard.
Note that all of the deprecated features of C++ Language Standard are defined in
ISO/IEC 14882:2014 - Programming Language C++ Annexes C “Compatibility” and D
“Compatibility features”.
See also:
• MISRA C++ 2008 [7]: 1-0-1 All code shall conform to ISO/IEC 14882:2003 “The
C++ Standard Incorporating Technical Corrigendum 1”
• JSF December 2005 [8]: 4.4.1 All code shall conform to ISO/IEC 14882:2002(E)
standard C++.
• HIC++ v4.0 [9]: 1.1.1 Ensure that code complies with the 2011 ISO C++
Language Standard.
• HIC++ v4.0 [9]: 1.3.4 Do not use deprecated STL library features.
A1-1-2Required · Non-automated✓ compilable📄 공식 예제Official example
A warning level of the compilation process shall be set in compliance with project policies.A warning level of the compilation process shall be set in compliance with project policies.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A1-1-2: A warning level of the compilation process shall be set in compliance with project policies. // No code example provided in the official guideline PDF.
⚠️ If compiler enables the high warning level, then it is able to generate useful warning
messages that point out potential run-time problems during compilation time. The
information can be used to resolve certain errors before they occur at run-time.
Note that it is common practice to turn warnings into errors.
Also, note that enabling the highest compiler warning level may produce numerous
useless messages during compile time. It is important that the valid warning level for
the specific compiler is established in the project.
See also:
• JSF December 2005 [8]: AV Rule 218 Compiler warning levels will be set in
compliance with project policies.If compiler enables the high warning level, then it is able to generate useful warning
messages that point out potential run-time problems during compilation time. The
information can be used to resolve certain errors before they occur at run-time.
Note that it is common practice to turn warnings into errors.
Also, note that enabling the highest compiler warning level may produce numerous
useless messages during compile time. It is important that the valid warning level for
the specific compiler is established in the project.
See also:
• JSF December 2005 [8]: AV Rule 218 Compiler warning levels will be set in
compliance with project policies.
A1-1-3Required · Non-automated✓ compilable📄 공식 예제Official example
An optimization option that disregards strict standard compliance shall not be turned on in the chosen compiler.An optimization option that disregards strict standard compliance shall not be turned on in the chosen compiler.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A1-1-3: An optimization option that disregards strict standard compliance shall not be turned on in the chosen compiler. // No code example provided in the official guideline PDF.
⚠️ Enabling optimizations that disregard compliance with the C++ Language Standard
may create an output program that should strictly comply to the standard no longer
valid.
See also:
• none
6.1.2 Normative referencesEnabling optimizations that disregard compliance with the C++ Language Standard
may create an output program that should strictly comply to the standard no longer
valid.
See also:
• none
6.1.2 Normative references
A1-2-1Required · Non-automated✓ compilable📄 공식 예제Official example
When using a compiler toolchain (including preprocessor, compiler itself, linker, C++ standard libraries) in safety-related software, the tool confidence level (TCL) shall be determined. In case of TCL2 or TCL3, the compiler shall undergo a “Qualification of a software tool”, as per ISO 26262-8.11.4.6 [6].When using a compiler toolchain (including preprocessor, compiler itself, linker, C++ standard libraries) in safety-related software, the tool confidence level (TCL) shall be determined. In case of TCL2 or TCL3, the compiler shall undergo a “Qualification of a software tool”, as per ISO 26262-8.11.4.6 [6].
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// The following mechanisms could help to increase the T ool error Detection (TD) and // thus allowing to reduce the T ool Confidence Level: // 1. Achievement of MC/DC code coverage on generated project assembly code // 2. Diverse implementation of safety requirements at software or even at system level // (e.g. two micro-controllers) // 3. Usage of diverse compilers or compilation options // 4. Diversity at the level of operating system // 5. Extensive testing (e.g. equivalence class testing, boundary value testing), testing // at several levels (e.g. unit testing, integration testing) // Note that in most automotive applications, the compiler is evaluated TCL3 or TCL2. In // case of TCL2 or TCL3, the following are typically performed (by compiler vendor or by // a project), see table 4 in ISO 26262-8: // 1. Evaluation of the tool development process // 2. Validation of the software tool, by performing automatic compiler tests that are // derived from the C++ language specification
⚠️ Vulnerabilities and errors in the compiler toolchain impact the binary that is built.
See also:
• ISO 26262-8 [6]: 11 Confidence in the use of software tools.
6.1.4 Implementation complianceVulnerabilities and errors in the compiler toolchain impact the binary that is built.
See also:
• ISO 26262-8 [6]: 11 Confidence in the use of software tools.
6.1.4 Implementation compliance
A1-4-1Required · Non-automated✓ compilable📄 공식 예제Official example
Code metrics and their valid boundaries shall be defined and code shall comply with defined boundaries of code metrics. --- PAGE 37 ---Code metrics and their valid boundaries shall be defined and code shall comply with defined boundaries of code metrics. --- PAGE 37 ---
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A1-4-1: Code metrics and their valid boundaries shall be defined and code shall comply with defined boundaries of code metrics. --- PAGE 37 --- // No code example provided in the official guideline PDF.
⚠️ Code metrics that concern i.e. project’s structure, function’s complexity and size of a
source code shall be defined at the project level. It is also important to determine valid
boundaries for each metric to define objectives of the measurement.
Source code metrics needs to be measured for the project and comply with defined
boundaries. This gives valuable information whether the source code is complex,
maintainable and efficient.
See also:
• HIC++ v4.0 [9]: 8.3.1 Do not write functions with an excessive McCabe
Cyclomatic Complexity .
• HIC++ v4.0 [9]: 8.3.2 Do not write functions with a high static program path count.
• HIC++ v4.0 [9]: 8.2.2 Do not declare functions with an excessive number of
parameters.Code metrics that concern i.e. project’s structure, function’s complexity and size of a
source code shall be defined at the project level. It is also important to determine valid
boundaries for each metric to define objectives of the measurement.
Source code metrics needs to be measured for the project and comply with defined
boundaries. This gives valuable information whether the source code is complex,
maintainable and efficient.
See also:
• HIC++ v4.0 [9]: 8.3.1 Do not write functions with an excessive McCabe
Cyclomatic Complexity .
• HIC++ v4.0 [9]: 8.3.2 Do not write functions with a high static program path count.
• HIC++ v4.0 [9]: 8.2.2 Do not declare functions with an excessive number of
parameters.
A1-4-3Advisory · Automated✓ compilable📄 공식 예제Official example
All code should compile free of compiler warnings.All code should compile free of compiler warnings.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule A1-4-3: All code should compile free of compiler warnings. // No code example provided in the official guideline PDF.
⚠️ Compiler warnings provide the earliest tool-supported indication of potential problems
in source code. Developers should not ignore compiler warnings.
Note: Compiler warnings should be turned on to a level matching (as far as possible)
the rules in this document, in particular A1-1-1. A possible enforcement of this rule is
to turn compiler warnings into errors.
See also:
• A1-1-1 in section 6.1.1
6.2 Lexical conventions
6.2.3 Character setsCompiler warnings provide the earliest tool-supported indication of potential problems
in source code. Developers should not ignore compiler warnings.
Note: Compiler warnings should be turned on to a level matching (as far as possible)
the rules in this document, in particular A1-1-1. A possible enforcement of this rule is
to turn compiler warnings into errors.
See also:
• A1-1-1 in section 6.1.1
6.2 Lexical conventions
6.2.3 Character sets
M1M1 (MISRA 유래)M1 (MISRA-origin)
M1-0-2Required · Non-automated✓ compilable📄 공식 예제Official example
Multiple compilers shall only be used if they have a common, defined interface.Multiple compilers shall only be used if they have a common, defined interface.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M1-0-2: Multiple compilers shall only be used if they have a common, defined interface. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M11M11 (MISRA 유래)M11 (MISRA-origin)
M11-0-1Required · Automated✓ compilable📄 공식 예제Official example
Member data in non-POD class types shall be private.Member data in non-POD class types shall be private.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M11-0-1: Member data in non-POD class types shall be private. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
See: POD-type, Standard-Layout-Class, Trivially-CopyableSee MISRA C++ 2008 [7]
See: POD-type, Standard-Layout-Class, Trivially-Copyable
M14M14 (MISRA 유래)M14 (MISRA-origin)
M14-5-3Required · Automated✓ compilable📄 공식 예제Official example
A copy assignment operator shall be declared when there is a template assignment operator with a parameter that is a generic parameter.A copy assignment operator shall be declared when there is a template assignment operator with a parameter that is a generic parameter.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M14-5-3: A copy assignment operator shall be declared when there is a template assignment operator with a parameter that is a generic parameter. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.14.6 Name resolutionSee MISRA C++ 2008 [7]
6.14.6 Name resolution
M14-6-1Required · Automated✓ compilable📄 공식 예제Official example
In a class template with a dependent base, any name that may be found in that dependent base shall be referred to using a qualified-id or this->.In a class template with a dependent base, any name that may be found in that dependent base shall be referred to using a qualified-id or this->.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M14-6-1: In a class template with a dependent base, any name that may be found in that dependent base shall be referred to using a qualified-id or this->. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.14.7 Template instantiation and specializationSee MISRA C++ 2008 [7]
6.14.7 Template instantiation and specialization
M2M2 (MISRA 유래)M2 (MISRA-origin)
M2-10-1Required · Automated✓ compilable📄 공식 예제Official example
Different identifiers shall be typographically unambiguous.Different identifiers shall be typographically unambiguous.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M2-10-1: Different identifiers shall be typographically unambiguous. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M2-13-2Required · Automated✓ compilable📄 공식 예제Official example
Octal constants (other than zero) and octal escape sequences (other than “\0” ) shall not be used.Octal constants (other than zero) and octal escape sequences (other than “\0” ) shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M2-13-2: Octal constants (other than zero) and octal escape sequences (other than "\0" ) shall not be used. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M2-13-3Required · Automated✓ compilable📄 공식 예제Official example
A “U” suffix shall be applied to all octal or hexadecimal integer literals of unsigned type.A “U” suffix shall be applied to all octal or hexadecimal integer literals of unsigned type.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M2-13-3: A "U" suffix shall be applied to all octal or hexadecimal integer literals of unsigned type. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M2-13-4Required · Automated✓ compilable📄 공식 예제Official example
Literal suffixes shall be upper case.Literal suffixes shall be upper case.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M2-13-4: Literal suffixes shall be upper case. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M2-7-1Required · Automated✓ compilable📄 공식 예제Official example
The character sequence /* shall not be used within a C-style comment.The character sequence /* shall not be used within a C-style comment.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M2-7-1: The character sequence /* shall not be used within a C-style comment. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M27M27 (MISRA 유래)M27 (MISRA-origin)
M27-0-1Required · Automated✓ compilable📄 공식 예제Official example
The stream input/output library <cstdio> shall not be used.The stream input/output library <cstdio> shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M27-0-1: The stream input/output library <cstdio> shall not be used. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M3M3 (MISRA 유래)M3 (MISRA-origin)
M3-1-2Required · Automated✓ compilable📄 공식 예제Official example
Functions shall not be declared at block scope.Functions shall not be declared at block scope.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-1-2: Functions shall not be declared at block scope. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M3-2-1Required · Automated✓ compilable📄 공식 예제Official example
All declarations of an object or function shall have compatible types.All declarations of an object or function shall have compatible types.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-2-1: All declarations of an object or function shall have compatible types. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M3-2-2Required · Automated✓ compilable📄 공식 예제Official example
The One Definition Rule shall not be violated.The One Definition Rule shall not be violated.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-2-2: The One Definition Rule shall not be violated. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M3-2-3Required · Automated✓ compilable📄 공식 예제Official example
A type, object or function that is used in multiple translation units shall be declared in one and only one file.A type, object or function that is used in multiple translation units shall be declared in one and only one file.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-2-3: A type, object or function that is used in multiple translation units shall be declared in one and only one file. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M3-2-4Required · Automated✓ compilable📄 공식 예제Official example
An identifier with external linkage shall have exactly one definition.An identifier with external linkage shall have exactly one definition.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-2-4: An identifier with external linkage shall have exactly one definition. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.3.3 ScopeSee MISRA C++ 2008 [7]
6.3.3 Scope
M3-3-2Required · Automated✓ compilable📄 공식 예제Official example
If a function has internal linkage then all re-declarations shall include the static storage class specifier.If a function has internal linkage then all re-declarations shall include the static storage class specifier.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-3-2: If a function has internal linkage then all re-declarations shall include the static storage class specifier. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
Note: Static storage duration class specifier is redundant and does not need to be
specified if a function is placed in an unnamed namespace.
6.3.4 Name lookupSee MISRA C++ 2008 [7]
Note: Static storage duration class specifier is redundant and does not need to be
specified if a function is placed in an unnamed namespace.
6.3.4 Name lookup
M3-4-1Required · Automated✓ compilable📄 공식 예제Official example
An identifier declared to be an object or type shall be defined in a block that minimizes its visibility.An identifier declared to be an object or type shall be defined in a block that minimizes its visibility.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-4-1: An identifier declared to be an object or type shall be defined in a block that minimizes its visibility. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
See also:
• C++ Core Guidelines [11]: ES.21: Don’t introduce a variable (or constant) before
you need to use it.
6.3.8 Object lifetimeSee MISRA C++ 2008 [7]
See also:
• C++ Core Guidelines [11]: ES.21: Don’t introduce a variable (or constant) before
you need to use it.
6.3.8 Object lifetime
M3-9-1Required · Automated✓ compilable📄 공식 예제Official example
The types used for an object, a function return type, or a function parameter shall be token-for-token identical in all declarations and re-declarations.The types used for an object, a function return type, or a function parameter shall be token-for-token identical in all declarations and re-declarations.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-9-1: The types used for an object, a function return type, or a function parameter shall be token-for-token identical in all declarations and re-declarations. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M3-9-3Required · Automated✓ compilable📄 공식 예제Official example
The underlying bit representations of floating-point values shall not be used.The underlying bit representations of floating-point values shall not be used.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M3-9-3: The underlying bit representations of floating-point values shall not be used. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.4 Standard conversions
6.4.5 Integral promotionsSee MISRA C++ 2008 [7]
6.4 Standard conversions
6.4.5 Integral promotions
M4M4 (MISRA 유래)M4 (MISRA-origin)
M4-10-1Required · Automated✓ compilable📄 공식 예제Official example
NULL shall not be used as an integer value.NULL shall not be used as an integer value.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M4-10-1: NULL shall not be used as an integer value. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M4-10-2Required · Automated✓ compilable📄 공식 예제Official example
Literal zero (0) shall not be used as the null-pointer-constant.Literal zero (0) shall not be used as the null-pointer-constant.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M4-10-2: Literal zero (0) shall not be used as the null-pointer-constant. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.5 Expressions
6.5.0 GeneralSee MISRA C++ 2008 [7]
6.5 Expressions
6.5.0 General
M4-5-1Required · Automated✓ compilable📄 공식 예제Official example
Expressions with type bool shall not be used as operands to built-in operators other than the assignment operator =, the logical operators --- PAGE 69 --- &&, ||, ! , the equality operators == and ! =, the unary & operator, and the conditional operator.Expressions with type bool shall not be used as operands to built-in operators other than the assignment operator =, the logical operators --- PAGE 69 --- &&, ||, ! , the equality operators == and ! =, the unary & operator, and the conditional operator.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M4-5-1: Expressions with type bool shall not be used as operands to built-in operators other than the assignment operator =, the logical operators --- PAGE 69 --- &&, ||, ! , the equality operators == and ! =, the unary & operator, and the conditional operator. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]See MISRA C++ 2008 [7]
M4-5-3Required · Automated✓ compilable📄 공식 예제Official example
Expressions with type (plain) char and wchar_t shall not be used as operands to built-in operators other than the assignment operator =, the equality operators == and ! =, and the unary & operator.Expressions with type (plain) char and wchar_t shall not be used as operands to built-in operators other than the assignment operator =, the equality operators == and ! =, and the unary & operator.
📄 공식 예제 — // Non-compliant 위반 · // Compliant 준수 라인Official example — // Non-compliant vs // Compliant lines
// Rule M4-5-3: Expressions with type (plain) char and wchar_t shall not be used as operands to built-in operators other than the assignment operator =, the equality operators == and ! =, and the unary & operator. // No code example provided in the official guideline PDF.
⚠️ See MISRA C++ 2008 [7]
6.4.7 Integral conversionSee MISRA C++ 2008 [7]
6.4.7 Integral conversion
MISRA C:2012 156 · MISRA C++:2023 179 · CERT C 303 · CERT C++ 83 · AUTOSAR C++14 396 | 대표 규칙rules 1117 · 사내 교육용. MISRA C:2012 / MISRA C++:2023의 매칭 가능한 예제 코드는 로컬 PDF에서 추출해 반영했고, 나머지 표준·미매칭 룰은 기존 교육용 예제를 유지합니다.Internal training. Matched MISRA C:2012 / MISRA C++:2023 examples are extracted from the local PDFs; other standards and unmatched rules keep the existing training examples.