__tg_promote在tgmath.h中做什么
What does __tg_promote do in tgmath.h
我正在查看tgmath.h
并试图准确了解它如何根据输入值的大小选择正确的函数。
特殊的调味料似乎是这个__tg_promote
宏,但我挖得越深,这个谜题就越深。有没有人对__tg_promote
实际做什么有一个简短的答案?
在 clang 的tgmath.h
实现中,__tg_promote
实际上似乎是一个函数,而不是一个宏。定义可以在这里找到。
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
是相似的。
标头的其余部分由委托给相应普通 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)
我们需要能够委派给__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))
,这正是我们想要的。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- ifstream什么都没读
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 我应该使用什么来代替void作为变体中的替代类型之一
- __tg_promote在tgmath.h中做什么