프로그래밍 언어/C++

C++ static - 4. 파일 및 함수 수준에서의 static (4.1. 파일 수준의 static (내부 연결성))

개발_노트 2025. 3. 25. 21:04

 

✅ 4.1. 파일 수준의 static (내부 연결성)

🔹 개념: static 전역 변수 = 해당 파일에서만 접근 가능

  • 전역 변수 앞에 static을 붙이면 해당 변수는 선언된 소스 파일(.cpp) 내에서만 접근 가능합니다.
  • 다른 소스 파일에서 extern으로 참조할 수 없으며, 내부 연결성(internal linkage) 을 가집니다.
// fileA.cpp
static int count = 0;  // fileA.cpp 내부에서만 사용 가능

📌 사용 목적:

  • 전역 이름 충돌 방지
  • 모듈 단위 캡슐화

🔹 extern과의 차이 비교

키워드 연결성(Linkage) 접근 범위 사용 예
없음 (일반 전역 변수) 외부 연결성 다른 파일에서 참조 가능 여러 파일에서 공유
extern 외부 연결성 외부에서 선언, 내부 정의 필요 외부 전역 변수 참조
static 내부 연결성 정의된 파일 내에서만 사용 가능 변수/함수 숨기기

📌 static은 숨기기, extern은 공유하기를 위한 키워드입니다.


🔹 예시: static vs extern

// fileA.cpp
static int count = 0;

void increment() {
    count++;
}
// fileB.cpp
extern int count;  // ❌ 오류: count는 static이라 외부 참조 불가

🔹 헤더 파일에 static 변수 정의 시 주의

// bad_header.h
static int counter = 0;  // ❌ 모든 포함 파일마다 counter가 생성됨

📌 이렇게 정의하면 헤더를 포함한 모든 소스 파일에 중복된 전역 변수 생성
의도치 않은 동작 + 디버깅 어려움 + 최적화 방해

✅ 안전한 헤더 작성 방식

// header.h
extern int counter;

// source.cpp
int counter = 0;

🔹 ✅ 익명 네임스페이스와의 비교 (Modern C++ 방식)

현대 C++에서는 static 대신 익명 네임스페이스를 사용하여 파일 범위 제한을 구현하는 것이 일반적입니다.

// fileA.cpp
namespace {
    int count = 0;  // 내부 연결성, 외부 참조 불가
}
항목 static  익명 네임스페이스
접근 범위 파일 단위 제한 파일 단위 제한
구조화 변수/함수 하나씩 제한 여러 선언 묶어 은닉 가능
문법 변수/함수 앞에 static 네임스페이스로 감쌈
현대 C++ 권장도 보통 (구식 스타일) ✅ 권장 (C++11 이후 일반화)

📌 익명 네임스페이스는 정적 변수, 함수, 클래스까지 함께 은닉 가능하여 더 유연하고 명확함


🔹 ✅ 컴파일러 최적화와의 관계

  • static으로 선언된 함수나 변수는 외부에서 접근되지 않음이 보장되므로,
    컴파일러가 보다 적극적으로 최적화할 수 있습니다.

최적화 예시:

  • 인라인화
  • 사용되지 않는 코드 제거 (Dead Code Elimination)
  • 링크 타임 최적화 (LTO) 활용 가능

💡 예: static 함수는 외부 참조가 없으므로, 사용되지 않으면 안전하게 제거 가능


✅ 요약

항목 설명
static 전역 변수 선언된 소스 파일 내에서만 접근 가능 (내부 연결성)
사용 목적 이름 충돌 방지, 모듈 캡슐화
extern과의 차이 static은 숨김, extern은 외부 참조 허용
헤더 작성 주의 헤더에 static 변수 정의 금지 (중복 정의 위험)
현대적 대안 익명 네임스페이스 사용 권장 (C++11 이후 표준 스타일)
최적화 관점 컴파일러가 더 강력한 최적화 적용 가능