Abseil ParseCommandLine 동작
#한 줄의 boilerplate
#include "absl/flags/parse.h"
int main(int argc, char** argv) { std::vector<char*> positional = absl::ParseCommandLine(argc, argv); // 이후 GetFlag로 flag 값 읽기}ParseCommandLine은 argv를 모두 소비해 flag로 인식되는 것은 registry에 적용하고, 인식 안 되는 positional 인자는 반환.
#flag 구문
지원되는 형식:
./app --port=8080./app --port 8080./app --no-verbose # bool 부정./app -p 8080 # short form (드물게 사용)./app -- positional_arg_only # 이후 모두 positionalbool은 다음 모두 동등.
--verbose --verbose=true --verbose=1--no-verbose --verbose=false --verbose=0#—help / —helpfull / —helpshort
ParseCommandLine이 자동 처리. 발견 즉시 출력 후 exit.
./app --help # 현재 모듈의 flag만./app --helpfull # 모든 flag (의존 lib 포함)./app --helpshort # 짧은 요약--help 출력은 flag 등록 시 의 help 문자열을 자동 모음.
#—flagfile — 파일에서 읽기
./app --flagfile=/etc/myapp.flags파일에 한 줄 한 flag.
--port=9090--timeout=30s--verbose여러 환경별 설정 관리에 유용. CLI override:
./app --flagfile=/etc/myapp.flags --port=80 # 파일 + override#환경 변수 — undocumented but supported
Abseil은 환경 변수 자동 읽기를 기본 지원하지 않는다. 환경 변수 기반이 필요하면 명시적으로:
const char* env = std::getenv("MYAPP_PORT");if (env) absl::SetFlag(&FLAGS_port, std::stoi(env));또는 ParseAbseilFlagsOnly 후 환경 변수 매핑 단계를 추가.
#알 수 없는 flag 처리
기본은 fatal error — 알 수 없는 flag면 exit.
./app --unknown_flag=x# F0525 ...: ERROR: --unknown_flag=x: unknown flag--undefok=foo,bar로 특정 flag를 허용할 수 있다(테스트·prototyping에서만).
#ParseAbseilFlagsOnly
ParseCommandLine이 abseil flag뿐 아니라 모든 등록 flag를 처리한다. 내가 등록한 것만 처리하려면 ParseAbseilFlagsOnly 변종. 라이브러리 차원에서 미세 통제가 필요한 드문 경우.
대부분 main에서는 ParseCommandLine 한 줄로 충분.
#main의 표준 패턴
int main(int argc, char** argv) { // 1. flag 파싱 std::vector<char*> positional = absl::ParseCommandLine(argc, argv);
// 2. 심볼라이저 + failure handler (Part 11-04) absl::InitializeSymbolizer(argv[0]); absl::InstallFailureSignalHandler({});
// 3. log 초기화 absl::InitializeLog();
// 4. positional 처리 if (positional.size() < 2) { std::cerr << "usage: " << positional[0] << " <input-file>\n"; return 1; } std::string input_file = positional[1];
// 5. 실제 작업 return Run(input_file);}ParseCommandLine을 가장 먼저 부른다. 이후 코드가 flag·log 등을 자유롭게 쓸 수 있다.
#positional 인자
./app --port=8080 input.txt output.txtpositional 벡터:
positional[0] = "./app";positional[1] = "input.txt";positional[2] = "output.txt";--로 명시적 구분도 가능.
./app --port=8080 -- --not-a-flag# positional: ["./app", "--not-a-flag"]#SetCommandLine* helper
테스트에서 argv 시뮬레이션:
const char* argv[] = {"test", "--port=9999", "in.txt", nullptr};auto pos = absl::ParseCommandLine(3, const_cast<char**>(argv));EXPECT_EQ(absl::GetFlag(FLAGS_port), 9999);EXPECT_EQ(pos.size(), 2); // {"test", "in.txt"}ParseCommandLine은 한 프로세스에서 여러 번 호출 안전. 테스트 fixture에서 매번 다시 호출 가능.
#회피 패턴
// 회피 — argv 직접 파싱for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "--port") == 0) { ... } // ❌ boilerplate}
// Goodabsl::ParseCommandLine(argc, argv);int p = absl::GetFlag(FLAGS_port);// 회피 — ParseCommandLine 이전에 LOGint main(int argc, char** argv) { LOG(INFO) << "boot"; // ❌ log 초기화 전, severity flag 미적용 absl::ParseCommandLine(argc, argv);}
// Good — 순서 지킴int main(int argc, char** argv) { absl::ParseCommandLine(argc, argv); absl::InitializeLog(); LOG(INFO) << "boot";}// 회피 — Parse 결과 무시int main(int argc, char** argv) { absl::ParseCommandLine(argc, argv); // ... positional이 필요한데 ignore}
// Goodauto positional = absl::ParseCommandLine(argc, argv);#정리
absl::ParseCommandLine(argc, argv)한 줄로 flag 분리 + positional 추출.--help/--helpfull/--helpshort/--flagfile자동 지원.- 알 수 없는 flag는 fatal —
--undefok로 화이트리스트 가능. - main의 표준 순서: Parse → Symbolizer → FailureHandler → InitializeLog → 작업.
- 환경 변수 매핑은 기본 미제공 — 직접 SetFlag.
#다음 장 예고
Part 12-03: Flag introspection / validation.
#관련 항목
Abseil Code Review · 65 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 회피
관련 글
ABSL_FLAG 정의 분석
ABSL_FLAG — gflags의 후속이자 Abseil 표준 command-line flag. type-safe definition과 GetFlag/SetFlag 접근.
같은 시리즈에서 이어 읽기
absl::from_chars·SimpleAtoi — 빠른 숫자 변환
absl::SimpleAtoi / SimpleAtof / from_chars — locale-free, exception-free, sscanf 대비 10~50배. std::charconv와의 관계.
같은 시리즈에서 이어 읽기
Abseil Flag introspection·validation
Flag validator, custom type AbslParseFlag/AbslUnparseFlag, introspection API — flag 정확성과 동적 조회.
같은 시리즈에서 이어 읽기