ABSL_FLAG 정의 분석
#매크로 한 줄로 flag 정의
#include "absl/flags/flag.h"
ABSL_FLAG(int32_t, port, 8080, "HTTP listen port");ABSL_FLAG(std::string, name, "world", "greeting target");ABSL_FLAG(absl::Duration, timeout, absl::Seconds(30), "request timeout");ABSL_FLAG(bool, verbose, false, "enable verbose logging");매크로 형식은 ABSL_FLAG(type, name, default, help). 컴파일 시 글로벌 변수 FLAGS_name이 생성되고 런타임에 Flag Registry에 자동 등록.
#접근 — GetFlag / SetFlag
int32_t port = absl::GetFlag(FLAGS_port);absl::Duration t = absl::GetFlag(FLAGS_timeout);
absl::SetFlag(&FLAGS_port, 9090);직접 FLAGS_port 변수에 접근하지 않는다. GetFlag/SetFlag를 통해야 thread-safe하다.
// 회피 — gflags 시절 관행if (FLAGS_verbose) { ... } // ❌ Abseil에서는 안 됨
// Goodif (absl::GetFlag(FLAGS_verbose)) { ... }ABSL_FLAG로 정의된 변수는 opaque holder 라 직접 읽기를 막아 둔다. 이는 런타임에 atomic 갱신을 보장하기 위함이다.
#지원 타입
기본 지원:
| 타입 | 예 |
|---|---|
bool, int{8,16,32,64}_t, uint{8,16,32,64}_t | ABSL_FLAG(int32_t, n, 0, "") |
float, double | ABSL_FLAG(double, rate, 1.0, "") |
std::string | ABSL_FLAG(std::string, name, "x", "") |
std::vector<std::string> | comma-separated |
absl::Duration | "30s", "500ms" |
absl::Time | RFC3339 |
absl::CivilSecond 등 | RFC3339 |
std::optional<T> | 값 또는 unset |
다른 타입은 AbslParseFlag/AbslUnparseFlag를 정의해 확장(다음 챕터).
#Duration / Time flag
ABSL_FLAG(absl::Duration, timeout, absl::Seconds(30), "Request timeout (e.g. 500ms, 5s, 1h)");ABSL_FLAG(absl::Time, deadline, absl::InfiniteFuture(), "Absolute deadline (RFC3339)");명령행에서 자연스러운 표기.
$ ./myapp --timeout=500ms --deadline=2026-05-25T20:00:00Zint seconds/int ms flag로 받지 말고 Duration flag를 쓴다(Part 7-01의 단위 안전과 같은 정신).
#—help 자동 생성
flag 등록 시 help 문자열 이 함께 보존된다.
$ ./myapp --help
Flags from myapp.cc: --port (HTTP listen port); default: 8080; --timeout (request timeout); default: 30s; --verbose (enable verbose logging); default: false;absl::ParseCommandLine이 --help를 본 즉시 출력 후 종료.
#ABSL_DECLARE_FLAG — 헤더에 선언
flag를 다른 파일에서도 읽으려면 헤더에 declare.
ABSL_DECLARE_FLAG(int32_t, port);ABSL_DECLARE_FLAG(absl::Duration, timeout);
// main.ccABSL_FLAG(int32_t, port, 8080, "HTTP port");ABSL_FLAG(absl::Duration, timeout, absl::Seconds(30), "timeout");declare는 extern과 동등. define은 한 곳에서만.
#scope — global
ABSL_FLAG는 전역 변수 다. namespace 안에 둘 수 없고, 클래스 멤버로도 불가.
// 회피namespace mylib {ABSL_FLAG(int, x, 0, ""); // ❌ 컴파일 에러}
class Foo { ABSL_FLAG(int, x, 0, ""); // ❌ 불가};
// Good — 파일 스코프 한정ABSL_FLAG(int, x, 0, "");namespace mylib {int Get() { return absl::GetFlag(FLAGS_x); }}이 제약 때문에 flag 이름이 전역 namespace를 공유 한다. 라이브러리는 prefix(mylib_x)를 두는 게 좋다.
#의존성 주입 vs flag
GetFlag 호출이 코드 곳곳에 흩어지면 테스트가 어렵다. 권장 패턴:
// 회피void HandleRequest() { if (absl::GetFlag(FLAGS_timeout) < absl::Seconds(1)) { ... } // ❌ 직접 호출}
// Good — 구조체로 캡슐화struct Config { absl::Duration timeout; int32_t port;};Config LoadConfig() { return { .timeout = absl::GetFlag(FLAGS_timeout), .port = absl::GetFlag(FLAGS_port), };}
void HandleRequest(const Config& cfg) { if (cfg.timeout < absl::Seconds(1)) { ... }}flag는 경계 한 곳에서 읽고, 그 결과를 구조체로 전달. 테스트는 구조체만 만들면 끝.
#작은 예시 — 서버 부팅
ABSL_FLAG(int32_t, port, 8080, "Listen port");ABSL_FLAG(std::string, host, "0.0.0.0", "Bind address");ABSL_FLAG(absl::Duration, shutdown_grace, absl::Seconds(10), "Grace period for in-flight requests on SIGTERM");ABSL_FLAG(std::vector<std::string>, allowed_origins, {}, "CORS allowed origins (comma-separated)");
int main(int argc, char** argv) { absl::ParseCommandLine(argc, argv); absl::InitializeLog();
Config cfg{ .port = absl::GetFlag(FLAGS_port), .host = absl::GetFlag(FLAGS_host), .grace = absl::GetFlag(FLAGS_shutdown_grace), .origins = absl::GetFlag(FLAGS_allowed_origins), };
LOG(INFO) << "starting on " << cfg.host << ":" << cfg.port; RunServer(cfg); return 0;}$ ./server --port=9090 --shutdown_grace=30s --allowed_origins=a.com,b.com#회피 패턴
// 회피 — int로 시간 표현ABSL_FLAG(int, timeout_ms, 5000, "timeout in ms");
// Good — DurationABSL_FLAG(absl::Duration, timeout, absl::Seconds(5), "request timeout");// 회피 — 매 호출 GetFlag (atomic load 누적)for (int i = 0; i < kHotLoop; ++i) { if (absl::GetFlag(FLAGS_verbose)) Log(...); // ❌ hot path}
// Good — 시작 시 한 번 캡처const bool verbose = absl::GetFlag(FLAGS_verbose);for (int i = 0; i < kHotLoop; ++i) { if (verbose) Log(...);}// 회피 — 직접 변수 읽기int p = FLAGS_port; // ❌ 컴파일 안 됨 또는 비추천
// Goodint p = absl::GetFlag(FLAGS_port);#정리
ABSL_FLAG(type, name, default, help)한 줄로 type-safe flag.GetFlag(FLAGS_x)/SetFlag(&FLAGS_x, v)통해서만 접근. 직접 변수 읽기 금지.- 기본 지원 타입: 정수·실수·string·Duration·Time·vector<string>·optional 등.
- 전역 namespace 공유 — 라이브러리는 prefix 권장.
- production 코드는 경계 한 곳에서 GetFlag 호출, 결과는 구조체로 전달.
#다음 장 예고
Part 12-02: ParseCommandLine — flag 파싱.
#관련 항목
- Part 7-04: TimeZone —
--service_timezone같은 명시 TZ flag - Part 12-02: ParseCommandLine
- Part 12-03: Flag introspection / validation
- 원문 — Abseil Flags
Abseil Code Review · 64 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 ParseCommandLine 동작
absl::ParseCommandLine — argv를 flag로 분리하고 positional 인자를 돌려주는 단일 진입점.
같은 시리즈에서 이어 읽기
Abseil Flag introspection·validation
Flag validator, custom type AbslParseFlag/AbslUnparseFlag, introspection API — flag 정확성과 동적 조회.
같은 시리즈에서 이어 읽기
absl::PeriodicSampler — 적응형 샘플링·jitter 회피
absl::profiling_internal::PeriodicSampler — sampling rate를 동적으로 조정, geometric distribution으로 jitter 회피. 메모리 할당 추적·profiling 인프라의 기반.
같은 시리즈에서 이어 읽기