C++ 코드가 컴파일러 눈에는 어떻게 보일까
혹시 C++로 코드를 짜다가 "내가 쓴 이 코드를 컴파일러는 도대체 어떻게 이해하고 있는 걸까?" 하고 궁금해진 적 있으세요? 사실 우리가 작성하는 소스 코드는 컴파일러 입장에서 그냥 텍스트 덩어리거든요. 이걸 의미 있는 구조로 바꾸기 위해 컴파일러는 제일 먼저 AST(Abstract Syntax Tree, 추상 구문 트리) 라는 걸 만들어요. 쉽게 말하면 코드를 트리 모양의 데이터 구조로 변환하는 거예요. 예를 들어 a + b c 같은 식이 있으면, 곱셈이 더 먼저 일어나야 하니까 노드가 자식이 되고 + 노드가 부모가 되는 식의 나무 구조가 만들어지는 거죠.
이번에 캐나다 빅토리아 대학교(University of Victoria)의 Aurora 연구 그룹에서 공개한 ACAV(Abstract Code Analysis and Visualization) 라는 도구는 바로 이 AST를 사람이 눈으로 보면서 탐색할 수 있게 도와주는 툴이에요. C++는 문법이 워낙 복잡하기로 유명한 언어잖아요. 템플릿, 매크로, 다중 상속, 람다, constexpr 같은 게 얽히면 같은 줄의 코드라도 내부적으로는 어마어마하게 큰 트리를 만들어내거든요. 이걸 그냥 텍스트 로그로 보면 정말 답이 안 나오는데, ACAV는 이걸 인터랙티브하게 펼쳐 보면서 어떤 노드가 어떤 자식을 갖고 있는지 클릭으로 따라갈 수 있게 해줍니다.
어떻게 동작하는가
ACAV는 내부적으로 Clang의 LibTooling 을 활용해요. Clang은 LLVM 프로젝트의 C/C++/Objective-C 컴파일러인데, 컴파일러 내부 정보에 접근할 수 있는 라이브러리(LibTooling, LibASTMatchers)를 함께 제공하는 게 큰 장점이에요. ACAV는 이 라이브러리를 통해 소스 파일을 파싱해서 진짜 컴파일러가 보는 것과 똑같은 AST를 추출하고, 그걸 웹 인터페이스나 시각화된 UI로 보여줍니다.
사용 흐름은 대략 이래요. 분석하고 싶은 C++ 프로젝트가 있으면 보통 compile_commands.json 이라는 파일을 먼저 만들어야 하는데요. 이게 뭐냐면 "이 파일은 이런 옵션으로 컴파일하면 된다"는 정보가 담긴 데이터베이스예요. CMake에서 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 옵션만 주면 자동 생성됩니다. ACAV는 이 정보를 읽어서 실제 빌드와 동일한 환경에서 코드를 파싱해요. 그래야 매크로 정의나 인클루드 경로 같은 게 정확히 맞아떨어지거든요.
그다음에는 함수, 클래스, 네임스페이스 단위로 트리를 펼쳐볼 수 있고, 특정 표현식을 클릭하면 그게 어떤 타입으로 추론됐는지, 어떤 오버로드된 함수로 디스패치됐는지까지 확인할 수 있어요. 이런 정보는 그냥 코드만 봐서는 절대 알 수 없는 것들이죠.
다른 도구들과 뭐가 다른가
비슷한 도구로는 Clang 자체에 내장된 clang -Xclang -ast-dump 옵션이 있어요. 이걸 쓰면 터미널에 AST를 텍스트로 쏟아내 주거든요. 그런데 실무에서 써본 분은 알겠지만, 표준 라이브러리 헤더 하나만 인클루드해도 출력이 수만 줄이 넘어가요. 검색하기도 힘들고, 부모-자식 관계를 따라가기도 어렵습니다. Cppast, Cling, SourceTrail 같은 정적 분석/시각화 도구도 있지만, 각각 목적이 조금씩 달라요. SourceTrail은 코드 네비게이션에 강하고 Cling은 REPL에 가깝죠.
ACAV의 포지션은 "AST 그 자체를 학습하고 분석하기 위한 전용 뷰어"에 가까워요. 그래서 컴파일러 개발자나 정적 분석 도구를 만드는 사람, 또는 C++ 표준의 동작을 깊이 이해하고 싶은 학습자에게 잘 맞습니다.
한국 개발자에게 주는 시사점
게임 엔진, 임베디드, 금융 트레이딩 시스템처럼 C++를 깊게 쓰는 분야가 한국에도 꽤 많잖아요. 이런 곳에서는 템플릿 메타프로그래밍이나 SFINAE 같은 고급 기법 때문에 컴파일 에러 메시지가 책 한 권 분량으로 나오는 경험을 다들 해보셨을 거예요. AST를 한 번이라도 직접 들여다보면 "아, 컴파일러가 내 의도와 다르게 이걸 해석했구나" 하는 걸 훨씬 빨리 파악할 수 있어요. 또 사내에서 코드 컨벤션을 강제하는 린터를 만들거나, 레거시 코드의 자동 리팩토링 도구를 짜야 할 때도 LibTooling 기반의 도구를 이해해두면 큰 무기가 됩니다.
마무리
ACAV는 화려한 신기술은 아니지만, C++라는 거대한 언어의 내부를 들여다보는 좋은 창이 되어주는 도구예요. 평소에 "내가 쓰는 언어가 정확히 어떻게 해석되는지" 궁금했다면 한 번쯤 설치해서 자기 프로젝트에 돌려볼 만합니다.
여러분은 평소 컴파일러 내부 동작이 궁금할 때 어떤 도구를 쓰시나요? godbolt(Compiler Explorer)처럼 어셈블리를 보는 것과 AST를 보는 것 중 어느 쪽이 더 도움이 됐는지 경험을 나눠주시면 좋을 것 같아요.
🔗 출처: Hacker News
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공