1. Rule 0-1-3 (Required) A Project shall not contain unused variables.
/ 사용하지 않는 변수를 코드에 남기지 말 것.
Example
Extern void usefn (int16_t a, int16_t b );
class C
{ … };
C c; // Non-compliant – unused
void withunusedvar ( )
{
int16_tunusedvar; // Non-compliant –unused
structs_tag
{
signed int a : 3;
signedint pad : 1; // Non-compliant – should be unnamed
signedint : 4; // Compliant, 비트필드에 이름없는 변수는 값을 쓰지 않아도 됨
signed int b : 2;
}s_var;
s_var.a= 0;
s_var.b= 0;
usefn( s_var.a, s_var.b );
}
2. Rule 0-1-4 (Required) A project shall not contain non-volatile POD variables having only one use.
/ volatile[1] 이 아닌 POD 변수[2] 는 한번만 쓰기 위해 사용하지 말 것.
Example
const int16_t x = 19; // Compliant, 선언 및 초기화, once_2 대입에 쓰임
const int16_t y = 21; // Non-compliant, 선언 및 초기화 후 쓰이지 않음
void usedonlyonce ( void )
{
int16_t once_1 = 42; // Non-compliant, 선언 및 초기화 후 쓰이지 않음
int16_t once_2;
once_2= x; // Non-compliant, 선언 및 초기화 후 쓰이지 않음
}
3. Rule 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.
/ 함수 반환값이 void 형이 아니면 반환값을 사용해야 함.
Exception
The return value of afunction may be discarded by use of a (void) cast.
/ 함수의 반환값에 (void) 를 붙이면 예외 인정
Example
uint16_t func ( uint16_t para1 )
{
return para1;
}
void discarded ( uint16_t para2 )
{
func ( para2 ); // Non-compliant, 반환값 사용안함
( void ) func ( para2 ); // Compliant by exception
}
4. Rule 0-1-8 (Required) All functions with void return type shall have external side effect(s)
/ 반환형이 void 형인 함수는 부가효과가 있어야 한다.
The following are examples of external side effects. / 부가효과의 예시.
- Reading or writing to a file, steam, etc. / 파일이나 스트림을 읽거나 쓰는 것 등.
- Changing the value of a non local variable. / 지역변수가 아닌 변수의 값을 바꿈.
- Changing the value of an argument having reference type. / 레퍼런스형 매개변수의 값을 바꿈
- Using a volatile object. / volatile 형 객체 사용.
- Raising an exception. / 예외 발생시키기.
Example
void pointless ( void ) // Non-compliant, no external side effects
{
int16_tlocal;
local = 0;
}
5. Rule 0-4-2 (Document) Use of floating-point arithmetic shall be documented
/ 부동소수점 연산은 문서화 되어야 한다.[3]
6. Rule 2-7-1 (Required) The character sequence /* shall not be used with in a C-style comment.
/ C스타일 주석에서 /* 문자를쓰면 안됨.
Example
/* Hello World /* !!! */ // Non-complaint, C스타일 주석안에 /* 포함
7. Rule 2-7-2 (Required) Sections of code shall not be “commented out” using C-style comments.
/ C스타일 주석에 소스코드를 포함하면 안됨.
Example
/* int32_t i = 0; */ // Non-complaint, C스타일 주석안에 소스코드 포함
8. Rule 2-13-4 (Required) Literal suffixes shall be upper case. / 리터럴 접미사는 대문자로.
Example
uint32_t i = 36u; // Non-complaint, 소문자 u 사용
i = 36U ; // Complaint
9. Rule 5-0-13 (Required) The condition of an if-statement and the condition of an iteration-statement shall have typebool.
/ if문과 반복문의 조건에는 bool 형이 와야 한다.
Example
int32_t x = 0;
if ( x ) // Non-complaint, 조건문의 조건이 bool 형이 아님
{ … }
if ( x == 0 ) // Complaint
{ … }
10. Rule 5-2-4 (Required) C-style casts (otherthan void casts) and functional notation casts (other than explicit constructor calls) shall not be used.
/ void 캐스팅을 제외한 C 스타일 캐스트와 명시적인 생성자 호출을 제외한 functional cast 는 사용하면 안됨
Example
int32_t i = 0;
int8_t b = 1;
( void ) function ( ); / / Complaint
i = ( int32_t ) b; // Non-complaint, C-style cast
i = static_cast( b ); // Complaint
class C
{
C ( int32_t i )
{ ... }
}
C c(10); // Complaint
int (b); // Non-complaint, functionalnotation cast;
11. Rule 5-2-5 (Required) A cast shall not remove any const or volatile qualification from the type of a pointer or reference.
/ 캐스팅 할 때 포인터나 레퍼런스형의 const, volatile 속성을 없애면 안됨.
Example
const int8_t * chArr =“Hello”;
int8_t * chArr2 =const_cast( chArr ); // Non-complaint, const 속성 제거
12. Rule 5-2-12 (Required) An identifier with array type passed as a function argument shall not decay to a pointer.
/ 배열이 함수 매개변수로 전달될 때 포인터처럼 쓰이면 안됨.
Example
int8_t chArr[10];
void function( int8_t * data );
function( chArr ); // Non-complaint, 배열 범위를 표시하지 않는 전달방식
function( &chArr[10] ); // Complaint
13. Rule 5-3-1 (Required) Each operand of the ! operator, the logical && or the logical || operators shall have type bool.
/ !연산자는 bool 타입 결과에만 사용할 수 있음.
Example
if ( !0 ) // Non-complaint, 정수형 상수 0 에 !연산자 사용
{ … }
int32_t x = 10;
if( !( x > 5 ) ) // Complaint
{ … }
14. Rule 6-2-2 (Required) Floating-point expressions shall not be directly or indirectly tested for equality or inequality.
/ 부동소수점 변수끼리동일한지 비교하지 말 것.
Example
float_t x = 5;
float_t y = 5;
if( x == y ) // Non-complaint, 부동소수점 변수끼리 비교
{ … }
if( abs( x – y ) < FLT_EPSILON[4] ) // Complaint
{ … }
15. Rule 6-3-1 (Required) The statement forming the body of a switch, while, do-while or for statement shall be a compound statement.
/ 반복문, 조건문 뒤에 1 줄짜리 코드라도 중괄호 쓸 것.
Example
if( x > 5 )
y = 10; // Non-complaint, 괄호 안넣음
if( x > 5 )
{
y = 10; // Complaint
}
16. Rule 6-4-2 (Required) All if-else constructs shall be terminated with an else clause.
/ 조건문에서 if else 까지 사용했으면 마지막은 else 로 끝나야 함
Example
if( x > 5 )
{ … }
else if ( x < 0 ) // Non-complaint, if-else 썼는데 else 문을 빠뜨림
{ … }
-------------------------------------------------------------------------------------------
if( x > 5 )
{ … }
else if ( x < 0 )
{ … }
else // Complaint
{ … }
17. Rule 6-4-6 (Required) The final clause of a switch statement shall be the default-clause.
/ switch문 마지막은 default 절로 끝낼 것.
Example
switch ( x )
{
case1:
break; // 마지막이 default 절로 끝나지 않음
}
-------------------------------------------------------------------------------------------
switch ( x )
{
case 1:
break;
default: // Complaint
break;
}
18. Rule 6-6-4 (Required) For any iteration statement there shall be no more than one break or goto statement used for loop termination.
/ 반복문에서 탈출하기 위해 break 나 goto 는 하나만 쓸 것.
Example
while ( … )
{
if( … )
{
break;
}
if( … )
{
break; // Non-compliant, 반복문 안에 두번째 break
}
}
19. Rule 6-6-5 (Required) A function shall have a single point of exit at the end of the function.
/ 함수에서 return 은 한번만 할 것. try-catch 는 예외.
Example
void function ( … )
{
if( … )
{
return; // Non-compliant, return문은 함수당 하나만
}
return;
}
void function2 ( … ) try
{
return;
}
catch ( … )
{
return; // Compliant by exception
}
20. Rule 7-1-1 (Required) A variable which is not modified shall be const qualified.
/ 변경되지 않는 변수는 const 로 선언할 것
Example
int32_t function ( int32_t* p1, // Non-compliant, p1값이 변경되지 않음
int32_t * const p2 ) // Compliant
{
*p1 = 10;
*p2 = 10;
int32_t i = 0; // Non-compliant, 초기화 이후 값이 변경되지 않음
return i;
}
21. Rule 7-3-1 (Required) The global namespace shall only contain main, namespace declarations and extern “C”declarations.
/ 메인함수, 네임스페이스 선언, extern “C”선언만 전역으로 쓸 수 있음
Example
void func1 ( int32_t p1 ); // Non-compliant
int32_t x1; // Non-compliant
namespace MY_API
{
voidfunc2 ( int32_t p2 ); // Compliant
int32_tx2; // Compliant
}
22. Rule 7-3-4 (Required) using-directives shall not be used.
/ using namespace 키워드 쓰지 말 것.
Example
using namespace std; // Non-compliant
using std::cout; // Compliant
cout << “Hello World”;
23. Rule 8-0-1 (Required) An init-declarator or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively.
/ 변수 선언시에 자료형 하나에 변수 하나만 선언할 것.
Example
int32_t var1, var2; // Non-compliant, 자료형 하나에 변수 2 개선언
int32_t var1; // Compliant
int32_t var2; // Compliant
24. Rule 8-4-2 (Required) The identifiers used for the parameters in a redeclaration of a function shall be identical to those in the declaration.
/ 변수 선언과 정의시에 매개변수 이름이 동일할 것.
Exception
It is not a violation of this rule if the declaration or re-declaration contains an unnamed parameter.
/파라미터 이름이 없는 경우에는 예외.
Example
void fn1 ( int32_t a );
void fn2 ( int32_t b );
void fn3 ( int32_t );
void fn1 ( int32_t a1 ) // Non-compliant, 선언과 정의시에 매개변수 이름이 다름
{ … }
void fn2 ( int32_t b ) // Compliant
{ … }
void fn3 ( int32_t c ) // Compliant by exception
{ … }
25. Rule 9-3-1 (Required) const member functions shall not return non-const pointers or references to class-data.
/ const멤버함수[5] 는 클래스의 non-const pointer 나 레퍼런스를 반환해서는 안됨.
Example
class CMyClass
{
public:
MyClass( ) : a( new int32_t[10], b( c ), c( 10 ) { }
int32_t* GetA ( ) const // Non-compliant, const 멤버함수가 non const pointer 반환
{return a; }
int32_t * GetB ( ) const // Non-compliant, const 멤버함수가 non const pointer 반환
{ return &b; }
const int32_t* GetB2 ( ) const // Compliant
{ return &b; }
private:
int32_t * a;
int32_t & b;
int32_t c;
};
main()
{
CMyClass myClass;
myClass.GetA()[0] = 10; // private 멤버 a 의 값을 외부에서 직접 수정 가능한 문제
*myClass.GetB() = 20; // private 멤버 b 의 값을 외부에서 직접 수정 가능한 문제
*myClass.GetB2() = 30; // compile error, private 멤버 b 의 값을 외부에서 변경불가
}
26. Rule 9-3-2 (Required) Member functions shall not return non-const handles to class-data.
/ 멤버함수는 클래스 데이터의 non-const 핸들을 반환하면 안됨.
Example
class CMyClass
{
public:
int32_t& GetA ( ) // Non-compliant
{ return a; }
private:
int32_t a;
}
main()
{
CMyClass myClass;
int32_t & a_ref = myClass.GetA();
a_ref = 10; // private 멤버 a 의 값을 외부에서 직접 수정 가능한 문제
}
-------------------------------------------------------------------------------------------
class C
{
public:
C ( int32_t* shared ) : m_shared ( shared ) { }
int32_t * GetA ( )
{ return m_shared; } // Compliant– m_shared is not class-data[6]
private:
int32_t* m_shared;
};
27. Rule 9-3-3 (Required) 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.
/ 멤버함수는 static 멤버함수가 가능하면 static 멤버함수로, const 멤버함수가 가능하면 const 멤버함수로 바꾸어야 한다.
Example
class A
{
public:
int16_tf1 ( ) // Non-compliant – can be const
{ return m_i; }
int16_tf2 ( ) // Non-compliant – can be static
{ return m_s; }
int16_tf3 ( ) // Compliant – cannot be const or static[7]
{ return ++m_i; }
private:
int16_t m_i;
static int16_t m_s;
};
28. Rule 16-0-1 (Required) #include directives in a file shall only be preceded by other preprocessor directives or comments.
/ #include 는 파일상단에 위치할 것
Example
#include // Compliant
int32_t i;
#include // Non-compliant, #include 하기 전에 변수 선언함
29. Rule 16-0-2 (Required) Macros shall only be #define ’d or #undef ’d in the global namespace.
/ #define , #undef 매크로는 전역 네임스페이스에 선언할 것.
Example
#ifndef MY_HDR
#define MY_HDR // Compliant
namespace NS
{
#defineFOO // Non-compliant
#undefFOO // Non-compliant
}
#endif
30. Rule 16-0-4 (Required) Function-like macros shall not be defined.
/ 매크로함수는 사용하지 말 것.
Example
#define FUNC_MACRO (X) ( (X) + (X) ) // Non-compliant, 매크로함수 정의
31. Rule 16-2-2 (Required) C++ macros shall only be used for include guards, type qualifiers, or storage class specifiers.
/ C++ 매크로는 include guards 에만 쓸 것.
Example
#define PLUS2 (X) ( (X) +2 ) // Non-compliant, 매크로함수
#define PI 3.14159F // Non-compliant, use constinstead
#define int32_t long // Non-compliant, use typedef instead
32. Rule 16-6-1 (Document) All uses of the #pragma directive shall be documented.
/ #pragma 사용시 문서화 할 것.
33. Rule 18-4-1 (Required) Dynamic heap memory allocation shall not be used.
/ 메모리 동적할당 하지 말 것.[8]
Example
int32_t * i = new int32_t[10]; // Non-compliant, new 사용
[1] 메모리 최적화를 방지하는 키워드, 잘 쓰이지 않음. 궁금하면 구글링하세요.
[2] Plain Old Data structure: 객체지향 프로그래밍의 오브젝트가 아닌 레코드, ex) 기본자료형, 구조체
[3] 왜 부동소수점 연산이 필요한 지. 어떻게 적절하게 처리되는 지.
[4] FLT_EPSILON은 0.0000001192, double_t 비교를하려면 DBL_EPSILON 도 있음.
[5] 클래스의 멤버함수 뒤에 const 가 붙는 함수
[6] m_shared의 값은 다른 곳에서 메모리를 생성하여 값을 저장하고 있는 메모리의 주소이기 때문에 class data가 아님. 본래부터 내 것이 아니란 말.
[7] m_i는 static 변수가 아니기 때문에 static 멤버함수가 될 수 없고, m_i 의 값을 변경하고 있기 때문에const 멤버함수도 될 수 없다.
[8] MFC 자동생성코드는 정적분석툴에서 false alarm 등록.