C++
const 변수와 일반 변수
Keisa
2024. 12. 17. 17:48
1. const 메모리
const는 특정 변수를 변경할 수 없도록 선언할 때 사용됩니다. 이를 통해 메모리 영역에 저장된 값은 변할 수 없으며, 코드의 안전성을 높이고 프로그램 오류를 줄일 수 있습니다.
특징:
- 컴파일 타임에 값이 고정될 수 있다
const 변수는 컴파일러가 해석하여 상수처럼 취급될 수 있습니다. 최적화 단계에서 const 값은 코드에 직접 인라인될 수 있습니다. - 읽기 전용
메모리 위치에 접근할 수 있지만 값을 변경할 수 없습니다. 변경 시 컴파일 오류가 발생합니다. - 런타임에 값이 결정될 수 있음
반드시 모든 const 변수가 컴파일 타임 상수는 아닙니다. 런타임에 초기화된 const 변수도 존재할 수 있습니다.
예시:
const int x = 10; // 컴파일 타임 상수
int y = 20;
const int* ptr = &y; // 포인터는 const로 선언되었으므로 *ptr의 값은 변경 불가.
const int x = 10; // 컴파일 타임 상수 int y = 20; const int* ptr = &y; // 포인터는 const로 선언되었으므로 *ptr의 값은 변경 불가.
메모리 할당 위치:
- 일반적으로 const 변수는 데이터 영역 또는 스택 영역에 위치합니다.
- 컴파일 타임 상수라면 코드 내에 하드코딩되어 존재할 수 있습니다.
- 런타임 상수라면 스택 메모리에 저장되지만 값은 변경되지 않습니다.
2. 일반 메모리 (변경 가능한 변수)
일반적으로 선언된 변수는 변경이 가능하며 읽기와 쓰기가 모두 가능합니다.
특징:
- 값 변경 가능
값을 언제든지 수정할 수 있습니다. - 컴파일러의 최적화와 제약 없음
값이 언제든 변경될 수 있으므로, 컴파일러는 이러한 변수를 최적화할 때 더 주의를 기울여야 합니다.
예시:
int a = 10; // 일반 변수
a = 20; // 값 변경 가능
int a = 10; // 일반 변수 a = 20; // 값 변경 가능
메모리 할당 위치:
- 스택: 함수 내에서 선언된 지역 변수들은 스택에 저장됩니다.
- 힙: 동적 할당된 변수들은 힙 메모리에 저장됩니다.
- 데이터 영역: 전역 변수나 정적 변수는 데이터 영역에 저장됩니다.
3. const와 일반 변수의 메모리 사용의 차이점 요약
특성const 변수일반 변수
변경 가능성 | 변경 불가능 | 변경 가능 |
최적화 | 값이 상수로 취급될 수 있어 최적화에 유리 | 변경될 수 있어 최적화에 제한적 |
메모리 위치 | 컴파일 타임에 상수로 치환되거나 데이터 영역에 저장 | 스택, 힙, 데이터 영역 등 다양한 위치 |
런타임 결정 여부 | 컴파일 타임 또는 런타임 상수 | 항상 런타임에 값 결정 |
4. 결론
- const 변수는 읽기 전용이며, 컴파일러가 더 강력한 최적화와 안정성을 보장할 수 있습니다.
- 일반 변수는 값 변경이 자유롭지만 최적화 측면에서는 제약이 생길 수 있습니다.
따라서, 코드에서 변경되지 않는 값을 const로 선언하면 코드의 명확성과 안정성을 높이고 최적화에 도움을 줄 수 있습니다.
※ const로 선언된 변수가 런타임에 초기화된다면 일반 변수와 똑같은가?
1. const 변수와 일반 변수의 차이점
1-1. 값 변경 가능 여부
- const 변수:
한번 초기화되면 값을 변경할 수 없습니다.
즉, 메모리 상에 할당된 위치는 읽기 전용입니다. - 일반 변수:
언제든지 값을 변경할 수 있습니다.
예시:
int a = 10; // 일반 변수
const int b = a; // 런타임에 초기화되는 const 변수
b = 20; // 오류! b는 const로 선언되어 값을 변경할 수 없습니다.
int a = 10; // 일반 변수 const int b = a; // 런타임에 초기화되는 const 변수 b = 20; // 오류! b는 const로 선언되어 값을 변경할 수 없습니다.
설명: b는 a의 값을 복사해서 초기화되었으나, 그 이후 변경할 수 없습니다. 일반 변수라면 이 코드가 문제없이 실행되었을 것입니다.
1-2. 메모리 보호
- const로 선언된 변수는 값 변경을 방지하기 위한 보호 장치로 사용됩니다.
- 컴파일러는 const 변수의 값을 변경하려는 시도를 감지하여 컴파일 타임 오류를 발생시킵니다.
예시:
void func(const int x) {
x = 100; // 오류! x는 const로 선언되어 변경 불가능.
}
void func(const int x) { x = 100; // 오류! x는 const로 선언되어 변경 불가능. }
일반 변수였다면 x를 수정하는 코드가 실행될 수 있지만, const가 적용되면 컴파일러가 변경을 막습니다.
1-3. 컴파일러의 최적화 여부
- 컴파일러는 const 변수의 변경 불가능성을 활용하여 최적화를 수행합니다.
하지만 런타임에 초기화된 const 변수는 컴파일 타임에 값을 알 수 없으므로 일반 변수와 동일하게 취급될 수 있습니다. - 다만, const로 선언된 변수는 불변성이 보장되기 때문에, 그 이후 코드에서 값이 변경될 수 없다는 점을 컴파일러가 알고 최적화를 돕습니다.
예시:
void func() {
const int a = getInput(); // 런타임에 결정됨
int b = getInput(); // 일반 변수
// 이후 코드에서 a는 불변, b는 변할 수 있음
}
void func() { const int a = getInput(); // 런타임에 결정됨 int b = getInput(); // 일반 변수 // 이후 코드에서 a는 불변, b는 변할 수 있음 }
여기서 a는 불변이기 때문에 이후 코드에서 a를 불변 값으로 간주하고 최적화를 적용할 수 있지만, b는 변경될 수 있기 때문에 최적화에 제한이 있습니다.
2. const의 의미적 차이
const로 선언된 변수는 코드의 의미상 "변하지 않는 값"이라는 의도를 명확히 전달합니다.
- 코드 리뷰나 유지 보수 시, 해당 변수가 절대 변경되지 않는다는 것을 보장합니다.
- 반대로 일반 변수는 언제든 값을 변경할 수 있다는 암묵적 의미가 포함됩니다.
예시:
const int threshold = getThreshold(); // threshold는 초기화 후 변경되지 않음
int current = getValue(); // current는 계속 변경될 수 있음
const int threshold = getThreshold(); // threshold는 초기화 후 변경되지 않음 int current = getValue(); // current는 계속 변경될 수 있음
여기서 threshold는 불변 값이라는 점이 명확하며, 다른 개발자들도 이 변수를 변경하려고 하지 않을 것입니다.
3. const와 일반 변수의 요약
특징const 변수 (런타임 초기화)일반 변수값 변경 가능 여부 | 초기화 후 변경 불가능 | 언제든지 변경 가능 |
의미적 불변성 | 코드상 의미적으로 불변임을 나타냄 | 변경될 수 있음 |
최적화 기회 | 변경 불가능을 활용한 최적화 가능 | 최적화에 더 많은 제약 |
코드 안정성 | 의도치 않은 값 변경 방지 | 의도치 않은 변경 가능 |
컴파일 타임 오류 여부 | 변경 시 컴파일 타임 오류 발생 | 변경 시 오류 없음 |
결론
런타임에 초기화된 const 변수는 컴파일 타임 상수는 아니지만, 값이 변경되지 않는다는 점에서 일반 변수와 차이가 있습니다.
- 의미적으로 불변성을 나타내어 코드 안정성을 높이고,
- 컴파일러가 값을 변경하지 않는다고 가정할 수 있으므로 최적화 기회를 제공하며,
- 컴파일 타임 오류를 통해 의도치 않은 값을 변경하는 실수를 방지합니다.
이러한 이유로, 값이 변경될 필요가 없는 경우 const를 사용하는 것이 바람직한 코드 스타일입니다.