문제

이 게시물 하나의 정의 규칙에 대한 참조.

Wikipedia는 그것을 구현하는 방법을 설명하는 데 꽤 나쁘다

C ++ .NET에서 따라야 할 지침에 대한 좋은 resSources는 어디에서 찾을 수 있습니까?

도움이 되었습니까?

해결책

하나의 정의 규칙은 기본적으로 변수/함수가 컴파일 된 실행 파일의 주소 공간의 한 곳에만 위치 할 수 있음을 의미합니다. 그것을 생각하는 한 가지 방법은 컴파일하는 동안 컴파일 된 프로그램 (객체 코드)에서 사용할 메모리 배열과 변수/함수 위치를 참조하기위한 조회 테이블이 있습니다. 이것은 프로세스 당 수준에서 수행됩니다. 다음이 간단한 프로그램이라고 가정합니다.

파일 1.cpp

int square(int x); // this is a declaration
extern int someVariable; // this is a declration

void square(int x)  // this is a definition
{
    return x * someVariable;
}

file2.cpp

int square(int x); // this is a declaration

int someVariable; // this is a definition    
void main()
{
    someVariable = 12;
    someVariable = square(4);
}       

컴파일러가 객체 코드를 컴파일하기 시작하면 선언을 읽고 테이블에 넣습니다. File 1.cpp를 컴파일하면 다음과 같은 것이 있습니다.

declarations:
    square (XX): function that returns int, and takes a single int as parameter [4 bytes]
    someVariable (YY): integer [4 bytes]
data:
    12 34 56 78 aa XX XX XX XX ab cd
definition:
    square: starts at address 0

이는 기능이 특정 어셈블리 지침에 컴파일된다고 가정합니다. 링커 시간에 xx xx xx xx는 약간의 변환의 주소로 대체됩니다.

file2는 다음과 같은 것입니다.

declarations:
    square (XX): function that returns int, and takes a single int as parameter [4 bytes]
    someVariable (YY): integer [4 bytes]
data:
    00 00 00 00 12 34 56 78 12 34 56 YY YY YY YY 23 21
definitions:
    someVariable: starts at address 0
    main: starts at address 4

이 경우 YY는 정사각형 주소로 대체됩니다.

그것이 링커가 작동하는 곳입니다. 링커의 임무는 목록을 통과하고 컴파일 타임에 프로그램의 주소 공간에있는 모든 것이 어디에 있는지 테이블을 구축하는 것입니다. 그러나 두 객체 파일이 링크를 시도 할 때 변수의 정의가 동일한 경우 문제가 있습니다. 위의 예에서 일부 변환에 대한 두 가지 정의가 있었다면 YY를 대체해야 할 사항을 알 수 없습니다. 마찬가지로, 있다면 아니요 정의, 그런 다음 추악한 링커 오류가 발생합니다.

규칙에 대한 "솔루션"은 .cpp 파일에만 정의가 있고 .h 파일에 사물의 선언이 있도록 파일을 분할하는 것입니다. 위의 예는 다음과 같습니다.

파일 1.cpp

#include "file2.h"

void square(int x)  // this is a definition
{
    return x * someVariable;
}

파일 1.H

int square(int x); // this is a declaration

file2.cpp

#include "file1.h"

int someVariable; // this is a definition    
void main()
{
    someVariable = 12;
    someVariable = square(4);
}

file2.h

extern int someVariable;

이것은 엄청나게 간단한 예이며, 선언과 정의 사이의 구별 개념이 없기 때문에 .NET에는 실제로 적용되지 않습니다.

다른 팁

하나의 정의 규칙을 준수하는 가장 쉬운 방법은 정의를 헤더 대신 .CPP 파일에 넣는 것입니다.

사람들은 때때로 매크로 및/또는 전처리 조건을 사용하여 헤더에 정의를 넣어 한 편집 장치에서만 객체 또는 기능을 정의합니다. 그러나 정의를 .cpp 파일에 넣는 것이 일반적으로 (그리고 확실히 이해하기 쉬운) 더 쉽습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top