본문 바로가기
Data & Programming/C

[C언어] U2L - Unix 와 Linux에서 변수 초기화 차이점

by 눈부셔™ 2023. 11. 13.
728x90

[C언어] U2L - Unix 와 Linux에서 변수 초기화 차이점

 

Unix와 Linux는 둘 다 유닉스 계열 운영체제이지만, 몇 가지 중요한 차이점이 있습니다. 이러한 차이점은 Unix에서 작성된 C프로그램을 Linux로 전환할 때 오류를 유발할 수 있습니다. 

 

그 중 하나로, Unix와 Linux는 변수 초기화에 대한 규칙이 다릅니다.

Unix에서는 변수의 초기화가 선택 사항입니다. 즉, 변수를 선언한 후 초기화하지 않고 사용해도 됩니다.

그러나 Linux에서는 모든 변수는 사용되기 전에 초기화해야 합니다.

[C언어] U2L - Unix 와 Linux에서 변수 초기화 차이점

 

Unix에서는 초기화하지 않아도 되는 경우

Unix는 POSIX 표준을 준수하는 운영체제입니다. POSIX 표준에 따르면, 다음과 같은 경우에는 변수를 초기화하지 않아도 됩니다.

 

  • 전역 변수정적 변수는 초기화하지 않으면 자동으로 0으로 초기화됩니다. 전역 변수는 함수 밖에서 선언된 변수이고, 정적 변수는 static 키워드를 사용하여 선언된 변수입니다. 예를 들어, 다음과 같은 코드에서는 x와 b는 모두 0으로 초기화됩니다.
1
2
3
4
5
6
7
8
9
10
11
int x; // 전역 변수
void func() {
  static int b; // 정적 변수
  b++;
}
int main() {
  int a; // 지역 변수
  printf("a = %d\n", a);
  func();
  return 0;
}

 

  • 지역 변수는 함수 내에서 선언된 변수입니다. 지역 변수는 초기화하지 않으면 쓰레기(garbage) 값을 가질 수 있습니다. 쓰레기 값이란, 메모리에 남아있는 임의의 값입니다. 예를 들어, 위의 코드에서는 a는 쓰레기 값을 가질 수 있습니다. 그러나, POSIX 표준에 따르면, 지역 변수가 다음과 같은 경우에는 0으로 초기화됩니다.
    • 레지스터 변수는 register 키워드를 사용하여 선언된 변수입니다. 레지스터 변수는 CPU의 레지스터에 저장되어 빠르게 접근할 수 있습니다. 예를 들어, 다음과 같은 코드에서는 r은 0으로 초기화됩니다.
1
2
3
4
void func() {
  register int r; // 레지스터 변수
  printf("r = %d\n", r);
}

 

  • 배열은 동일한 타입의 여러 개의 변수를 연속적으로 저장한 자료구조입니다. 배열은 크기를 명시적으로 지정하거나, 초기화 값의 개수에 따라 자동으로 결정됩니다. 예를 들어, 다음과 같은 코드에서는 arr1은 5개의 원소를 가지고, arr2는 3개의 원소를 가집니다. 배열은 초기화 값이 부족한 경우, 나머지 원소들은 0으로 초기화됩니다. 예를 들어, 아래의 코드에서는 arr1의 4번째와 5번째 원소는 0으로 초기화됩니다.
