Abseil 개요 — Google이 std를 보완한 이유
한 줄 요약: Abseil은 Google이 사내 수억 줄의 C++ 코드를 떠받치기 위해 만든 라이브러리이고, std의 빈자리를 메우거나 std보다 빠른 구현을 제공하는 두 축으로 굴러간다.
#어떤 문제를 푸는가
C++ 표준은 천천히 움직인다. 위원회가 합의에 도달하는 데 수년이 걸리고, 컴파일러가 지원하는 데 또 수년이 걸린다. 그동안 production 코드베이스는 멈춰 있을 수 없다. Google은 사내에서 표준에 들어갈 만한 기능을 먼저 만들어 쓰고, 표준화가 확정되면 std로 옮겨가는 식으로 움직였다. Abseil은 그 사내 결과물을 외부에 공개한 것이다.
세 가지 빈자리가 있다.
- 표준에 아직 없는 기능 — C++17 이전의
string_view,optional, C++20 이전의span같은 polyfill. - 표준에 있지만 느리거나 어색한 구현 —
unordered_map의 노드 기반 설계 대신 Swiss table 기반flat_hash_map. - 표준에 들어갈 가능성이 없는 도메인 —
absl::Status,absl::Time,absl::Flag같이 Google의 production 패턴에 특화된 도구.
Abseil은 이 셋을 한 우산 아래 묶어 제공한다.
#무엇이 들어 있는가
13개의 sub-library가 있다. 굵직한 것만 꼽으면 다음과 같다.
| 영역 | 헤더 | 대표 타입/함수 |
|---|---|---|
| 기반 | absl/base/* | ABSL_PREDICT_TRUE, ABSL_ATTRIBUTE_*, raw_logging |
| 에러 처리 | absl/status/* | absl::Status, absl::StatusOr<T> |
| 문자열 | absl/strings/* | absl::StrCat, absl::StrSplit, absl::string_view |
| 컨테이너 | absl/container/* | absl::flat_hash_map, absl::btree_map, absl::InlinedVector |
| 동기화 | absl/synchronization/* | absl::Mutex, absl::Notification |
| 시간 | absl/time/* | absl::Time, absl::Duration, absl::CivilDay |
| 수치/타입 | absl/numeric/*, absl/types/* | absl::int128, absl::optional, absl::variant |
| 로깅 | absl/log/* | LOG(INFO), CHECK, VLOG |
| 플래그 | absl/flags/* | ABSL_FLAG, absl::ParseCommandLine |
#짧은 맛보기
#include "absl/status/statusor.h"#include "absl/strings/str_cat.h"#include "absl/container/flat_hash_map.h"#include "absl/time/clock.h"
absl::StatusOr<int> ParseAge(absl::string_view s) { int v; if (!absl::SimpleAtoi(s, &v)) { return absl::InvalidArgumentError( absl::StrCat("not a number: ", s)); } if (v < 0 || v > 200) { return absl::OutOfRangeError(absl::StrCat("age out of range: ", v)); } return v;}
void Demo() { absl::flat_hash_map<std::string, int> ages; absl::Time start = absl::Now();
if (auto age = ParseAge("42"); age.ok()) { ages["alice"] = *age; }
absl::Duration elapsed = absl::Now() - start; LOG(INFO) << "took " << elapsed;}여기서 보이는 패턴은 시리즈 전반에 반복된다. exception을 던지지 않고 StatusOr로 결과를 감싼다. 문자열 합치기는 StrCat으로 단일 할당에 끝낸다. 시간은 Duration이라는 강타입으로 다룬다.
#왜 또 다른 라이브러리인가
흔히 받는 질문이다. 답은 표준 위원회의 속도와 Google의 production 요구 사이의 간극에 있다.
- 표준은
std::unordered_map을 바꿀 수 없다. ABI 안정성 때문에 노드 기반 구현이 박제되어 있다. Google은 더 빠른 해시맵이 필요했고, 새 타입으로 만드는 수밖에 없었다. - 표준의
std::optional<T&>은 끝내 합의되지 않았다. Abseil은 자체absl::optional을 가지고 있지만 reference에 대한 합의는 마찬가지로 보류 중이다. - exception을 쓰지 않는 코드베이스에서 에러를 반환하는 표준 방식은 빈약하다.
std::error_code는 너무 가볍고, exception은 금지. 그 자리에absl::Status가 들어간다.
#std와의 관계
Abseil은 std를 대체하지 않는다. 보완한다. 같은 코드베이스에서 둘이 공존하는 것이 정상이다.
// std와 absl을 섞어 쓰는 일상적 코드std::vector<absl::string_view> tokens = absl::StrSplit(line, ',', absl::SkipEmpty());
std::unique_ptr<Worker> w = std::make_unique<Worker>();absl::StatusOr<int> n = w->Process(tokens);선택의 일반 원칙은 다음과 같다.
| 상황 | 권장 |
|---|---|
| std 버전이 충분히 빠르고 표준에 있음 | std (std::optional on C++17+) |
| std 버전이 느리거나 어색함 | absl (absl::flat_hash_map) |
| 표준에 없음 | absl (absl::Status, absl::Time) |
| 컴파일러 지원 폴리필 | 표준 도달 후 std로 마이그레이션 |
#두 가지 릴리스 모드
Abseil은 두 모드로 배포된다.
- HEAD — main 브랜치를 직접 추적. Google 사내가 이 모델로 산다. “Live at Head” 철학.
- LTS — 1년에 두 번 정도 끊는 long-term snapshot. 외부 패키지 매니저(vcpkg, Conan)는 LTS만 다룬다.
이 둘의 차이는 1-04에서 자세히 다룬다. 일단은 “사내는 HEAD, 사외는 LTS”라고 기억해두면 충분하다.
#ABI 정책
Abseil의 ABI 정책은 한 줄로 요약된다.
같은 빌드 단위 안에서만 ABI 호환을 보장한다.
Abseil로 빌드한 두 정적 라이브러리를 다른 플래그로 컴파일해서 같은 실행 파일에 링크하면 동작이 깨질 수 있다. ODR violation을 막기 위해 inline namespace로 빌드 옵션을 인코딩하는 메커니즘이 들어 있다. 자세한 내용은 Part 1-05: Versioning & ABI 호환성에서 다룬다.
이 정책은 단일 실행 파일을 통째로 빌드하는 Google 사내 monorepo 모델에 최적화되어 있다. 외부 사용자에게는 약간의 함정이 있다.
#빌드 시스템
Abseil은 Bazel-first다. CMake는 second-class지만 LTS 릴리스에 함께 제공된다.
# Bazel — WORKSPACE 또는 MODULE.bazelhttp_archive( name = "com_google_absl", sha256 = "...", strip_prefix = "abseil-cpp-20240722.0", urls = ["https://github.com/abseil/abseil-cpp/releases/download/20240722.0/abseil-cpp-20240722.0.tar.gz"],)# CMake — FetchContentinclude(FetchContent)FetchContent_Declare( absl GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git GIT_TAG 20240722.0)FetchContent_MakeAvailable(absl)
target_link_libraries(my_app PRIVATE absl::strings absl::status)Bazel과 CMake 양쪽의 차이는 1-03에서 자세히 다룬다.
#이 시리즈를 읽는 법
세 가지 동선이 있다.
- production 코드를 읽고 리뷰하는 사람 — Part 3 (Status) → Part 4 (Strings) → Part 5 (Container) 순서. 가장 자주 마주치는 세 영역.
- 시스템 코드를 쓰는 사람 — Part 2 (Base · Meta · Memory)를 먼저. macro와 attribute로 portability를 확보하는 도구가 모여 있다.
- 마이그레이션 담당자 — Part 13 (Code Review Patterns)을 먼저 훑고, 필요한 모듈만 깊이 들어가는 방식.
이 시리즈는 사용법이 아니라 왜 이 모양인가에 비중을 둔다. cppreference처럼 API를 나열하지 않고, code review에서 “이걸 쓰면 안 되는 이유”가 무엇인지를 함께 본다.
#정리
- Abseil은 Google 사내 라이브러리의 오픈소스 부분 집합이고, std의 빈자리를 메우거나 std보다 빠른 구현을 제공한다.
- 13개 sub-library로 구성되며 Status, Strings, Container가 가장 자주 마주친다.
- std와 공존하는 것이 정상이고, 선택 기준은 “표준에 있는가, 충분히 빠른가” 두 가지로 단순화할 수 있다.
- HEAD와 LTS 두 모드가 있고, ABI 호환은 단일 빌드 단위 안에서만 보장된다.
- Bazel이 first-class, CMake가 second-class.
#다음 편
Part 1-02에서는 Abseil의 설계 철학을 본다. “std 호환 + 추가 기능”이라는 슬로건이 실제로는 어떤 트레이드오프 위에 서 있는지, header-only로 만들 수 없는 이유가 무엇인지 다룬다.
#관련 항목
Abseil Code Review · 2 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 Code Review — Google production-grade C++ 라이브러리 분석
Google이 만든 Abseil C++ 라이브러리를 code review의 시선으로 읽는다. std를 보완하는 industrial-grade 도구의 설계 의도와 사용 패턴을 13 Parts 68편으로 살펴본다.
같은 시리즈에서 이어 읽기
absl::PeriodicSampler — 적응형 샘플링·jitter 회피
absl::profiling_internal::PeriodicSampler — sampling rate를 동적으로 조정, geometric distribution으로 jitter 회피. 메모리 할당 추적·profiling 인프라의 기반.
같은 시리즈에서 이어 읽기
absl::ComputeCrc32c — 하드웨어 가속 체크섬
absl::ComputeCrc32c — SSE4.2 CRC32, ARM CRC 명령어로 가속된 CRC32C 구현. iSCSI·Btrfs·protobuf에서 표준화된 무결성 검사.
같은 시리즈에서 이어 읽기