2012-04-09 3 views
1

나는 최근에 "extern"키워드의 사용이 적극 권장됨을 알게되었습니다."extern"키워드없이 헤더 파일에 변수를 선언 할 때 단점이 있습니까?

을 main.c :

#include "main.h" 
#include "function.h" 

int main(void){ 
    globalvariable = 0; 

    testfunction(); 
    return 0; 
} 

main.h :

#ifndef MAIN_H_ 
#define MAIN_H_ 

int globalvariable; 

#endif /* MAIN_H_ */ 

따라서 나는 현재 (통근없는) 방식에 문제가 아무것도 내가 헤더 파일을 사용할 수있는 경우 궁금해하기 시작했다 function.c :

#include "main.h" 
#include "function.h" 

void testfunction(){ 
    globalvariable++; 
    return; 
} 

function.h :

#ifndef FUNCTION_H_ 
#define FUNCTION_H_ 

void testfunction(void); 

#endif /* FUNCTION_H_ */ 

따라서 전역 변수에 액세스해야하는 모든 새 소스 파일에는 main.h가 포함되어야합니다.

이 방법의 한 가지 명백한 단점은 배열입니다. {element0, element1, ...} 형식을 사용하여 선언 된 배열에 값을 할당 할 수 없습니다.

덧붙여서 글로벌 변수에 0의 초기 값을 지정하면 그 시점에서 정의 할 수 있습니까? 아니면 이전에 할당 된 메모리입니까?

또한 내가 사용하는 공식적인 용어가 있습니까?

+0

'extern' 키워드는 권장되지 않습니다. 절대적으로해야 할 때만 사용해야합니다. –

+0

http://stackoverflow.com/questions/1433204/what-are-extern-variables-in-c – cnicutar

+0

[글로벌 변수가 잘못되었습니다.] (http://c2.com/cgi/wiki?GlobalVariablesAreBad). –

답변

2

나는 방법에 대해 당신이 "구현에 의존 행동이"사용하고 알고있는 유일한 공식 용어 임에도 불구하고 대부분의 컴파일러는 코드를 받아 들일 수 있도록

유닉스 시스템 그러나 역사적으로,이 사용을 할 수 있습니다. 다른 컴파일러 (또는 동일한 컴파일러의 다른 버전)를 사용하여 빌드를 시작하면 해당 메소드로 모든 종류의 문제가 발생합니다.일부는 링커 오류를 발생 시키지만 일부는이를 받아들입니다 (정확히 어떻게 해석 될지는 확실하지 않지만). 컴파일러가 예측 가능한 방식으로 해석 할 수있는보다 표준적인 접근 방법을 채택하는 것이 좋습니다.

변수에 대한 정의은 .c 파일에 있어야합니다. 다른 .c 파일에서 해당 변수에 액세스하려면 선언 헤더에 추가하십시오. 이 기술은 표준 C이며 모든 컴파일러에서 예측 가능하게 해석됩니다.

할당 질문에 답하기 위해 프로그램이 실행되기 전에 모든 전역에 대한 메모리가 할당됩니다. 전역 변수는 절대로 실행되지 않는 코드의 하위 섹션에서만 사용되는 경우에도 공간을 차지합니다. globalvariable = 0; 행은 실제로 변수 값을 제공하지 않습니다. C 컴파일러는 프로그램이로드 될 때 모든 초기화되지 않은 전역 변수가 자동으로 0으로 초기화되도록합니다. 코드에서 기술적으로 변수의 값을 다시 지정합니다. 전역을 특정 값으로 초기화하려면 int globalvariable = 42;과 같이 정의에 이니셜 라이저를 추가하십시오.

+0

이 답변과 "R .."사이에 찢겨졌습니다. 이 원본은 원래 게시물의 모든 부분에 응답하기 때문에 나옵니다. – SharpHawk

1

코드의 단점은 아마도 링커 오류가 발생한다는 것입니다.


1. 1

은 "아마도"다른 툴체인의 전체 무리에 코드를 구축하는 개념을 기반으로합니다.

+0

링커 오류가 발생하면 계속 이런 식으로 작업을 계속한다고 생각합니까? – SharpHawk

+0

@SharpHawk : MSVC에서 해봤습니까? –

+0

아니요, AVR Studio 5에서만 사용했습니다 (끔찍한 프로그램 임). – SharpHawk

1

이 문제는 프로그램을 연결하려고 할 때 여러 정의 때문에 연결 오류가 발생할 수 있다는 것입니다. 구현 정의 된 동작에 의존합니다. 구현은 복제 정의를 모두 하나의 객체를 참조하는 것으로 처리 할 수 ​​있지만 필수는 아닙니다.

2
extern int globalvariable; 

선언

int globalvariable; 

선언하고 임시 정의 모두 인에게이다.

C에서는 동일한 변수가 여러 정의를 가질 수 없으며 두 개 이상의 번역 단위에 포함 된 헤더 파일에서 후자를 사용하는 경우 이러한 오류가 발생합니다. 그것은 잘못된 C.

+0

두 개 이상의 번역 단위에 포함 된 헤더 파일에서 후자를 사용한다는 것은 무엇을 의미합니까? 여러 소스 파일에 헤더 파일 수를 포함 시키면됩니까? 그렇다면 정확히 내가하고있는 일이고, 마지막 줄에 언급했듯이 컴파일러는 불평하지 않습니다. 사실, 경고조차 내지 않습니다. – SharpHawk

+0

오른쪽. 각 번역 단위가 유효하기 때문에 컴파일러는 불평 할 수 없습니다. 링커 만이 불평 할 수 있으며, 그렇게하지 않으면 유닉스에서 전통적이기 때문에 링커는 불평 할 수 있습니다. 여전히 유효한 C가 아니며 원하는대로하지 못합니다. (다른 번역 단위에서 정의 된 변수에 액세스하려고한다고 선언하는 대신 링크 타임에 변수의 여러 정의를 하나의 변수로 축소합니다.) –

0

ANSI C 표준은 외부 링크이다

객체 식별자 선언이 파일 스코프가

및 없이 스토리지 클래스 지정자를 말한다.

관련 문제