헤더 파일의 중복 포함 및 중첩 포함의 의미

개발过程中 헤더 파일의 중복 포함을 방지하기 위해#ifndef 토글을 사용하는 방법을 배웠습니다. 하지만 모든 구현을 .h 파일에두면 문제가 발생합니다. 예를 들어:
//a.h
#ifndef _A_H_
#define _A_H_
int max(int a, int b) {
    return a > b ? a : b;
}
#endif
//b.h
#include "a.h"
//c.h
#include "a.h"
//main.cpp
#include "b.h"
#include "c.h"

이 경우 main.cpp에서 max 함수가 두 번 포함됩니다. 컴파일러는 이중복합을 허용하지 않습니다.

헤더 파일의 중복 포함 문제

#include 문의 문제점 중 하나는 헤더 파일이 여러 번 포함될 수 있다는 것입니다. 예를 들어:

//main.cpp
#include "x.h"
#include "x.h"

이 코드는 누구도意匠적으로 작성하지 않을 것입니다. 그러나:

//a.h
#include "x.h"
//b.h
#include "x.h"
//main.cpp
#include "a.h"
#include "b.h"

이 코드는 x.h가 두 번 포함된다는 것을 모르고 작성할 수 있습니다. 이러한 중복 포함은 대형 프로젝트에서 특히 문제가 될 수 있습니다.

이 문제를 해결하기 위해 조건 컴파일을 사용합니다:

#ifndef HEADERNAME_H
#define HEADERNAME_H

// 헤더 파일 내용

#endif

이 방법은 헤더 파일이 중복 포함될 때 내용이 무시됨을 보장합니다. 변수 HEADERNAME_H는 헤더 파일의 이름을 기반으로 설정해야 합니다.

그러나 이 방법은 컴파일 속도를 늦출 수 있습니다. 따라서 중복 포함을 피할 수 있는 방법을 항상 검토해야 합니다.

헤더 파일에서의 변수 정의 문제

헤더 파일 내에서 변수를 정의하면 여러 .cpp 파일이 포함될 때 중복 정의 오류가 발생할 수 있습니다. 예를 들어:

//test.h
#ifndef _TEST_H_
#define _TEST_H_

char add1[] = "www.example.com";
char add2[] = "www.example.com";
int i = 10;
void test1();
void test2();

#endif
//test.c
#include 
#include "test.h"

extern i;
extern void test1();
extern void test2();

int main() {
    test1();
    printf("ok\n");
    test2();
    printf("%d\n", i);
    return 0;
}
//test1.c
#include 
#include "test.h"

extern char add1[];

void test1() {
    printf(add1);
}
//test2.c
#include 
#include "test.h"

extern char add2[];
extern i;

void test2() {
    printf(add2);
    for (; i > 0; i--)
        printf("%d-", i);
}

이 예제에서는 중복 정의 오류가 발생합니다. 해결 방법은 헤더 파일에 extern 선언만 남기고 변수 정의를 하나의 .cpp 파일에集中하는 것입니다.

//test.h
#ifndef _TEST_H_
#define _TEST_H_

extern int num;
extern char url1[];
extern char url2[];
void func1();
void func2();

#endif
//test.c
#include 
#include "test.h"

int num = 10;
char url1[] = "www.example.com";
char url2[] = "www.example.net";
void func1() {
    // 구현
}
void func2() {
    // 구현
}

int main() {
    func1();
    printf("ok\n");
    func2();
    printf("%d\n", num);
    return 0;
}
//test1.c
#include 
#include "test.h"

void func1() {
    printf(url1);
}
//test2.c
#include 
#include "test.h"

void func2() {
    printf(url2);
    for (; num > 0; num--)
        printf("%d-", num);
}

이 방법은 각 .cpp 파일에서 변수를 중복 정의하지 않도록 합니다.

외부 변수와 링크 지시자

외부 변수를 사용할 때는 주의가 필요합니다. 예를 들어:

extern int count;

이는 변수 count가 다른 파일에서 정의되었음을 나타냅니다. 함수를 외부 언어(예: C)와 호환하려면 링크 지시자를 사용합니다.

extern "C" int add(int x, int y);

이는 함수 add가 C 언어로 컴파일되었음을 나타냅니다. C++에서는 함수 이름에 형식 정보가附加되지만, extern "C"를 사용하면 이름이 단순히 C 방식으로 처리됩니다.

예를 들어:

void foo(int x, int y);

C 컴파일러는 이 함수를 _foo로 저장합니다. 반면 C++ 컴파일러는 _foo_int_int와 같이 저장합니다. extern "C"를 사용하면 이름이 _foo로 저장됩니다.

9월 12일 23:30에 게시됨