기호 상수 난제
Source: Dev.to
소개
프로그래밍 언어에서 심볼릭 상수는 상수를 대신해 사용할 수 있는 이름, 즉 기호입니다. 프로그래밍 언어는 수학에서 심볼릭 상수를 물려받았으며, 수학에서는 특정 분야별로 많은 상수가 그룹화되어 있습니다. 예를 들어: π(파이), c(광속), e(오일러 수), G(중력 상수), h(플랑크 상수) 등. 이러한 정확한 상수들을 프로그램에 정의하고 사용할 수 있지만, 대부분의 프로그램은 프로그램 자체에 특화된 상수를 정의합니다. 매직 넘버 대신 상수를 사용하는 것이 더 좋습니다.
C와 C++는 수십 년에 걸쳐 발전하면서 심볼릭 상수를 지정하는 여러 방법을 얻게 되었습니다. 주요 방법은 다음과 같습니다.
- 매크로 (
#define). - 열거형(enumeration).
const.constexpr.
특정 상황에 어느 방법을 써야 할지 결정하는 것은 꽤나 난제일 수 있습니다.
매크로
원래 C에는 매크로만 있었으며, 특히 객체‑같은 매크로가 사용되었습니다. 예:
#define BUF_SIZE 8192
매크로는 충분히 동작하지만, 좋은 방법은 아닙니다. 왜냐하면 매크로는 스코프를 무시하므로 충돌을 피하려면 보통 매우 구체적이고 긴 이름을 붙여야 하기 때문입니다.
열거형
C와 C++의 열거형은 관련된 상수 집합을 선언할 때 더 나은 선택입니다. C++에서는 enum class를 사용하면 스코프를 지정해 충돌을 방지할 수 있지만, C에서는 여전히 전역 스코프에 존재합니다. 또 하나의 제한은 열거형 상수는 정수값에만 사용할 수 있다는 점입니다.
const
C와 C++에서 상수를 선언할 때 const를 사용할 수 있습니다. 예:
static unsigned const BUF_SIZE = 8192;
char BUF[ BUF_SIZE ];
int main() {
char local_buf[ BUF_SIZE ];
// ...
}
C++에서는 경고 없이 정상적으로 컴파일되지만, C에서는 경고가 발생하거나 전혀 받아들여지지 않을 수 있습니다(특히 언어 확장을 비활성화한 경우). 왜냐하면 const는 불변을 의미할 뿐 상수를 의미하지 않으며, C는 이 부분에 더 까다롭기 때문입니다.
BUF 선언은 받아들여질 수 있지만, local_buf 선언은 가변 길이 배열(VLA)로 간주되거나(사용을 권장하지 않음) VLA가 선택적 기능이기 때문에(특히 Microsoft C 컴파일러는 지원하지 않음) 거부될 수 있습니다.
C23 이전(아래 참고)에서는 흔히 열거형을 이용해 우회합니다:
enum {
BUF_SIZE = 8192
};
즉, 이름이 없는 열거형을 사용하는 것입니다. 이 방법의 장점은 열거형 상수가 진정한 상수라는 점입니다.
constexpr
C++11 이상 또는 C23 이상을 사용한다면 constexpr가 있습니다. const와 달리 constexpr는 진정한 상수를 의미합니다. 이는 상수를 선언할 때 가장 좋은 선택입니다:
constexpr unsigned BUF_SIZE = 8192;
요약
- 관련된 정수 상수 집합을 선언한다면 C에서는
enum, C++에서는enum class를 사용하세요. - 그렇지 않다면 가능한 경우
constexpr를 사용하세요. - 그 외의 경우
const를 사용하세요. - 마지막 수단으로
#define을 사용하세요.