1
2
3
4
void func() {
  int arr1[5= {123}; // 크기를 지정하고 일부만 초기화
  int arr2[] = {456}; // 크기를 지정하지 않고 전체 초기화
}

 

  • 구조체는 서로 다른 타입의 여러 개의 변수를 묶어서 하나의 자료형으로 정의한 것입니다. 구조체는 typedef 키워드를 사용하여 별칭을 지정할 수 있습니다. 예를 들어, 다음과 같은 코드에서는 Point라는 구조체 타입을 정의하고, p라는 변수를 선언하고 있습니다.
1
2
3
4
5
6
7
typedef struct {
  int x;
  int y;
} Point;
void func() {
  Point q = {3}; // 구조체 변수 일부만 초기화
}

 

  • 공용체는 서로 다른 타입의 여러 개의 변수를 공유하는 자료형입니다. 공용체는 구조체와 마찬가지로 typedef 키워드를 사용하여 별칭을 지정할 수 있습니다. 예를 들어, 다음과 같은 코드에서는 Data라는 공용체 타입을 정의하고, d라는 변수를 선언하고 있습니다. 공용체는 초기화 값이 부족한 경우, 나머지 멤버들은 0으로 초기화됩니다. 예를 들어, 아래의 코드에서는 d의 f와 c 멤버는 0으로 초기화됩니다.
1
2
3
4
5
6
7
8
typedef union {
  int i;
  float f;
  char c;
} Data;
void func() {
  Data d = {10}; // 공용체 변수 초기화
}

 

 

 

Linux에서는 초기화를 반드시 해야 하는 경우

Linux는 Unix와 마찬가지로 POSIX 표준을 준수하는 운영체제이지만, 완전히 동일한 것은 아닙니다. 

Linux는 Unix보다 더 엄격한 규칙을 적용하여, 초기화하지 않은 변수에 대해 오류를 발생시킬 수 있습니다. 

Linux에서는 다음과 같은 경우에는 변수를 반드시 초기화해야 합니다.

  • 전역 변수와 정적 변수는 Unix와 마찬가지로 초기화하지 않으면 자동으로 0으로 초기화됩니다. 그러나, Linux에서는 전역 변수와 정적 변수를 상수가 아닌 다른 변수의 값으로 초기화할 수 없습니다. 예를 들어, 다음과 같은 코드에서는 k와 x가 오류를 발생시킵니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
int k; // 전역 변수
int x = k; // 전역 변수를 다른 전역 변수의 값으로 초기화
void func() {
  int z = 2// 지역 변수
  static int b = z; // 정적 변수를 지역 변수의 값으로 초기화
  b++;
}
int main() {
  int a; // 지역 변수
  printf("a = %d\n", a);
  func();
  return 0;
}

 

  • 지역 변수는 Unix와 달리, 레지스터 변수, 배열, 구조체, 공용체 등을 포함하여 모든 경우에 초기화하지 않으면 쓰레기 값을 가집니다. 쓰레기 값은 예측할 수 없고, 프로그램의 동작에 영향을 줄 수 있습니다. 예를 들어, 다음과 같은 코드에서는 r, arr1, p, q, d 등은 모두 쓰레기 값을 가질 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void func() {
  register int r; // 레지스터 변수
  int arr1[5= {123}; // 배열
  typedef struct {
    int x;
    int y;
  } Point;
  Point p = {12}; // 구조체
  Point q = {3}; // 구조체
  typedef union {
    int i;
    float f;
    char c;
  } Data;
  Data d = {10}; // 공용체
  printf("r = %d\n", r);
  printf("arr1[4] = %d\n", arr1[4]);
  printf("q.y = %d\n", q.y);
  printf("d.f = %f\n", d.f);
  printf("d.c = %c\n", d.c);
}

 

따라서, Linux에서는 지역 변수를 사용하기 전에 반드시 초기화를 해주어야 합니다. 초기화를 하지 않으면, 컴파일러가 경고 메시지를 보내거나, 실행 시에 오류를 발생시킬 수 있습니다.

 

 

Linux에서의 대응 방안

사용되는 모든 변수와 함수에는 항상 type이 존재하고 type에 맞는 초기화를 해야한다. 

취약점 Unix Linux
String인 경우 garbage data값이 들어 있어 다른 결과 값으로 인한 문제점 char lx_log[1000]; char lx_log[1000] = {0x00,};
또는
memset(lx_log, 0x00, sizeof(lx_log));
static 변수 선언에 type 이 없는 경우 warning 발생 static si_Cnt; static int si_Cnt;
함수 선언부 Return Type int 누락된 경우 에러 발생 static a0000_init_proc();
static b0000_inpvrf_proc();
static int a0000_init_proc();
static int b0000_inpvrf_proc();

 

 

#C언어  #Linux  #리눅스  #Unix  #유닉스  #개발언어  #은행IT  #금융IT  #코어뱅킹  #금융서비스  #CoreBanking  #프로그래밍  #U2L  #Unix to LInux  #변수 초기화

728x90