gpt4 book ai didi

c++ - __tg_promote 在 tgmath.h 中做什么

转载 作者:太空宇宙 更新时间:2023-11-04 02:49:31 27 4
gpt4 key购买 nike

我正在查看 tgmath.h 并试图准确理解它如何根据输入值的大小选择正确的函数。

特别的调味料似乎是这个 __tg_promote 宏,但我越深入,这个谜题就越深。有没有人对 __tg_promote 的实际作用有一个简短的回答?

最佳答案

tgmath.h 的 clang 实现中,__tg_promote 实际上是一个函数,而不是一个宏。可以找到定义 here .

typedef void _Argument_type_is_not_arithmetic;
static _Argument_type_is_not_arithmetic __tg_promote(...)
__attribute__((__unavailable__,__overloadable__));
static double _TG_ATTRSp __tg_promote(int);
static double _TG_ATTRSp __tg_promote(unsigned int);
static double _TG_ATTRSp __tg_promote(long);
static double _TG_ATTRSp __tg_promote(unsigned long);
static double _TG_ATTRSp __tg_promote(long long);
static double _TG_ATTRSp __tg_promote(unsigned long long);
static float _TG_ATTRSp __tg_promote(float);
static double _TG_ATTRSp __tg_promote(double);
static long double _TG_ATTRSp __tg_promote(long double);
static float _Complex _TG_ATTRSp __tg_promote(float _Complex);
static double _Complex _TG_ATTRSp __tg_promote(double _Complex);
static long double _Complex _TG_ATTRSp __tg_promote(long double _Complex);

这是一个具有多个重载(通常在 C 中不允许)且没有定义的函数,这很好,因为它从未真正被调用过! __tg_promote 仅用于确定应将数字类型提升为的类型。 (整型类型为 double;浮点类型为它们自身。)当您查看接下来的几个宏时,这一点就很清楚了:

#define __tg_promote1(__x)           (__typeof__(__tg_promote(__x)))
#define __tg_promote2(__x, __y) (__typeof__(__tg_promote(__x) + \
__tg_promote(__y)))
#define __tg_promote3(__x, __y, __z) (__typeof__(__tg_promote(__x) + \
__tg_promote(__y) + \
__tg_promote(__z)))

__tg_promote 函数未被调用,因为它出现在特定于编译器的 __typeof__ 宏中。 __tg_promote1 宏只是在括号内扩展为其参数的提升类型__tg_promote2 扩展为如果添加其参数的提升类型的两个值将产生的类型(再次用括号括起来)。因此,例如,__tg_promote2(0.0f, 0) 将是 (double),因为添加了一个 float 和一个 double(提升 int 的结果)给出了 double__tg_promote3 类似。

header 的其余部分由委托(delegate)给各个普通 C 函数的函数的重载定义组成:

// atan2

static float
_TG_ATTRS
__tg_atan2(float __x, float __y) {return atan2f(__x, __y);}

static double
_TG_ATTRS
__tg_atan2(double __x, double __y) {return atan2(__x, __y);}

static long double
_TG_ATTRS
__tg_atan2(long double __x, long double __y) {return atan2l(__x, __y);}

为了能够调用,比如说,atan2(1.0f, 1),我们需要能够委托(delegate)给 __tg_atan2(double, double)。这是 __tg_promote2 决定当我们有一个 float 参数和一个 int 参数时,两者都应该转换为 double :

#define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \
__tg_promote2((__x), (__y))(__y))

所以在这种情况下 __tg_promote2((__x), (__y)) 扩展为 (double) 我们得到 __tg_atan2((double)(__x) , (double)(__y)),这正是我们想要的。

关于c++ - __tg_promote 在 tgmath.h 中做什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23660611/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com