如何定义C中其他预定义值的总和?

如何定义C中其他预定义值的总和?,c,c-preprocessor,C,C Preprocessor,我如何使用#define来表示一个值由另外两个值的和组成。在C中,这样做是允许的吗 #define VALUE_A 2 #define VALUE_B 2 #define SUM_A_B (VALUE_A + VALUE_B) 如果没有,我应该如何实现此功能 Linux和GCC头文件通常都会这样做,如果这是信任投票的话。e、 g: $ grep -r 'define.*+' /usr/include/ ... /usr/include/linux/fdreg.h:#define FD_STAT

我如何使用
#define
来表示一个值由另外两个值的和组成。在C中,这样做是允许的吗

#define VALUE_A 2
#define VALUE_B 2
#define SUM_A_B (VALUE_A + VALUE_B)

如果没有,我应该如何实现此功能

Linux和GCC头文件通常都会这样做,如果这是信任投票的话。e、 g:

$ grep -r 'define.*+' /usr/include/
...
/usr/include/linux/fdreg.h:#define FD_STATUS    (4 + FD_IOPORT )
...
/usr/include/linux/elf.h:#define PT_GNU_STACK   (PT_LOOS + 0x474e551)
...
/usr/include/i386-linux-gnu/asm/unistd_32.h:#define __NR_timer_settime  (__NR_timer_create+1)

等等。

Linux和GCC头文件通常会这样做,如果这是信任投票的话。e、 g:

$ grep -r 'define.*+' /usr/include/
...
/usr/include/linux/fdreg.h:#define FD_STATUS    (4 + FD_IOPORT )
...
/usr/include/linux/elf.h:#define PT_GNU_STACK   (PT_LOOS + 0x474e551)
...
/usr/include/i386-linux-gnu/asm/unistd_32.h:#define __NR_timer_settime  (__NR_timer_create+1)

等等。

Linux和GCC头文件通常会这样做,如果这是信任投票的话。e、 g:

$ grep -r 'define.*+' /usr/include/
...
/usr/include/linux/fdreg.h:#define FD_STATUS    (4 + FD_IOPORT )
...
/usr/include/linux/elf.h:#define PT_GNU_STACK   (PT_LOOS + 0x474e551)
...
/usr/include/i386-linux-gnu/asm/unistd_32.h:#define __NR_timer_settime  (__NR_timer_create+1)

等等。

Linux和GCC头文件通常会这样做,如果这是信任投票的话。e、 g:

$ grep -r 'define.*+' /usr/include/
...
/usr/include/linux/fdreg.h:#define FD_STATUS    (4 + FD_IOPORT )
...
/usr/include/linux/elf.h:#define PT_GNU_STACK   (PT_LOOS + 0x474e551)
...
/usr/include/i386-linux-gnu/asm/unistd_32.h:#define __NR_timer_settime  (__NR_timer_create+1)

等等。

如果您只需要整数常量(type
int
)的枚举,您可以对此类常量使用枚举

enum { SUM_A_B = (VALUE_A + VALUE_B), };
可能的优势:

  • 编译器只对总和求值一次。这不是一个大问题 如果这仅仅是一个简单的总数,那么就为现代编译器交易,但是 当您使用更复杂的 表情
  • 即使是现在,编译器错误和调试信息也不是这样 适用于来自预处理器的值。枚举常量通常可以很好地跟踪
一个缺点是该值本身在预处理器中无法访问。所以你不能用它来构造
#if/#else
。但你至少可以把它定义为

#define SUM_A_B SUM_A_B

因此,
#ifdef/#else
构造仍然可以工作。

如果您只需要对整型常量(type
int
)使用它,您可以对此类常量使用枚举

enum { SUM_A_B = (VALUE_A + VALUE_B), };
可能的优势:

  • 编译器只对总和求值一次。这不是一个大问题 如果这仅仅是一个简单的总数,那么就为现代编译器交易,但是 当您使用更复杂的 表情
  • 即使是现在,编译器错误和调试信息也不是这样 适用于来自预处理器的值。枚举常量通常可以很好地跟踪
一个缺点是该值本身在预处理器中无法访问。所以你不能用它来构造
#if/#else
。但你至少可以把它定义为

#define SUM_A_B SUM_A_B

因此,
#ifdef/#else
构造仍然可以工作。

如果您只需要对整型常量(type
int
)使用它,您可以对此类常量使用枚举

enum { SUM_A_B = (VALUE_A + VALUE_B), };
可能的优势:

  • 编译器只对总和求值一次。这不是一个大问题 如果这仅仅是一个简单的总数,那么就为现代编译器交易,但是 当您使用更复杂的 表情
  • 即使是现在,编译器错误和调试信息也不是这样 适用于来自预处理器的值。枚举常量通常可以很好地跟踪
一个缺点是该值本身在预处理器中无法访问。所以你不能用它来构造
#if/#else
。但你至少可以把它定义为

#define SUM_A_B SUM_A_B

因此,
#ifdef/#else
构造仍然可以工作。

如果您只需要对整型常量(type
int
)使用它,您可以对此类常量使用枚举

enum { SUM_A_B = (VALUE_A + VALUE_B), };
可能的优势:

  • 编译器只对总和求值一次。这不是一个大问题 如果这仅仅是一个简单的总数,那么就为现代编译器交易,但是 当您使用更复杂的 表情
  • 即使是现在,编译器错误和调试信息也不是这样 适用于来自预处理器的值。枚举常量通常可以很好地跟踪
一个缺点是该值本身在预处理器中无法访问。所以你不能用它来构造
#if/#else
。但你至少可以把它定义为

#define SUM_A_B SUM_A_B

因此,
#ifdef/#else
构造仍然可以工作。

它可以工作,我一直都在做。编写一个包含它的小程序会很有趣(它是有效的,看起来很合理,只要你记住括号),然后查看编译后的代码。我99%确信编译器会将总和计算成一个简单的常量,这样在运行时就不会有性能损失。有人想检查一下吗?@Floris:编译器需要知道它是一个常量表达式,因为关于在哪里可以使用和不可以使用非常量表达式(或者根据是否有常量表达式语义不同)有不同的规则。没有什么要求它在编译时实际计算值,但不这样做是愚蠢的。它是有效的,我一直都在这样做。编写一个小程序并将其包含在其中(它是有效的,看起来合理的,只要你记住括号),然后查看编译后的代码,这会很有趣。我99%确信编译器会将总和计算成一个简单的常量,这样在运行时就不会有性能损失。有人想检查一下吗?@Floris:编译器需要知道它是一个常量表达式,因为关于在哪里可以使用和不可以使用非常量表达式(或者根据是否有常量表达式语义不同)有不同的规则。没有什么要求它在编译时实际计算值,但不这样做是愚蠢的。它是有效的,我一直都在这样做。编写一个小程序并将其包含在其中(它是有效的,看起来合理的,只要你记住括号),然后查看编译后的代码,这会很有趣。我99%确信编译器会将总和计算成一个简单的常量,这样在运行时就不会有性能损失。有人想检查一下吗?@Floris:编译器需要知道它是一个常量表达式,因为关于在哪里可以使用和不可以使用非常量有不同的规则