C宏建筑功能

时间:2014-05-23 12:45:23

标签: c macros c-preprocessor

我正在尝试使用预处理器减少一些打字。我正在尝试使用单个宏定义2个或更多类似函数的对象(内联函数或宏,而不是太麻烦):

#include <stdio.h>

#define gen(name0, name1, mask, offset)         \
  inline unsigned char #name0(config) {return (config & mask) << offset));}     \
  inline unsigned char #name1(config) {return ((config & (mask << offset)) >> offset);}

gen (clk_option_write, clk_option_read, 0x07, 1) 
// I would like this to generate functions:
// inline unsigned char clk_option_write(unsigned char config) {return (config & 0x07) << 1));}
// inline unsigned char clk_option_read(unsigned char config) {return ((config & (0x07 << 1)) >> 1);}
// or something that generated macros would do:
// #define clk_option_write(config) ((config & 0x07) << 1)
// #define clk_option_read(config) (((config & (0x07 << 1)) >> 1)

int main (void)
{
  char test = 0;
  test = (clk_option_write(2));
  printf("%d", clk_option_read(test));
}

这不会编译,但它希望能让你了解我想要的东西。我想知道是否有另一种方法可以获得相同的效果? (不使用预处理器)

1 个答案:

答案 0 :(得分:0)

您尝试实现的目标似乎是创建一个易于使用的API。并且您希望能够在编译时轻松更改各种函数的行为。

正确的方法是使用面向对象的设计并创建一个代码模块&#34;为此(称之为&#34;代码模块&#34;,ADT,类或任何你喜欢的)。

// clk.h

#ifndef CLK_H
#define CLK_H

#include <stdint.h>

uint8_t clk_option_write (uint8_t config);
uint8_t clk_option_read  (uint8_t config);

#endif

// clk.c

static const uint8_t MASK   = 0x07;
static const uint8_t OFFSET = 1;

uint8_t clk_option_write (uint8_t config)
{
  return (config & MASK) << OFFSET;
}


uint8_t clk_option_read  (uint8_t config)
{
  return ( (config & (MASK << OFFSET) >> OFFSET);
}

至于为什么我给出了上述答案:

  

我试图减少一些打字

通常是一个坏主意。编程就是键入文本。如果你不喜欢输入大量文字,或者如果你这么做很慢,你可能想考虑另一种职业。

当然有许多智能技巧可以避免重复输入:使用复制/粘贴,使用外部脚本,使用聪明的文本编辑器甚至MS Excel。这些技巧都不涉及混淆程序的源代码。

  

...使用预处理器

通常是一个坏主意。预处理器具有不存在的类型安全性,类似功能的宏很难读取,调试和维护。这是众所周知的,因此类似函数的宏应该只用作最后的手段。

  

我试图使用预处理器减少一些打字。

结合两个糟糕的想法会导致一个非常糟糕的想法。除了上面提到的内容之外,您可以期待其他人阅读您的代码(包括您自己,1年后)以了解C语言。你不能指望他们知道独特的,自酿的宏观语言。努力使程序简单易读,易于维护。