Skip to content

Instantly share code, notes, and snippets.

@ashafq
Last active December 8, 2016 02:21
Show Gist options
  • Save ashafq/edacd351f1e4ec28255b7d87114638fb to your computer and use it in GitHub Desktop.
Save ashafq/edacd351f1e4ec28255b7d87114638fb to your computer and use it in GitHub Desktop.
How to write a type generic ABS() macro with GNU extension.
#ifndef ABS
#ifdef __GNUC__
#define ABS(x) __extension__({ \
__builtin_choose_expr( \
__builtin_types_compatible_p(__typeof__(x), long int), \
__builtin_labs(x), \
__builtin_choose_expr( \
__builtin_types_compatible_p(__typeof__(x), int), \
__builtin_abs(x), \
__builtin_choose_expr( \
__builtin_types_compatible_p(__typeof__(x), short), \
__builtin_abs(x), \
__builtin_choose_expr( \
__builtin_types_compatible_p(__typeof__(x), char), \
__builtin_abs(x), \
__builtin_choose_expr( \
__builtin_types_compatible_p(__typeof__(x), long double), \
__builtin_fabsl(x), \
__builtin_choose_expr( \
__builtin_types_compatible_p(__typeof__(x), double), \
__builtin_fabs(x), \
__builtin_choose_expr( \
__builtin_types_compatible_p(__typeof__(x), float), \
__builtin_fabsf(x), \
(void)0))))))); })
#else /* DAMMIT! */
#define ABS(x) (((x) < 0) ? -(x) : (x))
#endif /* __GNUC__ */
#endif /* ABS */
#if 0
[PASS] --------------- ABS(5) == 5
[PASS] --------------- ABS(-5) == 5
[PASS] --------------- ABS(5L) == 5L
[PASS] --------------- ABS(-5L) == 5L
[PASS] --------------- ABS(S(5)) == S(5)
[PASS] --------------- ABS(S(-5)) == S(5)
[PASS] --------------- ABS(C('\x5')) == C('\x5')
[PASS] --------------- ABS(C('\xfb')) == C('\x5')
[PASS] --------------- ABS(5.0) == 5.0
[PASS] --------------- ABS(-5.0) == 5.0
[PASS] --------------- ABS(5.0f) == 5.0f
[PASS] --------------- ABS(-5.0f) == 5.0f
[PASS] --------------- ABS(5.0l) == 5.0l
[PASS] --------------- ABS(-5.0l) == 5.0l
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment