gcc builtin: choose_expr
You can use the built-in function __builtin_choose_expr to evaluate code depending on the value of a constant expression. This built-in function returns exp1 if const_exp, which is an integer constant expression, is nonzero. Otherwise it returns exp2.
April 7, 2026
gcc builtin: choose_expr
Reqruies
- Compiler : gcc 3.1 or later
이번 포스트에서는 GCC 빌트인 함수 중 하나인 __builtin_choose_expr에 대해 알아보겠습니다.
이 함수는 C++에서는 지원되지 않으며, C 언어에서만 사용할 수 있는 기능입니다.
이 함수는 C++에서는 지원되지 않으며, C 언어에서만 사용할 수 있는 기능입니다.
동작 방식은 C의 3항 연산자(
하지만 가장 중요한 차이점은 이 연산이 런타임이 아닌 compile-time에 수행된다는 점입니다.
? : operator)와 매우 유사합니다.하지만 가장 중요한 차이점은 이 연산이 런타임이 아닌 compile-time에 수행된다는 점입니다.
이 빌트인 함수는 Aldy Hernandez의 패치를 통해 GCC 3.1 버전부터 추가되었습니다.
GCC Documentation
GCC 공식 문서의 설명을 먼저 살펴보겠습니다.
__builtin_choose_expr (const_exp, exp1, exp2)DocYou can use the built-in function __builtin_choose_expr to evaluate code depending on the value of a constant expression. This built-in function returns exp1 if const_exp, which is an integer constant expression, is nonzero. Otherwise it returns exp2.
This built-in function is analogous to the '? :' operator in C, except that the expression returned has its type unaltered by promotion rules. Also, the built-in function does not evaluate the expression that is not chosen.
For example, if const_exp evaluates to true, exp2 is not evaluated even if it has side effects...
Internal Implementation
GCC의 소스 코드를 직접 확인해 보면 이 함수가 어떻게 동작하는지 더 쉽게 이해할 수 있습니다.
다음은 gcc 7.4의
다음은 gcc 7.4의
c-parser.c 코드 일부입니다.gcc/c/c-parser.cc
코드를 자세히 보면 내부적으로 3항 연산자로 구현되어 있음을 알 수 있습니다.
Constraints: Constant Expressions
여기서 주의해야 할 점은 첫 번째 인자가 반드시 const_exp(상수 표현식)이어야 한다는 것입니다.
C 언어에서는 일반적인
const 변수가 상수 표현식으로 취급되지 않으므로, 이를 첫 번째 인자로 사용할 수 없습니다.실제로 변수를 사용했을 때 어떤 결과가 나오는지 확인해 보겠습니다.
can we use the variables for the first argument?c
gcc version 7.4.0 –target=x86_64-linux-gnubash
위와 같이 컴파일 에러가 발생하는 것을 확인할 수 있습니다.
따라서 아래와 같이 실제 상수 표현식(constant expression)을 사용해야 합니다.
따라서 아래와 같이 실제 상수 표현식(constant expression)을 사용해야 합니다.
use const expr for the first argumentc
execution resultbash
어셈블리 코드를 확인해 보면 컴파일 타임에 이미 값이 결정된 것을 볼 수 있습니다.
assembly - x86_64 AT&Tbash
strings checkbash
__builtin_choose_expr가 컴파일 타임에 각각
exp1 또는 exp2로 완전히 치환된 것을 확인할 수 있습니다.Practical Examples
상수 표현식만 사용 가능하다는 제약 때문에 쓸모없어 보일 수 있지만, 실제로는 매우 유용하게 활용될 수 있습니다.
예를 들어, 특정 비트가 설정되어 있는지 컴파일 타임에 확인하는
IS_MASKED 매크로를 다음과 같이 작성할 수 있습니다.e.g. maskedc
리눅스 커널의
eBPF 코드에서도 sizeof와 함께 사용되는 사례를 찾아볼 수 있습니다.e.g. sizeof in BPF (include/trace/bpf_probe.h)c
Return Type Characteristics
이 빌트인 함수는 일반적인 3항 연산자와 타입 처리 방식에서 큰 차이가 있습니다.
일반적인 3항 연산자는 피연산자의 타입에 따라 암시적 형변환(type promotion)이 발생할 수 있지만, 이 builtin function은 형변환 없이 선택된
exp1 또는 exp2의 타입을 그대로 유지합니다.check return typec
execution resultbash
Advanced Usage: Function Overloading
__builtin_choose_expr는 다른 빌트인 함수들과 조합했을 때 더욱 강력해집니다.
예를 들어 __builtin_types_compatible_p와 조합하면, C 언어에서는 지원하지 않는 인자 타입에 따른 함수 오버로딩(function overloading)을 유사하게 구현할 수 있습니다.
function overloading in cc
execution resultbash
Conclusion
__builtin_choose_expr는 단순해 보일 수 있지만, 적재적소에 활용하면 불필요한 코드를 줄이고 컴파일 타임 최적화를 이끌어낼 수 있는 유용한 도구입니다.
참고로 표준 C에서도 매크로를 이용해 인자의 타입이나 개수에 따른 유사한 처리를 구현할 수 있는데, 기회가 된다면 다른 포스트에서 다뤄보도록 하겠습니다.