Abseil Conformance·Policy 분석
한 줄 요약: Abseil은 어떤 컴파일러·플랫폼·C++ 표준을 지원하는지 명문화된 정책을 가진다.
ABSL_DEPRECATED_IF_UNAVAILABLE같은 매크로는 미지원 환경에서 graceful degradation을 가능하게 한다.
#어떤 문제를 푸는가
라이브러리가 “어디서 동작하는가”는 사용자에게 가장 중요한 질문이다. 답이 모호하면 사용자는 매번 직접 확인해야 한다. Abseil은 명확한 conformance 정책을 가진다.
세 축이 있다.
- Tier 1 컴파일러 — 정식 지원. CI에서 매번 빌드·테스트.
- Tier 2 컴파일러 — Best-effort. 보고가 들어오면 고침.
- 그 외 — 동작 보장 없음.
#컴파일러·표준 지원 정책
#C++ 표준 최소 버전
C++14 이상
C++14가 최소다. C++11은 지원하지 않는다. C++14를 선택한 이유는 generic lambda, variable templates 같은 기능이 internal 구현에 필요하기 때문이다.
이 정책은 시간이 지나면서 올라간다. 2024년경 일부 sub-library에서 C++17 최소를 요구하기 시작했고, 곧 전체가 C++17 최소로 옮겨갈 예정이다.
#컴파일러 지원
| 컴파일러 | 최소 버전 | Tier |
|---|---|---|
| GCC | 7+ | 1 |
| Clang | 7+ | 1 |
| MSVC | 2017 (19.10+) | 1 |
| Apple Clang | Xcode 11+ | 1 |
| MinGW-w64 | 최신 | 2 |
| Intel ICX | 최신 | 2 |
| 그 외 | — | 미지원 |
Tier 1은 Google 사내 CI에서 매 commit마다 빌드된다. Tier 2는 사용자 보고에 의존한다.
#플랫폼 지원
| 플랫폼 | Tier |
|---|---|
| Linux (x86_64, aarch64) | 1 |
| macOS (x86_64, arm64) | 1 |
| Windows (x86_64) | 1 |
| iOS, Android | 1 (제한적) |
| FreeBSD, OpenBSD | 2 |
| WebAssembly | 2 |
| Bare-metal embedded | 미지원 |
embedded는 명시적으로 미지원이다. dynamic allocation을 가정하는 코드가 많고, raw_logging 같은 일부 예외를 제외하면 RTOS 환경에 적합하지 않다.
#ABSL_DEPRECATED_IF_UNAVAILABLE
마이그레이션을 부드럽게 해주는 매크로.
// absl/base/policy_checks.h에서 발췌#if SOME_FEATURE_AVAILABLE #define ABSL_DEPRECATED_IF_UNAVAILABLE(msg)#else #define ABSL_DEPRECATED_IF_UNAVAILABLE(msg) ABSL_DEPRECATED(msg)#endif
// 사용ABSL_DEPRECATED_IF_UNAVAILABLE("Will require C++17 in next LTS")absl::optional<int> Find(int key);특정 기능이 지원되는 환경에서는 deprecation 없이 동작하고, 지원되지 않는 환경에서만 deprecation 경고. 마이그레이션 시 일부 환경만 먼저 옮기는 패턴.
#ABSL_INTERNAL_C_PLUSPLUS — 표준 버전 감지
#if defined(_MSVC_LANG) #define ABSL_INTERNAL_C_PLUSPLUS _MSVC_LANG#else #define ABSL_INTERNAL_C_PLUSPLUS __cplusplus#endif
#if ABSL_INTERNAL_C_PLUSPLUS >= 201703L // C++17+#endif_MSVC_LANG vs __cplusplus의 차이를 흡수한다. MSVC는 /Zc:__cplusplus 옵션 없이는 __cplusplus가 199711L로 보고된다. _MSVC_LANG을 우선 확인하는 것이 정답.
#policy_checks.h — 컴파일 시점 검사
Abseil은 모든 컴파일에서 정책 위반을 잡는다.
// absl/base/policy_checks.h의 핵심#if defined(_MSVC_LANG) && _MSVC_LANG < 201402L #error "C++ versions less than C++14 are not supported."#elif defined(__cplusplus) && __cplusplus < 201402L #error "C++ versions less than C++14 are not supported."#endif
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 7 #error "Abseil requires GCC 7 or later."#endif지원하지 않는 환경에서 빌드하면 컴파일러 에러로 명확히 거부한다. silent 동작보다 명시적 거부가 낫다는 정책.
#표준 도달 시 마이그레이션
Abseil의 polyfill은 표준 도달 후 자동으로 std로 redirect할 수 있다.
#define ABSL_OPTION_USE_STD_OPTIONAL 2
// 의사 코드#if ABSL_OPTION_USE_STD_OPTIONAL == 2 // 자동 감지 #if ABSL_INTERNAL_C_PLUSPLUS >= 201703L && ABSL_HAVE_STD_OPTIONAL namespace absl { template <typename T> using optional = std::optional<T>; } #else // absl 자체 구현 #endif#elif ABSL_OPTION_USE_STD_OPTIONAL == 1 namespace absl { template <typename T> using optional = std::optional<T>; }#else // 항상 absl 자체 구현#endifabsl::optional이 std::optional의 alias가 될 수도, 자체 type일 수도 있다. 이 redirection은 ABI에 영향을 준다. (Part 1-05 참조)
#conformance 위반 사례
Abseil이 의도적으로 std를 따르지 않는 부분.
#exception 사용
Abseil은 -fno-exceptions 빌드를 지원한다. 따라서 일부 API는 throw가 아닌 LOG(FATAL) 또는 return-error를 쓴다.
// std::optional::value()는 bad_optional_access throwauto v = opt.value(); // throw if empty
// absl::optional은 exception 활성화 시에만 throw// -fno-exceptions에서는 LOG(FATAL)auto v = abs_opt.value();#initializer_list constexpr
// C++11: constexpr 제약 많음// C++14: constexpr 완화
// Abseil은 C++14 가정 — constexpr 적극 활용constexpr absl::Span<int> s(arr);#RTTI 사용
-fno-rtti 빌드를 지원하므로 typeid, dynamic_cast를 내부에서 쓰지 않는다. 일부 디버그 기능(stack trace decoding)은 RTTI 비활성화 시 제한된다.
#코드 리뷰 포인트
// 회피 — 컴파일러 분기를 직접#if defined(__GNUC__) && __GNUC__ < 7 // ...#endif
// Good — Abseil 정책 검사를 신뢰#include "absl/base/policy_checks.h" // 미지원 환경이면 #error// 회피 — __cplusplus만 검사#if __cplusplus >= 201703L // MSVC에서 동작 안 함
// Good — Abseil의 통일된 매크로#if ABSL_INTERNAL_C_PLUSPLUS >= 201703L// 회피 — Tier 외 컴파일러 동작 가정// "MinGW에서 잘 돌 거야" — Tier 2이므로 보장 없음// 회사 정책상 MinGW 필수라면, 자체 CI 추가하고 deviation 문서화리뷰에서:
- 타깃 컴파일러가 Tier 1인가 — 아니라면 자체 CI 필요.
- C++ 표준 버전 감지가 정확한가 —
_MSVC_LANG처리. - policy violation이 명시적으로 처리되는가 — silent 통과 금지.
#자주 보는 안티패턴
// 회피 — Abseil이 지원 안 한다고 명시한 환경에서 쓰기// bare-metal RTOS에 absl::flat_hash_map을 넣음// — heap 할당, exception, 큰 코드 크기. 보통 부적합.// 회피 — C++ 표준 버전을 빌드 시스템과 헤더에서 따로 지정// CMakeLists.txt: CMAKE_CXX_STANDARD 17// 헤더 안: #if __cplusplus >= 201402L (C++14만 가정)// 일관성 없음. 한 곳에서 결정.// 회피 — exception을 가정한 API를 -fno-exceptions에서 사용try { auto v = opt.value();} catch (const std::bad_optional_access&) { // -fno-exceptions에서는 도달 안 함. LOG(FATAL)로 죽음.}
// Good — bool check 우선if (opt.has_value()) { auto v = *opt;}#정리
- Abseil의 conformance는 Tier 1 (GCC 7+, Clang 7+, MSVC 2017+, Apple Clang 11+) 기반.
- C++14 최소, 곧 C++17로 올라갈 예정.
- 정책 위반은
policy_checks.h에서 컴파일 에러로 거부. _MSVC_LANG과__cplusplus차이는ABSL_INTERNAL_C_PLUSPLUS로 흡수.- bare-metal embedded는 명시적으로 미지원.
#다음 편
Part 2-06에서 memory utilities를 본다. absl::AllocatorTraits 같은 도구가 표준 allocator를 어떻게 보완하는지, make_unique 같은 polyfill의 위치는 어디인지.
#관련 항목
Abseil Code Review · 11 of 79
- 1 Abseil Code Review — Google production-grade C++ 라이브러리 분석
- 2 Abseil 개요 — Google이 std를 보완한 이유
- 3 Abseil 설계 철학 — std 호환과 추가 기능의 균형
- 4 Abseil 빌드와 의존성 — Bazel vs CMake
- 5 Abseil LTS vs HEAD 릴리스 모델 분석
- 6 Abseil Versioning과 ABI 호환성 정책
- 7 Abseil 매크로 — ABSL_HAVE_*·ABSL_ATTRIBUTE_*
- 8 Abseil ABSL_PREDICT_TRUE/FALSE — branch hint
- 9 absl::LogSeverity — 로그 레벨 타입
- 10 Abseil type_traits — negation·conjunction·void_t
- 11 Abseil Conformance·Policy 분석
- 12 Abseil Memory utilities 분석
- 13 Abseil raw_logging — heap-free 로깅
- 14 Abseil thread_annotations — clang TSA 통합
- 15 absl::Status — exception-free error handling
- 16 absl::StatusOr<T> — 값 또는 에러
- 17 absl status_macros — ASSIGN_OR_RETURN·RETURN_IF_ERROR
- 18 absl::Status payload — 구조화된 에러 컨텍스트
- 19 absl::Status ↔ exception 변환 패턴
- 20 absl::string_view — non-owning 문자열 참조
- 21 absl::string_view 함정 — dangling·c_str·임시 객체
- 22 absl::StrCat — 가변 인자 문자열 연결과 AlphaNum
- 23 absl::StrSplit — Delimiter·Predicate·컨테이너 변환
- 24 absl::StrJoin — 컨테이너 결합과 Formatter
- 25 absl::StrFormat — type-safe printf·FormatSpec
- 26 Abseil ASCII 함수 — locale-free 분류·대소문자 변환
- 27 Abseil Escape — CEscape·HexEscape·Base64
- 28 absl::flat_hash_map — Swiss Table 기반 hash map
- 29 absl::flat_hash_set — set 버전 Swiss Table
- 30 absl::node_hash_map — stable pointer가 필요할 때
- 31 absl::btree_map — sorted·cache-friendly B-tree
- 32 absl::FixedArray — 런타임 크기 stack 배열
- 33 absl::InlinedVector — small buffer optimization
- 34 Abseil Swiss Table internals — control byte·SIMD probing
- 35 absl::Mutex — reader-writer·fairness·deadlock 검출
- 36 absl::Mutex Conditional Critical Section — Await로 cv 없애기
- 37 absl::Notification — once-only signal
- 38 absl::BlockingCounter·Barrier — 다중 thread 조율
- 39 absl::Mutex annotations — clang thread-safety로 race를 컴파일 타임에
- 40 absl::Time·Duration 분석 — 단단한 type
- 41 absl::Time Format·Parse
- 42 absl::CivilTime 분석
- 43 absl::time_zone 분석
- 44 absl::Time mocking — 테스트 친화 시간
- 45 absl::BitGen — 모던 난수 생성기
- 46 Abseil Random Distributions — Uniform·Exponential
- 47 Abseil Mocking Random — 테스트 결정성
- 48 Abseil Random Seeding·Entropy
- 49 absl::int128·uint128 분석
- 50 absl::bits — popcount·countl_zero
- 51 absl::optional vs std::optional
- 52 absl::variant 분석
- 53 absl::span 분석
- 54 absl::any 분석
- 55 absl::compare — three-way 비교
- 56 Abseil utility — apply·in_place
- 57 Abseil AbslHashValue 분석
- 58 Abseil HashState chaining
- 59 Abseil Custom hashable 구현
- 60 Abseil LOG·VLOG·CHECK 분석
- 61 Abseil LogSink 분석
- 62 Abseil LogEntry·structured logging
- 63 Abseil Stack trace·failure_signal_handler
- 64 ABSL_FLAG 정의 분석
- 65 Abseil ParseCommandLine 동작
- 66 Abseil Flag introspection·validation
- 67 Google 스타일의 Abseil 사용 패턴
- 68 Abseil 자주 보는 anti-pattern
- 69 std → absl 마이그레이션 전략
- 70 absl::Cleanup — 함수 종료 시 실행 보장
- 71 Abseil algorithm container 확장 — c_sort·c_find_if·c_count_if
- 72 absl::function_ref와 any_invocable — 함수 객체 전달의 두 축
- 73 absl::bind_front와 Overload — 함수 객체 보조 도구
- 74 absl::Cord — 분산 시스템용 대용량 문자열
- 75 absl::from_chars·SimpleAtoi — 빠른 숫자 변환
- 76 absl::Cord vs std::string — 선택 기준과 메모리 프로파일
- 77 absl::GetStackTrace와 Symbolize — crash 시 readable stack
- 78 absl::ComputeCrc32c — 하드웨어 가속 체크섬
- 79 absl::PeriodicSampler — 적응형 샘플링·jitter 회피
관련 글
Abseil raw_logging — heap-free 로깅
Part 2-07: raw_logging — heap, exception, mutex 없이 동작하는 로깅. signal handler, ASan early init, OOM 경로.
같은 시리즈에서 이어 읽기
Abseil Memory utilities 분석
Part 2-06: absl::memory — make_unique polyfill, allocator_traits, RawPtr, uninitialized helpers.
같은 시리즈에서 이어 읽기
absl::LogSeverity — 로그 레벨 타입
Part 2-03: absl::LogSeverity — INFO/WARNING/ERROR/FATAL 4단계, NormalizeLogSeverity, 외부 시스템 연동.
같은 시리즈에서 이어 읽기