Dev*_*lar 9 c macros c-preprocessor
这是非常具体的,有点难以解释,而且很可能不可能,但是这里有.
我想实现<errno.h>.(我的爱好项目正在实施标准C库.)
天真的方式是:
// in <errno.h>
extern int errno;
// in some .c file
int errno = 0;
Run Code Online (Sandbox Code Playgroud)
这有效.但它有一个缺点:如果调用数学库函数,它总是必须在执行后查询FPU状态以errno进行适当的设置.这使得FPU在数学繁重的应用程序中停滞不前.
该Ç标准认可的懒评价errno通过使宏来代替:
int * __errno();
#define errno *__errno()
Run Code Online (Sandbox Code Playgroud)
这样,errno只有在实际请求其值时才"设置":
// "__errno()" returns the location of the current errno value,
// the "errno" macro turns it into a value.
x = errno;
Run Code Online (Sandbox Code Playgroud)
在库的其余部分给出一些逻辑,如果最后调用的库函数实际上是使用 FPU的库函数,则仅需要查询FPU状态,并且errno实际请求值.
到目前为止,一切都很好.但另一种方式是令我头疼:
errno = 0;
Run Code Online (Sandbox Code Playgroud)
errno根本不要求价值.但是__errno()不知道这一点,并且如果调用的最后一个库函数正在使用FPU,它将查询FPU状态.
现在我没有办法避免这种情况(即,根据它们是否用于赋值运算符的左侧或右侧,使errno宏或__errno()函数以某种方式工作不同),并且几乎满足于接受这一点.
但也许你们中的任何一个人都有一个好主意?
这里没有什么绝妙的想法,但据我所知,errno允许通过函数调用来实现,以使标准库的线程安全实现成为可能。我不认为延迟查询 FPU 是一个好主意:如何避免在这种情况下出现不一致:
errnoerrno是否应该调用__errno()清除标志?
根据标准,是否必须通过数学函数设置由(具体来说, )errno的值决定。math_errhandlingmath_errhandling & MATH_ERRNO
我要做的是通过预处理器指令使错误报告成为可选,并允许程序员math_errhandling在编译时设置 的值。这意味着数学函数不能预先静态编译,而必须驻留在标头中,无论如何,这可能是一个好主意,允许没有链接时优化的编译器内联这些函数。