C 宏构建函数

标签 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));
}

这无法编译,但希望它能让您了解我想要实现的目标。我想知道是否还有其他方法可以达到相同的效果? (无需借助预处理器)

最佳答案

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

正确的方法是使用面向对象的设计并为此创建一个“代码模块”(将其称为“代码模块”、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);
}
<小时/>

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

I'm trying to cut down on some typing

通常是个坏主意。编程就是输入文本。如果您不喜欢输入大量文本,或者输入速度非常慢,您可能需要考虑其他职业。

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

...using the preprocessor

通常是个坏主意。预处理器不存在类型安全性,并且类似函数的宏非常难以读取、调试和维护。这是众所周知的,因此类函数宏只能作为最后的手段使用。

I'm trying to cut down on some typing using the preprocessor.

将两个糟糕的想法结合起来会产生一个非常糟糕的想法。除了提到的事情之外,您可以期望阅读您的代码的其他人(包括一年后的您自己)了解 C 语言。你不能指望他们了解独特的、自制的宏语言。力求使程序简单、易读、易维护。

关于C 宏构建函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23829632/

相关文章:

c - fprintf() 问题 utf-8 linux

c - 套接字的所有操作都需要检查 EINTR 吗?

C 我怎样才能减少我的程序大小

我们可以用 c 将引号替换为其他字符吗?

c++ - header 一定是文件吗?

c - EVP_MD_CTX "error: storage size of ‘ctx’ 未知”

macros - &lisp 宏中的可选参数 : Why does this variable behave like this?

c++ - 您可以将一个宏作为参数提供给另一个宏,而不扩展初始宏吗?

c++ - 获取类的名称作为字符串

C 难题...如何将可变参数传递给宏?