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 변수컴파일 타임 상수는 아니지만, 값이 변경되지 않는다는 점에서 일반 변수와 차이가 있습니다.

  1. 의미적으로 불변성을 나타내어 코드 안정성을 높이고,
  2. 컴파일러가 값을 변경하지 않는다고 가정할 수 있으므로 최적화 기회를 제공하며,
  3. 컴파일 타임 오류를 통해 의도치 않은 값을 변경하는 실수를 방지합니다.

이러한 이유로, 값이 변경될 필요가 없는 경우 const를 사용하는 것이 바람직한 코드 스타일입니다.