IOCP 구축을 위해선 IOCP 객체를 생성해야 하는데, CreateIoCompletionPort() 함수로 생성 가능하다.
그런데 이 함수의 인자 중 ULONG_PTR CompletionKey
가 있는데, 이 값은 IOCP 객체를 처음 생성할 때에는 불필요한 값이고 타입이 ULONG_PTR
으로 포인터 타입으로 보여, 모던한 느낌을 주고자 아래와 같이 nullptr
를 대입하려 했다.
// IOCP 생성
mh_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, nullptr, m_threadCount);
그런데 컴파일 에러가 발생하며 오류를 확인했다.
이유는 ULONG_PTR
타입이 포인터가 아니어서 nullptr
를 대입할 수가 없던 것!
그럼에도 모던하게~ 해보고자 코드를 아래와 같이 고쳐보았다.
mh_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, reinterpret_cast<ULONG_PTR>(nullptr), m_threadCount);
그런데 이게 잘 될까?
**nullptr의 동작 원리는 ‘포인터 타입에 대한 암시적 캐스팅을 통한 0의 전달’**이다. reinterpret_cast
를 하면 객체를 암시적 형변환 하지 않고, 메모리의 값을 그대로 사용하여 캐스팅할 수 있다. → 포인터나 참조 등의 데이터를 다른 타입으로 강제로 변환할 때 사용.
결국 nullptr
를 reinterpret_cast
하려고 하면, 그 값이 0
으로 형변환이 될까?
https://en.cppreference.com/w/cpp/language/reinterpret_cast
위의 공식 문서에 명시된 내용으로 확인해보니… 된다.
4) Any value of type std::nullptr_t, including nullptr can be converted to any integral type as if it were (void)0*, but no value, not even nullptr can be converted to std::nullptr_t: static_cast should be used for that purpose.
즉, reinterpret_cast<int>(nullptr)
같은 코드를 짜면, 0이 출력될 것이다.
아래의 코드 작성 및 검증으로 0으로 형변환 됨을 확인했다.