gcc __attribute__((used)), ((aligned(x))), ((packed)), ((weak))

728x90
반응형

"__attribute__" 키워드는 GCC 컴파일러가 제공하는 확장 기능으로 C 표준은 아니며 윈도우의 #pragma와 비슷한 역할을 한다. 

 

Linux나 MCU 소스코드를 분석하다보면 자주 볼 수 있을 것이다. attribute라는 단어 그대로 "속성"을 지정하는 키워드다.

 

__attribute__((__used__))

  • 컴파일러가 컴파일 과정에서 코드를 최적화 할 때 선언되어 있고 사용되지 않는 변수를 제거하지 않도록 하는 기능
  • 변수를 선언해놓고 사용하지 않을 때 발생하는 관련 warning를 발생시키지 않음

__attribute__((__aligned__(x)))

  • 선언한 변수의 메모리주소를 x의 배수로 정렬
  • example : __attribute__((__aligned__(sizeof(long))))

__attribute__((__packed__))

  • 구조체 변수에 대한 메모리 할당을 실제 데이터 크기만큼만 하도록 한다. 일반적으로 align 규칙은 4 byte, word 단위이다.
  • example
    typedef struct {
    	int a;
    	char b;
    } test;
     위와같은 구조체가 있을 경우 컴파일러는 일반적으로 align 규칙에 의해 총 8Byte의 메모리를 할당할 것이다. 이렇게 되면 변수 b는 1 byte만 사용하기 때문에 3byte의 메모리 손실이 발생하게 된다.  

    typedef struct {
    	int a;
    	char b;
    } __attribute__((__packed__)) test;
     위 코드와 같이 구조체 이름 앞에 __attribute__((__packed__)) 키워드를 사용하게 되면 컴파일러는 구조체의 실제 크기인 5byte를 할당해 사용하지 않는 메모리를 할당하지 않도록 할 수 있다.

__attribute__((weak))

  • 같은 이름의 symbol(변수, 함수 등)이 2개 있을 때 어떤 하나에 __attribute__((weak)) 표기가 되어 있다면 표기가 없는 Symbol이 __attribute__((weak)) 표기되어 있는 심볼을 오버라이드(override)한다.
  • __attribute__((weak)) 표기가 없는 Symbol을 Strong symbol이라 한다.
  • __attribute__((weak)) 표기가 여러개 있으면 랜덤 선택된다.
  • 하나의 Strong symbol와 여러 개의 __attribute__((weak)) symbol이 있다면 Strong symbol이 선택된다. 
  • 여러 개의 Strong Symbol은 컴파일 에러가 발생한다. 
  • 컴파일 과정에서 초기화된 전역변수들은 Strong, 초기화되지 않은 변수들은 weak 속성을 갖는다.
  • weak symbol은 Definition이 필요하지 않다. 

 

__attribute__((section ("section_name")))

  • 임의의 함수 or 변수가 특정 영역에 있어야 한다는것을 명시함.
  • __attribute__((section (.vector))) const uint16_t variable; 이와 같이 선언하면 variable 변수는 .vector영역에 있다는 의미다.
  • 이 부분은 Linker 파일에 대한 이해가 더 필요하다. 

 

 

 

 

이 외에도 다양한 옵션이 있지만 현재까지 이해된것들만 정리하도록 하겠다. 

 

 

 

 

 

 

728x90
반응형