C++ inline - 9. C++17 이후의 변화
9. C++17 이후의 변화
🔹 inline 변수 (inline variable)
✅ C++17 이전의 문제점
C++17 이전에는 헤더 파일에서 변수를 정의하는 것이 까다로웠습니다.
- 전역 변수를 헤더 파일에 정의하면, 여러 개의 소스 파일에서 포함될 경우 링커 오류(Linker Error) 가 발생할 수 있습니다.
- 이를 방지하려면 extern 키워드를 사용해야 했습니다.
📌 C++17 이전의 전역 변수 사용 예제
📁 config.h
#ifndef CONFIG_H
#define CONFIG_H
extern int globalValue; // 선언만 제공 (정의는 다른 소스 파일에 존재)
#endif // CONFIG_H
📁 config.cpp
#include "config.h"
int globalValue = 42; // 전역 변수의 실제 정의
📁 main.cpp
#include <iostream>
#include "config.h"
int main() {
std::cout << globalValue << std::endl; // 42 출력
return 0;
}
📌 문제점
- extern을 사용하면 여러 소스 파일에서 동일한 전역 변수를 공유할 수 있지만,
항상 정의(.cpp 파일)를 따로 제공해야 하는 불편함이 있습니다. - 만약 config.h에서 직접 변수를 정의하면 링커 오류 발생 가능성이 큽니다.
✅ C++17 이후: inline 변수를 통한 해결
C++17에서는 inline 변수를 도입하여 헤더 파일에서도 안전하게 전역 변수를 정의할 수 있게 되었습니다.
즉, inline 변수는 중복 정의 문제 없이 여러 번 포함될 수 있습니다.
📌 C++17 이후 inline 변수를 사용한 예제
📁 config.h
#ifndef CONFIG_H
#define CONFIG_H
inline int globalValue = 42; // C++17 이후에는 헤더 파일에서 정의 가능
#endif // CONFIG_H
📁 main.cpp
#include <iostream>
#include "config.h"
int main() {
std::cout << globalValue << std::endl; // 42 출력
return 0;
}
📌 변경된 점
- inline int globalValue = 42;를 사용하면 여러 소스 파일에서 config.h를 포함해도 링커 오류가 발생하지 않음.
- inline 변수를 통해 하나의 전역 변수를 여러 번 정의해도 문제가 발생하지 않음.
✅ inline 변수의 특징
특징 | 설명 |
헤더 파일에서 정의 가능 | 여러 소스 파일에서 포함해도 중복 정의 오류 없음 |
컴파일러가 한 번만 생성 | inline 변수가 포함된 모든 파일에서 같은 객체로 처리됨 |
extern 불필요 | extern 키워드를 사용할 필요 없음 |
🔹 inline을 활용한 헤더 전용 변수 정의
C++17 이전에는 헤더 파일에서 전역 변수를 정의하는 것이 위험했습니다.
그러나, C++17 이후에는 inline 변수를 사용하여 헤더 전용 변수를 안전하게 정의할 수 있습니다.
📌 예제: 헤더 파일에서 inline을 활용한 전역 변수 정의
📁 constants.h
#ifndef CONSTANTS_H
#define CONSTANTS_H
inline constexpr double PI = 3.141592653589793;
inline constexpr int MAX_USERS = 1000;
#endif // CONSTANTS_H
📁 main.cpp
#include <iostream>
#include "constants.h"
int main() {
std::cout << "PI: " << PI << std::endl;
std::cout << "Max Users: " << MAX_USERS << std::endl;
return 0;
}
📌 설명
- inline constexpr double PI = 3.141592653589793; → 헤더 파일에서 정의 가능.
- inline이 없으면 여러 파일에서 포함될 때 링커 오류가 발생할 가능성이 있음.
- constexpr과 함께 사용하면 컴파일 타임에 상수 값으로 최적화 가능.
✅ inline 변수와 기존 방식(extern) 비교
비교 항목 | extern 변수 (C++17 이전) | inline 변수 (C++17 이후) |
헤더 파일에서 정의 가능 여부 | ❌ (정의하면 링커 오류 발생) | ✅ 가능 |
추가적인 .cpp 파일 필요 여부 | ✅ 필요 (extern 선언 후 .cpp에서 정의) | ❌ 불필요 (헤더 파일에서 바로 정의 가능) |
전역 변수 관리 용이성 | 불편함 (변수마다 extern 선언 필요) | 간편함 (헤더 파일에서 직접 관리 가능) |
📌 결론
- C++17 이전 → extern을 사용하여 전역 변수를 선언하고, .cpp 파일에서 정의해야 함.
- C++17 이후 → inline 변수를 사용하면 헤더 파일에서 직접 전역 변수를 정의할 수 있음.
🔹 inline 변수의 사용 사례
✅ 1. 전역 설정 값 저장
#ifndef SETTINGS_H
#define SETTINGS_H
inline int screenWidth = 1920;
inline int screenHeight = 1080;
#endif // SETTINGS_H
📌 설명
- screenWidth와 screenHeight를 전역 변수로 사용하면서도 여러 소스 파일에서 안전하게 포함 가능.
✅ 2. 싱글톤 패턴(Singleton)과 inline 변수 활용
#ifndef LOGGER_H
#define LOGGER_H
#include <iostream>
class Logger {
public:
void log(const std::string& message) {
std::cout << "[LOG] " << message << std::endl;
}
};
// C++17 이전에는 extern Logger logger; 사용
inline Logger globalLogger; // C++17 이후에는 inline 사용 가능
#endif // LOGGER_H
📁 main.cpp
#include "logger.h"
int main() {
globalLogger.log("Hello, World!"); // [LOG] Hello, World!
return 0;
}
📌 설명
- inline Logger globalLogger;를 사용하면 싱글톤 객체를 전역적으로 정의할 수 있음.
- extern 없이도 헤더 파일에서 안전하게 전역 객체를 관리할 수 있음.
📌 정리
✅ C++17 이전에는 전역 변수를 헤더 파일에서 정의하면 링커 오류 발생 가능 → extern 필요
✅ C++17 이후 inline 변수를 사용하면 헤더 파일에서 안전하게 전역 변수를 정의할 수 있음
✅ inline 변수는 여러 번 포함해도 단일 객체로 처리되므로 중복 정의 문제 없음
✅ inline constexpr을 사용하면 컴파일 타임에 상수 값으로 최적화 가능
✅ 싱글톤 패턴, 설정 값 관리 등 여러 파일에서 공유해야 하는 변수에 유용
📌 결론
C++17 이후에는 inline 변수를 적극 활용하면 코드의 유지보수성을 높이고, 전역 변수 관리가 더욱 쉬워집니다!