C预处理器#if处理非整数常量

时间:2018-02-28 18:43:37

标签: c c-preprocessor

我有以下代码片段,允许我在浮点值的double和float表示之间轻松翻转:

#define FLOATINGPOINTSIZE 64

#if FLOATINGPOINTSIZE == 64
typedef double FP_TYPE;
#define FP_LIT_SUFFIX 
#else
typedef float FP_TYPE;
#define FP_LIT_SUFFIX f
#endif

在另一个地方,我写了以下内容:

/* set floating point limits used when initialising values that will be subject
 * to the MIN() MAX() functions
 *
 * uses values from float.h */
#if FP_TYPE == double
#define FPTYPE_MAX DBL_MAX
#define FPTYPE_MIN DBL_MIN
#else
#define FPTYPE_MAX FLT_MAX
#define FPTYPE_MIN FLT_MIN
#endif

而我认为我应该写:

#if FLOATINGPOINTSIZE == 64

我有-Wall编译器设置给我很多警告,但这并没有被标记为问题。可能-Wall完全独立于预处理器?

我的问题是预处理器如何解释:

#if FP_TYPE == double

程序员的意义是显而易见的,但我不确定预处理器是做什么的?

它必须是一个错误吗?

2 个答案:

答案 0 :(得分:6)

  

我有-Wall编译器设置给我很多警告但是这个   没有被标记为问题。

代码有效,但你是对的。

  

我的问题是如何   预处理器解释:

#if FP_TYPE == double

好问题。

  

程序员的意思是显而易见的,但我不知道是什么   预处理器可以做到吗?

意图意义似乎很明显,作为代码的作者,你知道你的意思。但是你看起来的确不是预处理器如何解释这种条件。

预处理程序条件中的表达式被解释为整数常量表达式。就像在C if语句中一样,如果表达式求值为0,则该条件被视为false,否则它被视为true。表达式中的所有宏在评估之前都会展开,而任何剩余的标识符都将替换为0 。详情见section 6.10.1 of the standard

假设没有名为FP_TYPEdouble的宏的范围内定义(而typedef 宏定义),你的条件相当于

#if 0 == 0

,这总是如此。

  

它必须是一个错误吗?

预处理结果不符合您的预期,因此它是您代码中的错误。另一方面,编译器接受它是正确的。

答案 1 :(得分:2)

  

程序员的意义是显而易见的,但是我不确定预处理器是做什么的?

     

它必须是一个错误吗?

从用户的角度来看这是一个错误,但它不是预处理器中的错误。

#if FP_TYPE == double

被解释为

#if 0 == 0

因为FP_TYPEdouble都不是预处理器的已知符号。

来自https://gcc.gnu.org/onlinedocs/cpp/If.html#If

  

不是宏的标识符,它们都被认为是数字零。如果您知道#if MACRO在定义时始终具有非零值,则允许您编写#ifdef MACRO而不是MACRO。没有函数调用括号的函数式宏也被视为零。