C++11 - alignas

개요

alignas()은 컴파일러에 대한 변수를 메모리 상의 특정 위치에 배치(배열) 하도록 요구하는 키워드이다.
예를 들면 4바이트 경계 위치에 배치할 경우 변수는 4의 배수 주소로 배치되고, 8바이트 경계 위치에 배치할 경우 변수는 8의 배수 주소로 배치된다.

문법

alignas()는 변수 선언이나 클래스 멤버 변수 선언에 사용하거나 구조체나 클래스의 선언 시 사용할 수 있다.
변수와 클래스 멤버 변수 선언 시 사용된 경우 선언한 변수를 배치한다.

alignas(32) int i;  // 32바이트 경계로 배치한다

구조체나 클래스의 선언 시 사용된 경우 그 타입의 인스턴스 전체를 배치한다.

struct alignas(32) Test {
};

Test a; // 32바이트 경계로 배치한다.
Test b; // 32바이트 경계로 배치한다.
  • alignas(상수)는 정수의 값으로 배치한다. 0 또는 0으로 평가되는 값을 지정했을 때는 아무것도 일어나지 않는다.
  • alignas(타입)은 alignas(alignof(타입)와 등가이다. 어느 타입 A의 배치를 다른 타입 B에도 적용하고 싶을 때 alignas(A) B test 처럼 쓰인다.




코드

#include <iostream>

struct test {
  alignas(1) int i1, i1_n;
  alignas(2) int i2, i2_n;
  alignas(4) int i4, i4_n;
  alignas(8) int i8, i8_n;
  alignas(16) int i16, i16_n;
  alignas(8) alignas(16) int i8_16, i8_16_n;
};

int distance(void *a, void *b)
{
  return reinterpret_cast<int>(a) - reinterpret_cast<int>(b);
}

int main()
{
  //Zero is ill-formed in GCC 4.9.
  //alignas(0) test a;

  test t;

  std::cout <<
    "alignas(1) int i1:   " << distance(&t.i1_n, &t.i1) << std::endl <<
    "alignas(2) int i2:   " << distance(&t.i2_n, &t.i2) << std::endl <<
    "alignas(4) int i4:   " << distance(&t.i4_n, &t.i4) << std::endl <<
    "alignas(8) int i8:   " << distance(&t.i8_n, &t.i8) << std::endl <<
    "alignas(16) int i16: " << distance(&t.i16_n, &t.i16) << std::endl;

  std::cout <<
    "alignas(8) alignas(16) int i8_16: " << 
    distance(&t.i8_16_n, &t.i8_16) << std::endl;

  return 0;
}
alignas(1) int i1:   4
alignas(2) int i2:   4
alignas(4) int i4:   4
alignas(8) int i8:   8
alignas(16) int i16: 16
alignas(8) alignas(16) int i8_16: 16

만든 이유

  • 메모리 접근을 최적화 한다
  • 하드웨어의 제약을 만족시킨다
  • 같은 주소에 다른 데이터를 저장한다




출처: https://cpprefjp.github.io/lang/cpp11/alignas.html


이 글은 2017-04-01에 작성되었습니다.