Coding Memo
[에러?] the template instantiation context ~ 본문
일단은 해당 내용은 에러나 경고로 나타나지 않고, 단순히 output에서 나타난 일종의 메시지 이다.
the template instantiation context (the oldest one first) is 1> ...Session.cpp(49,23): 1> see reference to function template instantiation 'std::shared_ptr<_Ty> NetCore::make_shared<NetCore::SendBufferSegment,std::shared_ptr<NetCore::SendBuffer>,NetCore::_ubyte*&,const size_t&>(std::shared_ptr<NetCore::SendBuffer> &&,NetCore::_ubyte *&,const size_t &)' being compiled 1> with 1> [ 1> _Ty=NetCore::SendBufferSegment 1> ] 1> ...Memory.h(54,3): 1> see reference to function template instantiation 'Type *NetCore::xxnew<NetCore::SendBufferSegment,_Ty,NetCore::_ubyte*&,const size_t&>(_Ty &&,NetCore::_ubyte *&,const size_t &)' being compiled 1> with 1> [ 1> Type=NetCore::SendBufferSegment, 1> _Ty=std::shared_ptr<NetCore::SendBuffer> 1> ] |
해당 관련 코드이다.
template<typename Type, typename... Args>
[[nodiscard]] Type* xxnew(Args&&... args)
{
...
}
template<typename Type, typename... Args>
std::shared_ptr<Type> make_shared(Args&&... args)
{
return std::shared_ptr<Type>
{
xxnew<Type>(std::forward<Args>(args)...), xxdelete<Type>
};
}
// xxdelete는 동적할당 해제 함수에 해당
// SendBufferSegment 클래스 생성자
SendBufferSegment(std::shared_ptr<SendBuffer> buffer, unsigned char* bufferPos, unsigned int size)
: _size(size), _buffer(buffer), _bufferPos(bufferPos)
{
}
// Session에서의 코드
auto seg = NetCore::make_shared<SendBufferSegment>(TLS_SendBuffer->shared_from_this(), pos, size);
// TLS_SendBuffer는 std::shared_ptr<SendBuffer> 타입으로 thread_local
// make_shared는 std::make_shared와 동일한 기능 (사용자 정의 shared_ptr 생성)
// using _ubyte = unsigned char
// using uint32 = unsigned int
물론 위 내용이 나타났음에도, 프로그램은 정상적으로 컴파일되었고, 실행도 문제 없었다. 그러나 잠재적인 문제가 되거나, 내가 의도한 코드와 다르게 될 수도 있기 때문에 해결해보기로 했다.
SendBufferSegment에 대한 shared_ptr를 NetCore::make_shared()로 생성 시에 문제가 생기는 것으로 보인다.
하지만, 겉보기에는 문제도 없고, 컴파일러 경고나, 에러가 나타나지 않았고, 컴파일 및 실행에 전혀 지장이 없었다.
단순히, '컴파일 시에 ~~하게 했으니 확인바람~' 정도일려나?
몇 가지 이유를 생각해보았다.
1. SendBuffer의 shared_from_this() 문제
2. xxnew에서의 문제
3. SendBufferSegment의 생성자 문제
첫 번째 이유를 확인하기 위해 thread_local에 있는 TLS_SendBuffer 변수도 확인했고, shared_from_this를 호출하는 위치도 바꾸어 보았지만, 별 문제가 없었다.
두 번째는 다른 NetCore:make_shared()라 던가, NetCore::xxnew()가 제대로 작동하는 것으로 보아 문제가 없어보였고, xxnew 호출시에도 Args에 대한 타입도 제대로 전달되고 있었다.
마지막으로, SendBufferSegment 생성자의 정의와 이를 호출하는 코드를 좀 더 까다롭게 확인해보았다. 일단, 정답이 여기였다.
메시지 내용을 다시 되짚어보면,
see reference to function template instantiation 'std::shared_ptr<_Ty> NetCore::make_shared<NetCore::SendBufferSegment,std::shared_ptr<NetCore::SendBuffer>,NetCore::_ubyte*&,const size_t&>(std::shared_ptr<NetCore::SendBuffer> &&,NetCore::_ubyte *&,const size_t &)' being compiled
see reference to function template instantiation 'Type *NetCore::xxnew<NetCore::SendBufferSegment,_Ty,NetCore::_ubyte*&,const size_t&>(_Ty &&,NetCore::_ubyte *&,const size_t &)' being compiled
원래 코드에서는 Args의 3번째 타입으로 unsigned int(uint32)가 들어가서 해당 타입으로 템플릿 인스턴스화되어야 하는데, size_t라는 타입으로 인식되고 있는 것을 알 수 있었다.
실제 코드에서도 size라는 변수가 strlen()의 반환값인 size_t였다.
const auto size = strlen(buffer); // size는 size_t 타입(unsigned long long)
...
auto seg = NetCore::make_shared<SendBufferSegment>(TLS_SendBuffer->shared_from_this(), pos, size);
따라서 컴파일러는 이렇게 말하고 있다
SendBufferSegment의 shared_ptr를 만들때 호출되는 생성자의 템플릿의 원본은 Type=SendBufferSegment, Args=[std::shared_ptr<SendBuffer>, unsigned char*, unsigned int]인데, 너의 코드를 컴파일하다 보니까 Args에서 3번째 인수 타입이 unsigned int가 아니라 size_t인거 같다. 그래서 unsigned int로 하지 않고 size_t로 인스턴스를 생성했다. 다음 두 템플릿 함수로 컴파일 되었다:
NetCore::make_shared에서 Args의 3번째 타입을 size_t로,
NetCore::xxnew에서 Args의 3번째 타입을 size_t로.
(즉, 원래 버전(old version)의 인스턴스와 내가 컴파일한 인스턴스가 다르다.)
내 코드에서는 unsigned int와 size_t의 데이터 차이가 없기 때문에 딱히 문제가 없긴하지만, 좀 더 확실하게 하는 것이 좋다는 생각이 들었다. C++은 까다로운 언어다!
const uint32 size = static_cast<uint32>(strlen(buffer));
위와 같이 캐스팅하여 size의 값을 기존 타입인 uint32로 확실하게 지정하여, 해당 메시지가 더 이상 나타나지 않게 할 수 있었다.
아니면 explicit를 활용하여 암시적 형변환에 제한을 두어서 확실하게 코드를 짜는 방법도 있겠다!!
'Language > C++' 카테고리의 다른 글
[C++] Concurrent 우선순위 큐 (with lock) (0) | 2024.05.13 |
---|---|
const 포인터 캐스팅 (const_cast) (0) | 2024.05.02 |
[에러] 상속과 가상 함수 테이블(vtable)의 메모리 레이아웃 (1) | 2024.04.19 |
[메모] const 함수 유의사항 (C2665 에러 등) (0) | 2024.04.16 |
[Winsock] WSAEINVAL(10022) 에러 (ConnectEx) (0) | 2024.03.25 |