(嵌入)C:void function()或#define function()函数
我正在为嵌入式设备编程,我想知道宏函数应该使用什么,例如一些寄存器的init。 我应该将其设为static/const还是将其定义为宏 例如,这:(嵌入)C:void function()或#define function()函数,c,function,static,c-preprocessor,C,Function,Static,C Preprocessor,我正在为嵌入式设备编程,我想知道宏函数应该使用什么,例如一些寄存器的init。 我应该将其设为static/const还是将其定义为宏 例如,这: #define FPGA_INIT()\ { \ /* Set function and direction of start_code pin*/\ P0SEL &= ~0x04; \ P0DIR |= 0x04; \ FPGA_START_CODE = 0; \ } 还是这个 static void fpga_init
#define FPGA_INIT()\
{ \
/* Set function and direction of start_code pin*/\
P0SEL &= ~0x04; \
P0DIR |= 0x04; \
FPGA_START_CODE = 0; \
}
还是这个
static void fpga_init()
{
/* Set function and direction of start_code pin*/
P0SEL &= ~0x04;
P0DIR |= 0x04;
FPGA_START_CODE = 0;
}
内存位置有什么不同呢?如果使用宏,那么无论在哪里使用它,预处理器都会将其替换为整个宏。这意味着,如果你说10次,那么你需要10倍的内存。但是,由于没有函数调用的开销,代码的执行速度会更快
我通常会避免在函数中使用宏。宏很难调试和维护。如果您需要在位代码,一个更干净的解决方案是使用,这是大多数现代编译器所支持的。如果您使用宏,那么无论您在何处使用它,预处理器都会将其替换为完整的宏体。这意味着,如果你说10次,那么你需要10倍的内存。但是,由于没有函数调用的开销,代码的执行速度会更快
我通常会避免在函数中使用宏。宏很难调试和维护。如果您需要在位代码,一个更干净的解决方案是使用,这是大多数现代编译器所支持的。宏可以在操作期间为您节省函数调用的开销(速度) 函数可以节省在多个位置(程序空间)使用相同代码的开销
选择速度和空间中对您更为关键的一个,并使用适当的选项。宏可以在操作期间为您节省函数调用的开销(速度) 函数可以节省在多个位置(程序空间)使用相同代码的开销
选择哪个速度和空间对您更重要,并使用适当的选项。通常,最好将预处理器宏的使用保留到需要预处理器在编译代码之前操作代码的时候——不应该使用预处理器宏来定义可以作为正常函数实现的过程。因为无论在哪里调用宏,预处理器都会替换宏代码,所以很难调试发生的错误。例如,如果调用FPGA_INIT()宏,则(可能)全局变量P0SEL、P0DIR和FPGA_START_代码可能被同名的局部变量隐藏 如果您声明一个fpga_init()函数,编译器将根据您所针对的平台的任何规则,将该函数的代码与您声明的其他函数的代码放在一起。如果声明一个FPGA_INIT()宏,编译器将永远不会知道它存在,因为对它的所有引用都将由预处理器解析;编译器将在调用宏的每个函数中分别查看和编译宏的语句
除非您需要频繁地调用此代码(在内部循环中),否则宏和函数实现的性能很可能无法区分。如果确实需要频繁调用代码,则应尝试以每种方式衡量性能:根据处理器的体系结构,使用预处理器内联代码可能会更快,或者将代码放在单独的函数中可能会更快(特别是当扩展每个调用导致重要循环溢出缓存线时).一般来说,最好将预处理器宏的使用保留在编译前需要预处理器处理代码的时候---您不应该使用预处理器宏来定义可以作为正常函数实现的过程。因为预处理器会在需要时替换宏代码调用宏时,可能很难调试发生的错误。例如,如果调用FPGA_INIT()宏,则(可能)全局变量P0SEL、P0DIR和FPGA_START_代码可能被同名的局部变量隐藏 如果您声明一个fpga_init()函数,编译器将根据您所针对的平台的任何规则,将该函数的代码与您声明的其他函数的代码放在一起宏,编译器永远不会知道它存在,因为对它的所有引用都将由预处理器解析;编译器将在调用的每个函数中分别查看和编译宏的语句
除非您需要频繁调用此代码(在内部循环中),宏和函数实现的性能可能无法区分。如果确实需要频繁调用代码,则应尝试以每种方式衡量性能:根据处理器的体系结构,使用预处理器内联放置代码可能会更快,或者将代码放入sep可能会更快arate函数(特别是当扩展每个调用导致重要循环溢出缓存线时).信任您的编译器-使其成为常规函数,让编译器选择如何使用它。信任您的编译器-使其成为常规函数,让编译器选择如何使用它。将函数放入头文件,并以
内联关键字作为前缀:
inline void fpga_init()
{
/* Set function and direction of start_code pin*/
P0SEL &= ~0x04;
P0DIR |= 0x04;
FPGA_START_CODE = 0;
}
inline关键字建议编译器将语句“inline”与其他代码放在一起,类似于#define
宏。这比宏更好,因为它的行为类似于函数,没有宏的缺陷。将函数放入头文件中,并以inline
关键字作为前缀:
inline void fpga_init()
{
/* Set function and direction of start_code pin*/
P0SEL &= ~0x04;
P0DIR |= 0x04;
FPGA_START_CODE = 0;
}
inline关键字建议编译器将语句与其他代码“inline”放在一起,类似于#define
宏。这比宏更好,因为它的行为类似于函数,没有宏的缺陷。考虑对init代码使用宏以节省内存空间,因为