• [MFC] c++ 신뢰성시험에서 자주 위반하는 룰 모음 (MISRA c++ 2008 기반)2022.10.27 PM 05:26

게시물 주소 FONT글자 작게하기 글자 키우기

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 등록.

댓글 : 0 개
친구글 비밀글 댓글 쓰기

user error : Error. B.