컴파일 가드가 다중 정의 포함을 방지하지 못하는 이유는 무엇입니까?
여러 *.c 소스 파일에 포함된 헤더 파일 x.h가 있습니다.이 헤더 파일에는 몇 가지 구조 변수가 정의되어 있습니다.
헤더 파일의 선두에 다음과 같이 다중 포함 방지 가드를 배치했습니다.
#ifndef X_H
#define X_H
...
..
//header file declarations and definitons.
#endif//X_H
빌드 시 여러 정의와 관련된 링커 오류가 발생합니다.나는 그 문제를 이해한다.
헤더 파일 상단에 있는 다중 포함 방지 가드는 헤더 파일 x.h의 다중 포함을 방지하여 x.h에 있는 변수의 다중 정의를 회피하지 않습니까?
#pragma
일단 이 컴파일러에서는 동작하지 않습니다.그러면 해결책은 무엇일까요?누군가 비슷한 질문에 이 답을 올렸습니다.나한테는 잘 안 되는 것 같아.이 솔루션은 어떻게 작동합니까?
링커가 불만을 나타내고 있는 경우는, 헤더에 선언만이 아니고 정의가 있는 것을 의미합니다.여기 잘못될 수 있는 것의 예가 있습니다.
#ifndef X_H
#define X_H
int myFunc()
{
return 42; // Wrong! definition in header.
}
int myVar; // Wrong! definition in header.
#endif
이를 다음과 같이 소스 파일과 헤더 파일로 분할해야 합니다.
머리글:
#ifndef X_H
#define X_H
extern int myFunc();
extern int myVar;
#endif
C 출처:
int myFunc()
{
return 42;
}
int myVar;
헤더 가드는 단일 컴파일 유닛(즉, 소스 파일)에만 유효합니다.헤더 파일이 여러 번 포함된 경우(아마도 모든 헤더가 포함된 경우)main.c
차례로 포함되다stdio.h
경비원들이 도와줄 거야
함수의 정의가 있는 경우f
에x.h
이것은 에 의해 포함됩니다.main.c
그리고.util.c
의 정의를 복사하여 붙여넣는 것과 같습니다.f
안으로main.c
작성할 때main.o
같은 일을 하고 있다util.c
창조하다util.o
그러면 링커가 불만을 제기하고 헤더 가드에도 불구하고 이 문제가 발생합니다.여러 개를 가지#include "x.h"
에 기재되어 있는 스테이트먼트main.c
물론 이 경비원들 덕분에 가능하죠
함수가 크지 않으면 그 전에 "인라인"을 사용하면 링커가 불평하지 않습니다.
include guard를 사용하면 1개의 컴파일 유닛이 헤더를 2회 포함할 수 없습니다.예를 들어 헤더 B.h가 A.h를 포함하고 B.cpp가 A.h와 B.h를 포함하는 경우 A.h로부터의 모든 것이 컴파일 B.cpp에서 2회 선언됩니다.
당신네들 경호원들이 이런 일을 막아요, 지금까지는 아무 문제 없어요.
그러나 링크 시 여러 개의 정의가 표시됩니다.즉, 2개의 컴파일 유닛이 같은 것을 정의합니다.이는 헤더에 실제 정의가 있음을 의미하며 모든 변수에 extern을 사용하여 함수가 인라인인지 또는 cpp 파일에 정의되어 있는지 확인합니다.
다중 포함 가드를 사용하면 컴파일러 오류를 방지할 수 있지만 링커 오류가 발생합니다.헤더 파일에 사용하지 않는 데이터 정의가 있습니까?extern
maybe요 maybe maybe maybe?X_H
미미정 정의 ?? ???가 Xlib를 정의하는 문제에.X_H
usr/include/X11/X에 .h로 설정합니다.
""로 전화하시면 .gcc -dM -E
사용하는 예를 (gcc를 사용하는 와 함께 에서 사용할 수 있습니다.CC=gcc CFLAGS="-dM -E" make
에 "Drughta" 가 포함되어 있는#define X_H
할 수 없습니다.Y_H
예를 들어)는 소스 코드 외부에 이미 정의되어 있습니다.
언급URL : https://stackoverflow.com/questions/249701/why-arent-my-compile-guards-preventing-multiple-definition-inclusions
'source' 카테고리의 다른 글
최적의 C/C++ 네트워크 라이브러리 (0) | 2022.08.19 |
---|---|
프로젝트 오일러와의 속도 비교: C vs Python vs Erlang vs Haskell (0) | 2022.08.19 |
VueJ + Vuex + map Actions (0) | 2022.08.19 |
Nuxt.js에서 Rails로 전송된 데이터를 저장하고 싶다. (0) | 2022.08.19 |
Vue: 템플릿은 키를 입력할 수 없지만 템플릿을 div로 바꿀 수 없음 - 래퍼 div 요소가 없는 v-for, 중첩된 v-for 루프가 필요합니다. (0) | 2022.08.18 |