문제

두 파일로 구성된 C 프로그램을 고려하십시오.

F1.C :

int x;

f2.c :

int x=2;

제 6.9.2 항에 대한 나의 읽기 C99 표준 이 프로그램은 거부해야한다는 것입니다. 6.9.2의 해석에서 변수 x 잠정적으로 정의되어 있습니다 f1.c, 그러나이 잠정적 인 정의는 번역 단위의 끝에서 실제 정의가되므로 (내 의견으로는) 마치 마치 f1.c 정의를 포함했습니다 int x=0;.

모든 컴파일러 (그리고 중요한 링커)를 사용하면 시도 할 수 있었지만 이것이 일어나지 않습니다. 내가 시도한 모든 컴파일 플랫폼은 위의 두 파일과 값을 연결합니다. x 두 파일 모두에서 2입니다.

우연히 발생하거나 표준이 요구하는 것 외에도 제공하는 "쉬운"기능으로 이런 일이 발생합니다. 당신이 그것에 대해 생각한다면, 그것은 명시 적으로 초기화 된 사람들과는 달리 초기화가없는 글로벌 변수에 대한 링커에 특별한 지원이 있음을 의미합니다. 누군가 어쨌든 Fortran을 컴파일하는 데 링커 기능이 필요할 수 있다고 말했습니다. 그것은 합리적인 설명 일 것입니다.

이것에 대한 생각이 있습니까? 표준에 대한 다른 해석? 어떤 파일의 플랫폼 이름 f1.c 그리고 f2.c 함께 연결되기를 거부합니까?

참고 : 이는 정적 분석의 맥락에서 질문이 발생하기 때문에 중요합니다. 두 파일이 일부 플랫폼에서 링크되지 않으면 분석기가 불만을 제기해야하지만 모든 컴파일 플랫폼이 수락하면 경고 할 이유가 없습니다.

도움이 되었습니까?

해결책

또한보십시오 c의 외부 변수는 무엇입니까?. 이것은 유익한 부록 J의 C 표준에 공통 확장으로 언급됩니다.

J.5.11 다중 외부 정의

키워드의 명시 적 사용 유무에 관계없이 객체의 식별자에 대한 외부 정의가 하나 이상있을 수 있습니다. 정의가 동의하지 않거나 하나 이상의 초기화되면 동작은 정의되지 않습니다 (6.9.2).

경고

@litb가 여기에서 지적하고 상호 참조 된 질문에 대한 나의 대답에 언급 된 바와 같이, 글로벌 변수에 대한 여러 정의를 사용하면 정의되지 않은 동작으로 이어지는 것은 "무엇이든 일어날 수있다"고 말하는 표준의 방법입니다. 일어날 수있는 일 중 하나는 프로그램이 예상대로 작동한다는 것입니다. 그리고 J.5.11은 대략 "당신은 자격이있는 것보다 더 자주 운이 좋을 것"이라고 말합니다. 그러나 명시 적 '외부'키워드가 있거나없는 외부 변수의 여러 정의에 의존하는 프로그램은 엄격하게 준수하는 프로그램이 아니며 어디에서나 작동하는 것을 보장하지 않습니다. 동등하게 : 그것은 a를 포함합니다 벌레 스스로를 보여줄 수도 있고 아닐 수도 있습니다.

다른 팁

변수가 한 번만 초기화되는 한 변수를 여러 번 정의하는 것이 허용되는 표준에 "공통 확장"이라고 불리는 것이 있습니다. 보다 http://c-faq.com/decl/decldef.html

링크 된 페이지에 따르면 이것이 UNIX 플랫폼과 관련이 있다고 말합니다. C89와 C99와 동일하다고 생각합니다. 어쩌면 더 많은 컴파일러가 일종의 Defacto 표준을 형성하기 위해 채택했을 수도 있습니다. 흥미로운.

이것은 olovb의 의견에 대한 나의 대답을 명확히하기위한 것입니다.

"int x;"에서 컴파일 된 객체 파일의 NM 출력. 이 플랫폼에서 기호는 '_'로 선정됩니다. 즉, 변수 x는 _x로 나타납니다.

00000000 T _main
         U _unknown
00000004 C _x
         U dyld_stub_binding_helper

"int x = 1"에서 컴파일 된 객체 파일의 NM 출력

00000000 T _main
         U _unknown
000000a0 D _x
         U dyld_stub_binding_helper

"int x = 0"에서 컴파일 된 객체 파일의 NM 출력;

00000000 T _main
         U _unknown
000000a0 D _x
         U dyld_stub_binding_helper

"extern int x"에서 컴파일 된 객체 파일의 NM 출력;

00000000 T _main
         U _unknown
         U dyld_stub_binding_helper

편집 : "extern int x"에서 컴파일 된 객체 파일의 NM 출력; 여기서 X는 실제로 함수 중 하나에서 사용됩니다.

00000000 T _main
         U _unknown
         U _x
         U dyld_stub_binding_helper
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top