라이브러리 내부 요소에 대한 종속성 해결Fix your dependencies on library internals

Microsoft는 표준 라이브러리, 대부분의 C 런타임 라이브러리, 기타 여러 Visual Studio 버전의 Microsoft 라이브러리에 대한 소스 코드를 게시했습니다.Microsoft has published the source code for the Standard Library, most of the C Runtime Library, and other Microsoft libraries in many versions of Visual Studio. 소스 코드를 게시한 이유는 라이브러리 동작을 이해하고 코드를 디버그하는 데 도움을 주기 위해서입니다.The intent is to help you understand library behavior and to debug your code. 라이브러리 소스 코드 게시의 한 가지 부작용은 라이브러리 인터페이스의 일부가 아닌 내부 값, 데이터 구조 및 함수가 노출된다는 점입니다.One side-effect of publishing the library source code is that some internal values, data structures, and functions are exposed, even though they are not part of the library interface. 여기에는 일반적으로 두 개의 밑줄 또는 한 개의 밑줄 뒤에 한 개의 대문자로 시작되는 이름이 있습니다. 이것은 C++ 표준이 구현을 위해 예약하는 이름입니다.They usually have names that begin with two underscores, or an underscore followed by a capital letter, names that the C++ Standard reserves to implementations. 이러한 값, 구조 및 함수는 시간이 지나면서 라이브러리가 진화함에 따라 달라질 수 있는 구현 세부 사항이므로 여기에 지나치게 의존하지 않는 것이 좋습니다.These values, structures, and functions are implementation details that may change as the libraries evolve over time, and so we strongly recommend against taking any dependencies on them. 여기에 의존하는 경우에는 새 라이브러리 버전으로 코드를 마이그레이션할 때 문제가 생기거나 코드를 이동하지 못하게 될 위험이 있습니다.If you do, you risk non-portable code and issues when you try to migrate your code to new versions of the libraries.

대부분의 경우에는 Visual Studio의 각 릴리스에 대한 새로운 기능 또는 변경 내용 문서에서 라이브러리 내부 요소에 대한 변경 사항을 언급하지 않습니다.In most cases, the What's New or Breaking Changes document for each release of Visual Studio doesn't mention changes to library internals. 따라서 이러한 구현 정보에 의해 영향을 받지 않아야 합니다.After all, you're not supposed to be affected by these implementation details. 그러나 때로는 라이브러리 내부에서 볼 수 있는 일부 코드를 사용하고 싶을 때가 있을 것입니다.However, sometimes the temptation to use some code you can see inside the library is too great. 이 항목에서는 사용할 수 있는 CRT 또는 표준 라이브러리 내부 요소에 대한 종속성 및 코드를 업데이트하여 이러한 종속성을 제거함으로써 이동성을 높이거나 새 라이브러리 버전으로 마이그레이션하는 방법에 관해 설명합니다.This topic discusses dependencies on CRT or Standard Library internals you may have relied on, and how to update your code to remove those dependencies so you can make it more portable or migrate to new versions of the library.

_Hash_seq_Hash_seq

표준 라이브러리의 최신 버전에서는 일부 문자열 형식에 대해 std::hash를 구현하는 데 사용되는 내부 해시 함수 std::_Hash_seq(const unsigned char *, size_t)가 표시되었습니다.The internal hash function std::_Hash_seq(const unsigned char *, size_t), used to implement std::hash on some string types, was visible in recent versions of the Standard Library. 이 함수는 문자 시퀀스에 대해 FNV-1a 해시를 구현했습니다.This function implemented an FNV-1a hash on a character sequence.

이 종속성을 제거하는 방법은 두 가지입니다.To remove this dependency, you have a couple of options.

  • basic_string과 동일한 해시 코드 기계를 사용하여 순서가 지정되지 않은 컨테이너에 const char * 시퀀스를 설정하려면 std::string_view를 이용하는 std::hash 템플릿 오버로드를 사용하여 이동 가능한 방법으로 해당 해시 태그를 반환하면 됩니다.If your intent is to put a const char * sequence into an unordered container by using the same hash code machinery as basic_string, you can do that by using the std::hash template overload that takes a std::string_view, which returns that hash code in a portable way. 문자열 라이브러리 코드는 향후 FNV-1a 해시 사용에 의존할 수도 있고 아닐 수도 있으므로 특정 해시 알고리즘에 대한 종속성을 피하는 것이 가장 좋은 방법입니다.The string library code may or may not rely on use of an FNV-1a hash in the future, so this is the best way to avoid a dependency on a particular hash algorithm.

  • 임의의 메모리에 대해 FNV-1a 해시를 생성하려는 사용자를 위해 MIT 라이선스에 따라 독립 실행형 헤더 파일 fnv1a.hppVCSamples 리포지토리에 있는 GitHub에서 이 코드를 사용할 수 있도록 만들었습니다.If your intent is to generate an FNV-1a hash over arbitrary memory, we've made that code available on GitHub in the VCSamples repository in a stand-alone header file, fnv1a.hpp, under an MIT license. 사용자 편의를 위해 여기에도 복사본을 넣었습니다.We've also included a copy here for your convenience. 이 코드를 헤더 파일에 복사하고 영향을 받는 모든 코드에 헤더를 추가한 다음 _Hash_seq를 찾아 fnv1a_hash_bytes로 바꿀 수 있습니다.You can copy this code into a header file, add the header to any affected code, and then find and replace _Hash_seq by fnv1a_hash_bytes. 동일한 동작을 _Hash_seq에서 내부 구현으로 가져오게 됩니다.You'll get identical behavior to the internal implementation in _Hash_seq.

/*
VCSamples
Copyright (c) Microsoft Corporation
All rights reserved. 
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <stddef.h>

inline size_t fnv1a_hash_bytes(const unsigned char * first, size_t count) {
#if defined(_WIN64)
    static_assert(sizeof(size_t) == 8, "This code is for 64-bit size_t.");
    const size_t fnv_offset_basis = 14695981039346656037ULL;
    const size_t fnv_prime = 1099511628211ULL;

#else /* defined(_WIN64) */
    static_assert(sizeof(size_t) == 4, "This code is for 32-bit size_t.");
    const size_t fnv_offset_basis = 2166136261U;
    const size_t fnv_prime = 16777619U;
#endif /* defined(_WIN64) */

    size_t result = fnv_offset_basis;
    for (size_t next = 0; next < count; ++next)
        {   // fold in another byte
        result ^= (size_t)first[next];
        result *= fnv_prime;
        }
    return (result);
}

참고 항목See also

이전 버전의 Visual C++에서 프로젝트 업그레이드Upgrading Projects from Earlier Versions of Visual C++
잠재적인 업그레이드 문제 개요(Visual C++)Overview of potential upgrade issues (Visual C++)
코드를 유니버설 CRT로 업그레이드Upgrade your code to the Universal CRT