2.1 Code Refine 과정
SWUD에서 Code Reverse 기능을 사용하기 전에 반드시 Code Refine하는 과정이 필요하다. Compile이 정상적으로 진행되었어도 설계에 맞지 않는 문법이나 AUTOSAR 표준 타입을 참조하지 않는 경우 수정 작업을 진행 후 Code Reverse 기능을 사용해야한다.
MISRA rule을 적용한 코드를 Code Reverse 기능을 사용한다.
1. AUTOSAR 표준 타입
AUTOSAR_DatatTypes에 정의되어 있는 ImplementationDataTypes를 사용하도록 수정한다.
bool -> boolean unsigned char -> uint8 unsigned int -> uint16 또는 uint32 char -> sint8 int -> sint16 또는 sint32 float -> float32 double -> float64 ...
2. MISRA C:2012 rule
기존 Legacy 코드를 MISRA rule이 적용된 코드로 수정해서 Code Reverse를 진행한다.
1. A standard C environment
Rule 1.1
The program shall contain no violationsof the standard C syntax and
constraints, and shall not exceed the implementation’s tr anslation
limits
프로그램은 C 표준 문법과 제약 조건을 위반해서는 안 되며, 구현체의 변환 한계를 초과해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
세미콜론(;)이나 중활호 쌍({}) 누락 – 이는 표준 C 문법 위반이며 컴파일 에러를 발생시킴
너무 많은 매크로나 중첩된 include 사용으로 번역 유닛이 구현체의 한계를 초과할 수 있음
Rule 1.2
Language extensions should not be used
언어 확장은 사용하지 않아야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Advisory | Undecidable, Single Translation Unit | C90, C99 |
컴파일러 고유 확장 기능(예: GCC의 \\_attribure\\_, typeof)은 다른 구현체에서 호환되지 않음.
표준 외 기능은 사용하지 않아야 하나 불가피하게 사용할 경우 주석이나 문서에 명시하고 제한적으로 관리
Rule 1.3
There shall be no occurrence of undefi ned or critical unspecifi ed
behaviour
정의되지 않았거나 치명적으로 미정의된 동작이 발생해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Undecidable, System | C90, C99 |
Undefined Behavior 예 : 0으로 나누기, 잘못된 포인터 역참조, 초기화되지 않은 변수 사용, 배열 범위 초과 접근
Unspecified Behaivor 예 : 동일한 객체에 대해 순서가 정의되지 않은 연산 (i = i++;)
2. Unused code
Rule 2.1
A project shall not contain unreachable code
프로젝트에 도달할 수 없는 코드가 존재해서는 안된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Undecidable, System | C90, C99 |
return, break, exit() 뒤에 오는 문장은 절대 실행되지 않으므로 제거해야 함
주석 처리된 디버깅 코드나 임시 테스트 코드를 그대로 남겨두는 것도 이 Rule에 위배 될 수 있음코드 복잡도 증가 및 유지보수 혼란의 원인
Rule 2.2
There shall be no dead code
죽은 코드는 존재해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Undecidable, System | C90, C99 |
실행될 가능성이 전혀 없는 코드를 의미 (예 : 조건문이 항상 참 또는 거짓으로 특정 블록이 절대 실행되지 않는 경우 등)
프로젝트 내 로직의 명확성을 위해 반드시 제거되어야 함
Rule 2.3
A project shall not contain unused type declarations
사용되지 않는 형 선언이 존재해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
정의되었지만 코드 어디에서도 사용되지 않는 구조체, 열거형, typedef 등이 해당
이는 불필요한 복잡성을 증가시키고 유지보수성을 저해
Rule 2.4
A project should not contain unused tag declarations
사용되지 않는 태그 선언은 존재하지 않아야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Advisory | Decidable, System | C90, C99 |
예:
struct또는union의 태그 이름만 선언하고 실제 정의나 사용이 없는 경우.
이는 코드의 불명확성을 초래할 수 있으므로 제거가 권장된다.
3. Comments
Rule 3.1
*The character sequences / and // shall not be used within a comment**
주석 내부에서/*또는//문자열을 사용해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
주석 내부에 주석 구문이 들어가면 닫히지 않는 주석 오류를 유발
이로 인해 코드가 의도치 않게 비활성화될 위험이 있음
Rule 3.2
Line-splicing shall not be used in // comments
//형식의 주석에서는 줄 연결(line-splicing)을 사용해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C99 |
백슬래시(
\\)를 이용해 줄을 이어 붙이면 주석 범위가 예기치 않게 확장될 수 있음
코드 가독성 저하 및 유지보수 시 혼동을 초래할 수 있음
4. Character Sets and Identifiers
Rule 4.1
Octal constants shall not be used
8진 상수는 사용해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
8진수 리터럴(
0123)은 혼동을 일으키기 쉬우며, 특히 숫자 앞의0이 의미를 바꾸는 문제를 야기할 수 있음
명시적 10진수 또는 16진수 표기를 사용하는 것이 안전
Rule 4.2
Trigraphs shall not be used
트라이그래프(trigraph) 시퀀스는 사용하지 않아야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
트라이그래프(
??=등)는 특정 환경에서만 인식되며 가독성을 해침
현대 컴파일러에서는 대부분 지원되지 않으므로 사용하지 않음
Rule 4.3
Identifiers in the same name space shall be distinct
같은 네임스페이스 내 식별자는 서로 달라야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
같은 스코프 또는 동일한 의미 영역에서 동일한 이름을 사용하면 혼동을 초래
예를 들어 전역 변수명과 함수명이 같을 경우 가독성과 유지보수성이 떨어짐
Rule 4.4
Identifiers shall be distinct from macros.
식별자는 매크로 이름과 동일해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
함수나 변수명이 매크로 이름과 같을 경우, 전처리기 단계에서 예기치 않은 치환이 발생할 수 있음
Rule 4.5
Identifiers shall be distinct from keywords
식별자는 C 언어의 키워드와 동일해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
예를 들어 변수명을
int,switch,static등으로 선언하면 문법 오류를 일으킴
예약어와 구분되는 명확한 명명 규칙을 유지해야 함
Rule 4.6
Typedef names shall be distinct from macros
typedef로 정의된 이름은 매크로 이름과 같지 않아야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
전처리 매크로와 typedef가 동일한 이름을 가질 경우, 컴파일 시 의미가 모호해진다.
Rule 4.7
If identifiers differ only by the use of underscores, then the identifiers shall not be used in the same scope
식별자가 밑줄(_)의 유무로만 구분되는 경우 동일 스코프 내에서 사용해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
data와_data같은 이름을 같은 범위에서 사용하면 혼동을 초래
코드 리뷰 시 오류 가능성을 줄이기 위해 명확히 구분해야 함
Rule 4.8
If identifiers differ only by the use of case, then the identifiers shall not be used in the same scope
식별자가 대소문자만 다른 경우 동일 스코프에서 사용해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
Data와data를 같은 함수 내에서 사용하면 오탈자나 혼동을 유발할 수 있음
MISRA는 대소문자를 구분하지만, 코딩 가이드 차원에서는 혼용을 금지
Rule 4.9
A function shall be used in preference to a function-like macro
함수형 매크로보다는 실제 함수를 우선적으로 사용해야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Advisory | Undecidable, Single Translation Unit | C90, C99 |
매크로는 타입 검사가 불가능하며, 부작용(side-effect)을 초래할 수 있음
함수는 타입 안정성과 디버깅 용이성을 제공
Rule 4.10
In the definition of a function-like macro, each instance of a parameter shall be enclosed in parentheses
함수형 매크로 정의 시, 매개변수의 각 사용은 괄호로 감싸야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
괄호가 누락되면 연산자 우선순위로 인한 예기치 않은 결과가 발생할 수 있음 (예:
#define SQUARE(x) x*x→SQUARE(1+2)=1+2*1+2)
Rule 4.11
All macro identifiers in preprocessor directives shall be defined before use
전처리 지시문에서 사용되는 모든 매크로 식별자는 사용 전에 정의되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
#if등 조건문에서 정의되지 않은 매크로를 참조하면, 컴파일러마다 결과가 달라질 수 있음
Rule 4.12
Preprocessing directives shall be syntactically correct
전처리 지시문은 문법적으로 올바르게 작성되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
#ifdef,#endif쌍 불일치, 오타, 미닫힘 누락 등이 대표적인 위반 사례
전처리 오류는 컴파일 전 단계에서 프로그램을 깨뜨릴 수 있음
Rule 4.13
Only preprocessor directives and comments shall occur before the first
#includedirective in a file
파일 내 첫 번째#include지시문 이전에는 전처리 지시문과 주석만 존재해야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
코드나 선언이 include 이전에 존재하면 헤더 의존성이 깨질 수 있음
주석이나 매크로 정의 외의 내용은 포함하지 않아야 함
Rule 4.14
The
#includedirective shall be followed by either a filename in double quotes or angle brackets#include지시문은 큰따옴표(“”) 또는 꺾쇠괄호(<>)로 감싼 파일명을 따라야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
C 표준에서 허용된 include 형식 외의 파일 지정 방식은 비표준이며, 이식성을 저하시킴
5. Identifiers and Scope
Rule 5.1
External identifiers shall be distinct
외부 식별자는 서로 달라야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
모든 외부 링크 식별자는 프로그램 전체에서 고유해야 함
서로 다른 파일에서 동일한 함수명이나 전역 변수명을 사용하면 링커 단계에서 충돌이 발생할 수 있음
Rule 5.2
Identifiers declared in more than one scope shall be distinct
둘 이상의 스코프에 선언된 식별자는 서로 달라야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
같은 이름을 다른 범위에서 재선언하면, 코드 가독성이 떨어지고 버그를 유발함
특히 전역 변수와 지역 변수가 동일한 이름일 경우 혼동을 초래함
Rule 5.3
📖 An identifier shall be declared at block scope if its identifier is only accessed within a single function
식별자가 하나의 함수 내에서만 사용된다면, 반드시 블록 스코프(지역 변수)로 선언되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
불필요한 전역 변수 사용은 코드 의존성을 증가시킨다.
해당 함수에서만 사용하는 데이터는 지역 변수로 제한하는 것이 원칙이다.
Rule 5.4
📖 A macro identifier shall be distinct from identifiers declared in the same scope
매크로 식별자는 같은 스코프 내의 다른 식별자와 달라야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
매크로 이름과 변수 이름이 같으면 전처리 과정에서 예기치 않은 치환이 일어날 수 있다.
Rule 5.5
📖 Identifiers shall be distinct from typedef names
식별자는 typedef 이름과 동일하지 않아야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
typedef로 정의된 타입 이름과 변수명이 같을 경우 의미가 혼동될 수 있다.
6. Constants
Rule 6.1
📖 The plain char type shall be used only for the storage and use of character values
char 타입은 문자 값을 저장하거나 사용하는 경우에만 사용해야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
char는 부호가 구현체마다 다르기 때문에, 정수 데이터 저장 용도로 사용하면 부호 확장 문제를 일으킬 수 있다.
Rule 6.2
📖 Signed and unsigned types shall not be mixed in arithmetic expressions without an explicit cast
명시적 형 변환 없이 부호 있는 정수형과 부호 없는 정수형을 혼합해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
int와 unsigned int를 혼용할 경우, 암묵적 형변환으로 인해 비교나 계산 결과가 달라질 수 있다.
Rule 6.3
📖 Bit-fields shall only be defined to be of type unsigned int or signed int
비트필드는 unsigned int 또는 signed int 타입으로만 정의되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
다른 타입으로 정의할 경우, 구현체마다 메모리 정렬 방식이 달라져 이식성이 떨어진다.
Rule 6.4
📖 Bit-fields of signed type shall use the same type for all members of the same structure
signed 비트필드 멤버는 같은 구조체 내에서 동일한 타입을 사용해야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
같은 구조체 안에서 서로 다른 signed 타입의 비트필드를 혼합하면, 구현체마다 부호 확장 방식이 달라질 수 있다.
7. Literals
Rule 7.1
📖 Octal constants and escape sequences (other than \\0) shall not be used
8진수 상수나 \\0을 제외한 8진수 이스케이프 시퀀스는 사용하지 않아야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
0123 또는 '\\033' 형태는 혼동을 초래하기 쉽다.
명시적으로 10진수 또는 16진수로 표기하는 것이 권장된다.
Rule 7.2
📖 A “u” or “U” suffix shall be applied to all constants of unsigned type
부호 없는 상수에는 반드시 u 또는 U 접미사를 붙여야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
0xFFu처럼 명시적으로 unsigned임을 표시해야 암묵적 형변환 문제를 방지할 수 있다.
Rule 7.3
📖 The lowercase character “l” shall not be used in a literal suffix
소문자 l은 리터럴 접미사로 사용해서는 안 된다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C90, C99 |
💡 설명
1l은 11처럼 보이기 쉬우므로 혼동을 피하기 위해 대문자 L을 사용해야 한다 (1L).
8. Declarations and Definitions
Rule 8.1
📖 Functions shall have prototype declarations and definitions
모든 함수는 프로토타입 선언과 정의를 가져야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
함수를 선언 없이 호출하면 암묵적 반환 타입이 int로 간주되어 문제를 유발할 수 있다.
모든 함수는 명시적 선언이 필요하다.
Rule 8.2
📖 Whenever an object or function is declared, its type shall be explicitly stated
객체나 함수가 선언될 때, 반드시 명시적 타입이 선언되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
암묵적 형 추론은 허용되지 않는다.
모든 변수와 함수의 타입을 명시해야 코드 명확성이 보장된다.
Rule 8.3
📖 All declarations of an object or function shall use the same type qualifiers
같은 객체나 함수의 모든 선언은 동일한 타입 한정자를 사용해야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
예: 한 파일에서는 extern const int x;, 다른 파일에서는 extern int x; 로 선언하는 것은 위반이다.
Rule 8.4
📖 An external object or function shall be declared once in one header file
외부 객체나 함수는 한 헤더 파일에서 한 번만 선언되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
중복 선언은 링커 에러와 유지보수 혼란을 야기한다.
모든 외부 선언은 공용 헤더로 일원화해야 한다.
Rule 8.5
📖 An external object or function shall be declared in one and only one file
외부 객체나 함수는 단 하나의 소스 파일에서만 정의되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
중복 정의는 링커 단계에서 충돌을 일으킨다.
공용 헤더에 선언하고, 실제 정의는 한 곳에만 존재해야 한다.
Rule 8.6
📖 An identifier with external linkage shall have exactly one definition
외부 연결성을 가진 식별자는 단 하나의 정의만 가져야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
전역 변수를 여러 파일에서 중복 정의하면 링커 오류가 발생한다.
Rule 8.7
📖 Objects shall be defined at block scope if they are only accessed within a single function
하나의 함수에서만 접근되는 객체는 블록 스코프(지역 변수)로 정의해야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
불필요한 전역 변수는 피해야 하며, 지역 스코프 내에서 관리해야 한다.
Rule 8.8
📖 An external object or function shall be declared before use
외부 객체나 함수는 사용 전에 반드시 선언되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
선언되지 않은 함수나 변수를 참조하면 컴파일러가 암묵적 타입으로 추론하거나 오류를 낼 수 있다.
Rule 8.9
📖 An identifier with internal linkage shall be declared static
내부 연결성을 가지는 식별자는 static으로 선언되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
파일 내에서만 사용하는 함수나 변수는 static으로 제한하여 외부에서 접근 불가능하도록 해야 한다.
Rule 8.10
📖 An inline function shall be declared static
인라인 함수는 반드시 static으로 선언되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, Single Translation Unit | C99 |
💡 설명
inline 함수가 외부 링크를 가지면 여러 번 정의될 위험이 있다.
이를 방지하기 위해 내부 링크로 한정한다.
Rule 8.11
📖 When an array is declared with external linkage, its size shall be stated explicitly
외부 연결성을 가진 배열은 반드시 명시적으로 크기를 지정해야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
명시적 크기가 없으면 다른 파일에서 잘못된 접근이 발생할 수 있다.
Rule 8.12
📖 When an object is declared, its type shall be explicitly stated
객체가 선언될 때 그 타입은 명시적으로 선언되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
암묵적인 자료형 지정은 허용되지 않는다.
MISRA는 모든 선언의 타입 명시를 의무화한다.
Rule 8.13
📖 An object shall be defined at block scope if its identifier appears in only one function
식별자가 단 하나의 함수에서만 사용된다면 해당 객체는 블록 스코프에서 정의되어야 한다.
| Category | Analysis | Applies to |
|---|---|---|
| Required | Decidable, System | C90, C99 |
💡 설명
로컬하게만 쓰이는 변수를 전역으로 선언하면 불필요한 의존성을 유발한다.
