Using a previously defined #define in a new #define in C

落爺英雄遲暮 提交于 2019-12-12 11:30:00

问题


Are there any potential issues/dangers in doing something such as

#define SAMPLERATE 32 // Sample rate in hertz
#define ONE_MINUTE ( SAMPLERATE * 60 )
#define FIVE_MINUTES ( ONE_MINUTE * 5 ) 

My compiler doesn't issue any errors or warnings. It's very nice because I can change one #define value (SAMPLERATE) and all the others get set to what they need to be with no other changes. I'm just not entirely sure if this is best practice or safe.


回答1:


A #define is handled by the pre-processor. The pre-processor is run prior to compilation and can perform simple mathematical operations and copy/paste of code. For instance, you could do the following with your example:

int myVar = SAMPLERATE;

The pre-processor would simply paste 32 where SAMPLERATE is before being compiled.

This mechanism is powerful in the sense that you have now created a name for an integer value. This adds meaning for both you and future developers. It also allows you to make changes in one place instead of many.

Just be sure to #define SAMPLERATE 32 prior to any other #define statements that may use SAMPLERATE.




回答2:


Macros are NEVER expanded in a #define statement. When you have #define like:

#define ONE_MINUTE ( SAMPLERATE * 60 )

That defines the macro ONE_MINUTE with an expansion (body) of ( SAMPLERATE * 60 ). Whether there is a macro called SAMPLERATE defined elsewhere in your program or not is completely irrelevant. The exisitence (or non-existence) of such a macro has no effect.

Instead, when a macro is USED (and the macro expanded), the result of that expansion is rescanned for other macros to expand. So all that matters is whether SAMPLERATE is defined at the point at which ONE_MINUTE is USED.




回答3:


#define constants (object-like macros) are used by the pre-processor to substitute the identifier with the token list specified . #defines can also take parameters. These are called function-like macros. The advantage of such macros is that they are replaced in-line something that you can't always guarantee with normal functions. Object-like macros are used frequently in conditional compilation. The drawback of macros in my opinion is that they are not type safe. When used carefully however they can be a great help.

Here is an example of macros making your life easier.

#include <stdio.h>
#include <stdlib.h>

static const unsigned char BYTES[256] = {
#define A(n) n, n+1, n+1, n+2
#define B(n) A(n), A(n+1), A(n+1), A(n+2)
#define C(n) B(n), B(n+1), B(n+1), B(n+2)
C(0), C(1), C(1), C(2)
};

int main() {
  unsigned char BYTE = 0b01011101;
  printf("The byte 01011101 has %d set bits.\n",BYTES[BYTE]);
}


来源:https://stackoverflow.com/questions/21030041/using-a-previously-defined-define-in-a-new-define-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!