C 언어 기초

#define GPIO_BASE 0x40020000u
volatile uint32_t *const odr =
    (volatile uint32_t *)(GPIO_BASE + 0x14);
*odr |= 1u << 5;

마이컴의 출력 레지스터를 위와 같이 선언하여 사용하고 있다. 이 선언에 대한 설명으로 올바른 것은?

  1. A*odr의 값은 고쳐 쓸 수 없고, odr 쪽은 인터럽트로 바뀔 수 있으므로 사용할 때마다 다시 읽힌다
  2. Bvolatile을 붙였으므로, *odr |= 1u << 5의 읽기·변경·쓰기가 도중에 인터럽트되지 않는 하나로 이어진 조작이 된다
  3. Codr가 가리키는 주소는 바꿀 수 없으며, odr를 통한 읽기/쓰기는 생략되지 않고 쓴 횟수만큼 실제로 이루어진다
정답과 해설 보기

정답: C. odr가 가리키는 주소는 바꿀 수 없으며, odr를 통한 읽기/쓰기는 생략되지 않고 쓴 횟수만큼 실제로 이루어진다

const가 *의 오른쪽에 있으므로, odr라는 포인터 자체를 바꿀 수 없고 항상 같은 레지스터의 주소를 가리킨다는 것을 나타냅니다. 가리키는 곳의 uint32_t에는 volatile이 붙어 있으므로, 컴파일러는 *odr의 읽기/쓰기를 생략하거나 합치지 않고 쓴 횟수만큼 실제로 접근합니다. 다만 volatile은 조작을 불가분으로 만들지는 않으므로, *odr |= …의 읽기와 쓰기 사이에 인터럽트가 들어갈 수는 있습니다. 인터럽트 핸들러와 같은 레지스터를 조작하는 경우에는 그동안만 인터럽트를 금지하거나, 비트 세트 전용 레지스터를 사용합니다.

이 분야 연습하기 분야로 돌아가기

C 언어 기초의 다른 문제

  1. C 언어 규격에서 말하는 미정의 동작의 설명으로 올바른 것은?
  2. int와 unsigned int는 32비트로 한다. 다음 중 C 언어 규격에서 미정의 동작이 되는 것은?
  3. 위의 함수를 gcc로 최적화를 켜고 컴파일하면 if (p == NULL)의 판정이 삭제되는 경우가 있다. 그 이유로 올바른 것은?
  4. C 언어 규격에서 int형의 크기에 대해 정해져 있는 것으로 올바른 것은?
  5. 임베디드 프로그램에서 32비트 주변 장치 레지스터의 값을 넣는 변수를 unsigned int가 아니라 stdint.h의 uint32_t로 선언하는 경우가 많다. 주된 이유로 올바른 것은?