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의 3항 연산자(? : operator)와 매우 유사합니다.
하지만 가장 중요한 차이점은 이 연산이 런타임이 아닌 compile-time에 수행된다는 점입니다.
이 빌트인 함수는 Aldy Hernandez의 패치를 통해 GCC 3.1 버전부터 추가되었습니다.

GCC Documentation

GCC 공식 문서의 설명을 먼저 살펴보겠습니다.
__builtin_choose_expr (const_exp, exp1, exp2)
Doc

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.

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의 c-parser.c 코드 일부입니다.
gcc/c/c-parser.c
c
코드를 자세히 보면 내부적으로 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-gnu
bash
위와 같이 컴파일 에러가 발생하는 것을 확인할 수 있습니다.
따라서 아래와 같이 실제 상수 표현식(constant expression)을 사용해야 합니다.
use const expr for the first argument
c
execution result
bash
어셈블리 코드를 확인해 보면 컴파일 타임에 이미 값이 결정된 것을 볼 수 있습니다.
assembly - x86_64 AT&T
bash
strings check
bash
__builtin_choose_expr가 컴파일 타임에 각각 exp1 또는 exp2로 완전히 치환된 것을 확인할 수 있습니다.

Practical Examples

상수 표현식만 사용 가능하다는 제약 때문에 쓸모없어 보일 수 있지만, 실제로는 매우 유용하게 활용될 수 있습니다.
예를 들어, 특정 비트가 설정되어 있는지 컴파일 타임에 확인하는 IS_MASKED 매크로를 다음과 같이 작성할 수 있습니다.
e.g. masked
c
리눅스 커널의 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 type
c
execution result
bash

Advanced Usage: Function Overloading

__builtin_choose_expr는 다른 빌트인 함수들과 조합했을 때 더욱 강력해집니다.
예를 들어 __builtin_types_compatible_p와 조합하면, C 언어에서는 지원하지 않는 인자 타입에 따른 함수 오버로딩(function overloading)을 유사하게 구현할 수 있습니다.
function overloading in c
c
execution result
bash

Conclusion

__builtin_choose_expr는 단순해 보일 수 있지만, 적재적소에 활용하면 불필요한 코드를 줄이고 컴파일 타임 최적화를 이끌어낼 수 있는 유용한 도구입니다.
참고로 표준 C에서도 매크로를 이용해 인자의 타입이나 개수에 따른 유사한 처리를 구현할 수 있는데, 기회가 된다면 다른 포스트에서 다뤄보도록 하겠습니다.
Jooojub
System S/W engineer
Explore Tags
Series
    Recent Post
    © 2026. jooojub. All right reserved.