2017-02-18 12 views
1

나는 다음과 같이 간단한 실험, 클래스 정의와 funciton의 정의와 ".H"파일했던 그런 다음헤더 파일에 함수 본문이 들어있어 중복 된 정의로 이어 집니까?

$cat testInline.h 
#pragma once 
class C{ 
public: 
    void f(){} 
}; 
void g(){} 

을이 .H 파일의 2 사용자 :

$cat use01.cpp 
#include"testInline.h" 
void g01(){ 
    g(); 
    C obj1; 
    obj1.f(); 
} 

$cat use02.cpp 
#include"testInline.h" 
int main(){ 
    g(); 
    C obj2; 
    obj2.f(); 
    return 0; 
} 

내가 그들을 함께 컴파일 오류 가져옵니다

$g++ use01.cpp use02.cpp 
duplicate symbol __Z1gv in: 
    /var/folders/zv/b953j0_55vldj97t0wz4qmkh0000gn/T/use01-34f300.o 
    /var/folders/zv/b953j0_55vldj97t0wz4qmkh0000gn/T/use02-838e05.o 
ld: 1 duplicate symbol for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

정말 이상한 보이는 : 나는 아직도 내가 g (의 중복 정의를보고에서 컴파일러를 중지 할 수 없습니다 "한번의 #pragma"사용했습니다) (__ Z1gv를

inline void g(){} 

글쎄, 그것은 컴파일 :

가 그럼 난 testInline.h-> g()의 정의를 수정) 이름 맹 글링으로처럼합니다. C++에서는 "인라인"키워드는 기본적으로 쓸모가 없습니다. 왜냐하면 컴파일러가 함수의 인라인 여부를 결정할 것이기 때문입니다.

왜 C 스타일의 함수 g()가 중복을보고하지 않고 .h 파일의 코드를 사용하는 C :: f()가 중복을보고하지 않는 이유는 무엇입니까? 그리고 클래스 C가 "f()"함수에 "인라인"을 추가하지 않아도되는 반면, g()는 "인라인"을 사용해야하는 이유는 무엇입니까?

희망 내 질문을 명확하게 말했습니다. 당신의 도움을 주셔서 감사합니다.

답변

3

I've used "#pragma once",

예. 그리고 두 번역 단위의 각 하나는 헤더 파일을 정확히 한 번 효과적으로 처리했습니다. 각 번역 단위에는 헤더 파일이 한 번만 포함되어 있기 때문에 pragma가 없어도 각각의 경우에 그렇게했을 것입니다.

#pragma once "컴파일중인 번역 단위 중 하나에이 헤더 파일을 포함"한다는 의미가 아닙니다. 이것은 "번역 단위가 직접 또는 간접적으로 헤더 파일을 두 번 이상 포함하는 경우에도 번역 단위당 한 번이 헤더 파일을 포함합니다"를 의미합니다. 따라서 각 번역 단위는 헤더 파일을 포함하고 헤더 파일 자체에서 함수/메소드를 정의했습니다. 동일한 함수 또는 메소드가 두 번역 단위에 의해 정의되기 시작했기 때문에 링크 시간에 복제본이 생성되었습니다.

Isn't it in C++ that "inline" keyword is basically useless, because compilers will decide whether it'll inline a function or not?

컴파일러가 함수가 실제로 인라인되는지 여부를 결정하는 것은 사실입니다. 그러나 inline 키워드는 함수 정의가 실제로 사용될 때마다 논리적으로 인라인 된 것처럼 처리되는지 여부를 지정합니다. 따라서 inline 키워드를 사용하더라도 논리적으로 모든 참조에서 인라인으로 삽입되므로 중복 정의가 발생하지 않습니다.

실제로 발생하는지 또는 컴파일러에서 인라인되지 않은 코드를 생성하는지 여부는 컴파일러의 책임입니다. 그러나 C++은 함수가 "인라인 된 것처럼"컴파일되도록 요구합니다. 컴파일러가 함수를 인라인하지 않기로 결정한 경우에도 함수의 중복되지 않은 인라인 된 복사본이 잘못된 형식의 프로그램이되지 않도록 모든 단계를 수행해야합니다.

And,why C::f() with code in .h file doesn't report duplication,

클래스 메소드는 클래스의 정의 안에 정의하므로

inline 키워드가 명시 적으로 지정되지 않은 경우에도 효과적으로 인라인 정의입니다.

+0

"C++은 함수가"인라인 된 것처럼 "컴파일되도록 요구합니다."재귀 함수를 고려하십시오. ;-) –

3

inline 키워드는 쓸모가 없습니다. 함수가 실제로 인라인되었는지 여부를 반드시 제어하지는 않습니다.

inline 키워드는 여러 번역 단위에서 정의 된 기능을 표시합니다. (정의와 의미는 모두 같아야합니다.) 헤더 파일에 정의 된 함수를 inline으로 표시해야합니다.

C::f과 같이 클래스 정의 내에 정의 된 함수는 자동으로 "inline"으로 간주됩니다.