임베디드 면접 용어 사전
C 언어

extern

다른 파일에 정의된 심볼을 참조한다는 선언. 정의가 아니라 선언이라는 점이 핵심이다.

"이 심볼은 다른 곳에 정의되어 있다"고 선언하는 키워드. 정의가 아니라 선언이다.

선언과 정의의 차이 — 이것이 핵심

extern int counter;    // 선언 — "어딘가에 있다". 메모리를 잡지 않는다
int counter;           // 정의 — 실제로 메모리를 할당한다

정의는 프로그램 전체에서 정확히 하나여야 하고, 선언은 여러 번 해도 된다.

표준 사용법

// sensor.c  — 정의는 여기 딱 한 번
int g_temperature = 0;

// sensor.h  — 선언은 헤더에
extern int g_temperature;

// main.c
#include "sensor.h"    // 선언을 가져온다
void f(void) { g_temperature = 25; }

헤더에 정의를 쓰면 안 되는 이유

// sensor.h  ✗ 잘못된 예
int g_temperature;     // 정의!

이 헤더를 두 개의 .c가 include 하면 정의가 두 개가 되어 링커가 multiple definition of 'g_temperature' 를 낸다.

주의 — 예전 GCC는 -fcommon이 기본이라 이것을 눈감아 줬다. GCC 10부터 -fno-common이 기본이 되어, 예전에 되던 코드가 갑자기 링크 에러를 내는 일이 생긴다. 툴체인을 올렸을 때 겪는 흔한 문제다.

헤더에서 함수는 extern이 생략된다

void init(void);            // 함수 선언은 자동으로 extern
extern void init(void);     // 같은 뜻. 붙여도 되지만 관례상 생략

함수는 본체 { } 가 없으면 선언이므로 extern이 불필요하다.

상수 정의를 헤더에 두는 방법

// ① static — 각 .c 마다 별도의 사본이 생긴다 (RAM/ROM 낭비 가능)
static const int MAX = 100;

// ② extern + 정의 분리 — 사본이 하나
// config.h
extern const int MAX;
// config.c
const int MAX = 100;

// ③ enum 또는 #define — 메모리를 아예 안 쓴다
enum { MAX = 100 };

임베디드에서는 ③을 선호한다. 작은 정수 상수에 ROM 공간과 심볼을 낭비할 이유가 없기 때문이다.

extern "C" — C++과 섞을 때

#ifdef __cplusplus
extern "C" {
#endif

void hal_uart_init(void);

#ifdef __cplusplus
}
#endif

왜 필요한가 — 이름 맹글링

C++은 오버로딩을 지원하려고 함수 이름에 매개변수 타입 정보를 붙인다.

C에서 void f(int)→ 심볼 "f"
C++ 에서 void f(int)→ 심볼 "_Z1fi"(맹글링)

C로 컴파일된 라이브러리(HAL, 벤더 SDK)를 C++ 코드에서 부르면 링커가 _Z1fi를 찾다가 실패한다. extern "C"맹글링을 끄라고 지시한다.

ISR 핸들러에 특히 중요하다 — 벡터 테이블은 어셈블리나 C로 작성되어 SysTick_Handler라는 정확한 이름을 기대한다. C++ 파일에 핸들러를 쓰면서 extern "C"를 빠뜨리면 맹글링된 이름이 되어 링크는 되지만 인터럽트가 기본 핸들러로 가서 무한 루프에 빠진다. 원인을 찾기 매우 어렵다.

링커 스크립트 심볼 참조

extern uint32_t _sdata, _edata, _sbss, _ebss;   // 링커가 만든 심볼

// startup 코드에서 .data 를 복사할 때 사용
for (uint32_t *p = &_sdata; p < &_edata; p++) { … }

주소 자체가 값이므로 반드시 &를 붙여 쓴다. 이 심볼들에는 실제 저장 공간이 없다 — 링커가 주소만 정해 준 것이다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — C 언어 핵심 — 포인터·메모리클래스·const/volatile·비트·struct 패딩