Chromium Chronicle #24: StrongAlias, IdType 및 TokenType

에피소드 24: 작성자: 루카스 안포로비츠, 워싱턴주 벨뷰 (2021년 8월)
이전 에피소드

아래 코드에서 버그를 찾을 수 있나요? 여기 보이는 바로 버그 코드 검토에서 어떻게 해야 할까요?

Token CreateToken(int command_data, int buffer_id);
...
auto token = CreateToken(GetCommandBufferId(), GetCommandData());

동일한 유형이 호환되지 않는 도메인의 값을 나타내는 경우도 있습니다. 이는 일반적으로 정수나 문자열과 같은 비특정 데이터 유형에서 발생합니다. 위의 예는 이로 인해 버그가 발생하는 이유를 보여줍니다. 다행히 Chromium의 //base를 사용하면 명시적이고 고유한 유형을 쉽게 도입할 수 있습니다.

#include "base/types/strong_alias.h"

// The first template argument of StrongAlias is a "tag" type.
// The "tag" type is used to distinguish between different
// StrongAlias types.
using CommandData = base::StrongAlias<class CommandDataTag, int>;
using CommandBufferId = base::StrongAlias<class CommandBufferIdTag, int>;

Token CreateToken(CommandData command_data, CommandBufferId buffer_id);

별도의 유형을 사용하면 가독성이 향상됩니다. 또한 StrongAlias는 컴파일 시간에 유형 혼동을 포착합니다.

test.cc:456:16: error: no matching function for call to 'CreateToken'
  auto token = CreateToken(GetCommandBufferId(), GetCommandData());
               ^~~~~~~~~~~
test.cc:123:7: note: candidate function not viable: no known conversion from
'StrongAlias<class CommandBufferIdTag, [...]>' to
'StrongAlias<class CommandDataTag, [...]>' for 1st argument
Token CreateToken(CommandData command_data, CommandBufferId buffer_id);
      ^

컴파일러는 유형이 호환되지 않음을 확인하고 '태그'가 다르기 때문에 있습니다. StrongAlias는 모든 유형을 '태그'로 허용합니다. 있습니다. 이 예에서는 'tag'가 유형은 어디에도 유형 정의가 필요하지 않습니다. 존재하지 않는 클래스의 인플레이스 포워드 선언은 괜찮습니다.

향후에는 구체적이지 않은 유형 (예: 부울, 정수, 문자열) 대신 다음 대안을 고려하세요.

  • int32_t를 식별자로 사용하는 대신 base::IdType32<TagType>를 사용합니다.
  • 구체적이지 않은 base::UnguessableToken 대신 base::TokenType<TagType>를 사용합니다.
  • 부울 대신 enum 클래스 사용 예를 들어 kForReload, true 대신 kNotForReload, false).
  • 기타 구체적이지 않은 유형을 base::StrongAlias<TagType, SomeWrappedType>로 바꿉니다.