static이 내부 연결 (internal linkage)를 수행한다면, extern은 외부연결(external linkage)를 수행함으로써, 파일을 넘어서 전체 프로그램에서 유효하도록 하기 위함이다.

 

사용 방법은 하나의 변수당 한 번만 선언되어야 하고, 한 번만 정의 될수 있다. 

아래는 사용 예시이다. "myvar.h"에서 extern 키워드가 없으면 링킹이 되지 않아서 빌드 에러가 발생한다. 

 

"var.h"

extern int myvar; // extern variable declaration

"var.cpp"

#include "var.h"

int myvar = 0; // extern variable definition

"dog.h"

void do_dog();

"dog.cpp"

#include <iostream>
#include "var.h"
#include "dog.h"

void do_dog()
{
   myvar += 1000;
   std::cout << myvar << std::endl;
}

"cat.h"

void do_cat();

"cat.cpp"

#include <iostream>
#include "var.h"
#include "cat.h"

void do_cat()
{
   myvar += 10;
   std::cout << myvar << std::endl;
}

"main.cpp"

#include "dog.h"
#include "cat.h"

int main()
{
   do_cat(); // 10
   do_dog(); // 10 + 1000 = 1010
}

 

참고

 

Brian Kernighan & Dennis Ritchie, <The C Programming Language> 2nd edition

Bjarne Stroustrup, <The C++ Programming Language> 4th edition

'프로그래밍 언어 > C' 카테고리의 다른 글

C - 키워드 static  (0) 2021.01.24

키워드 "static"은 왜 쓰는것일까? 

 

데니스 리치 & 커니핸은 static의 존재 이유가 같은 프로그램내의 다른 파일들에 있는 똑같은 이름들로 인한 혼란을 방지하기 위함이라고 설명하고 있다.  

 

비야네 스트롭스트룹은 static 키워드를 "use internal linkage"로 해석한다. 

 

결론적으로, 이것은 링킹 과정에서의 에러를 피하기 위함이라고 설명 할 수 있다.

따라서, Linking에 그 원인이 있다고 생각한다.  좀 더 자세한 예제를 통해 살펴보자. 

 

<dog.h>

void sayhello();

<dog.cpp>

#include <iostream>
#include "dog.h"

void sayhello()
{
   std::cout << "Hi, I'm a dog" << std::endl;
}

 

<cat.h>

void sayhello();

<cat.cpp>

#include <iostream>
#include "cat.h"

void sayhello()
{
   std::cout << "Hi, I'm a cat " << std::endl;
}

 

sayhello()가 두 번 정의 및 구현 되었기 때문에 링킹과정에서 에러가 생겨서 빌드를 실패하게 된다. 

dog와 cat 파일의 sayhello()의 translation unit의 범위를 각각의 파일에 한정시킬 필요가 있다.

({dog.h, dog.cpp} | ({cat.h, cat.cpp}) 따라서 static을 쓰는 것이다. 아래와 같이 코드를 수정하면 빌드 할 수 있다.  

 

<dog.h>

static void sayhello();

<dog.cpp>

#include <iostream>
#include "dog.h"

static void sayhello()
{
   std::cout << "Hi, I'm a dog" << std::endl;
}

<cat.h>

static void sayhello();

<cat.cpp>

#include <iostream>
#include "cat.h"

static void sayhello()
{
   std::cout << "Hi, I'm a cat " << std::endl;
}

 

빌드를 성공적으로 수행한다.

이 static 키워드를 선언하면 해당 변수가 파일에서 전역변수로서 사용된다. 다음 예를 보자. 

 

#include <iostream>

static int sayhello()
{
  static int count = 0;
  count++;
  return count;
}

int main()
{
  for (int i = 0; i < 100; i++)
  {
    std::cout << sayhello() << std::endl;
  }
}

주목할 점은, sayhello()를 100번 호출할때마다 static int sayhello() = 0를 100번 수행하여 count를 100번 초기화 하지 않는 다는 것이다 (만약 그랬으면 0,1,0,1,0,1,0,1,0... 이 출력되었을 것이다).

대신, 컴파일 시에 static int sayhello() = 0를 메모리의 데이터영역에 집어 넣고 이후의 선언은 무시하고 count++로 count 값을 증가 시키고 있다 (1,2,3,4,5 ... 97,98,99,100). 

 

참고

 

Brian Kernighan & Dennis Ritchie, <The C Programming Language> 2nd edition

Bjarne Stroustrup, <The C++ Programming Language> 4th edition

'프로그래밍 언어 > C' 카테고리의 다른 글

C - 키워드 extern  (0) 2021.01.24

+ Recent posts