스택큐힙리스트

왜 C++17에서 "정의되지 않은 외부 변수"가 링커 오류를 일으키지 않는 걸까요? 본문

카테고리 없음

왜 C++17에서 "정의되지 않은 외부 변수"가 링커 오류를 일으키지 않는 걸까요?

스택큐힙리스트 2023. 12. 5. 00:21
반응형

나는 C++17 컴파일러 (Coliru)에서 다음 프로그램을 컴파일하고 실행했습니다. 이 프로그램에서 extern 변수를 선언했지만 정의하지 않았습니다. 그러나 컴파일러는 링커 에러를 표시하지 않습니다.


#include <iostream>
extern int i; // 선언만 함
int func()
{
if constexpr (true)
return 0;
else if (i)
return i;
else
return -1;
}
int main()
{
int ret = func();
std::cout<<Ret : <<ret<<std::endl;
}

왜 컴파일러가 링커 에러를 표시하지 않는 것일까요?

답변 1

변수가 odr-used되지 않기 때문에 그곳에 항상 사용할 수있는 constexpr if가 있습니다.


constexpr if의 한 가지 목적은 폐기 된 분기가 컴파일 될 필요조차없이 잘 구성되어있을 수 있다는 것입니다. 이것이 폐기 된 분기에 존재하지 않는 멤버 함수를 호출 할 수있는 방법입니다.

답변 2

왜 C++17에서 정의되지 않은 외부 변수는 링커 오류를 일으키지 않을까요?
C++ 언어에서 정의되지 않은 외부 변수는 프로그래밍 중 꽤 흔하게 발생할 수 있는 문제 중 하나입니다. 이 문제가 발생하면 컴파일러에서는 변수를 찾을 수 없다는 오류 메시지를 보여주게 됩니다. 그러나 C++17부터는 이러한 오류가 링커 오류를 일으키지 않는 경우가 있습니다. 그 이유에 대해 알아보겠습니다.
C++ 언어에서 정의되지 않은 외부 변수는 일반적으로 선언되었지만 정의되지 않은 변수를 의미합니다. 즉, 다른 소스파일에서 선언된 변수를 현재 소스파일에서 참조하고자 할 때 발생하는 문제입니다. 일반적으로 이러한 상황에서는 링커 오류가 발생하며, 링커는 정의되지 않은 변수를 해결할 수 없기 때문에 프로그램을 빌드할 수 없게 됩니다.
그러나 C++17에서는 정의되지 않은 외부 변수 에러가 링커 오류로 해석되지 않고, 해당 변수가 사용될 때 컴파일 오류로 처리됩니다. 이는 C++17에서 템플릿과 관련된 언어 기능이 업데이트되었기 때문입니다. C++17 이전에는 템플릿 인스턴스화에 사용되는 정의된 타입들의 외부 변수들은 링커 오류로 처리되었는데, 이는 컴파일 시간에 타입 정보를 알 수 있어야만 템플릿을 인스턴스화 할 수 있기 때문입니다.
그러나 C++17에서는 템플릿 인스턴스화가 포인터나 참조로 이루어지는 경우, 컴파일러가 실제 타입을 알아내지 못해도 템플릿 함수를 인스턴스화할 수 있도록 변경되었습니다. 따라서 C++17에서는 정의되지 않은 외부 변수가 발생하더라도 링커 오류가 아닌 컴파일 오류로 처리되며, 컴파일 시간에 타입에 대한 정보가 없을 때에도 템플릿을 인스턴스화할 수 있게 되었습니다.
결론적으로, C++17에서는 정의되지 않은 외부 변수가 링커 오류가 아닌 컴파일 오류로 처리되는데, 이는 템플릿의 인스턴스화 과정에 대한 언어 기능 업데이트로 인한 것입니다. 이러한 변경은 템플릿의 유연성과 사용 편의성을 증가시켜준다는 장점을 가지고 있습니다.

반응형
Comments