前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c语言下利用p99:模拟实现try-cath-finally

c语言下利用p99:模拟实现try-cath-finally

作者头像
10km
发布2019-05-25 22:22:00
6130
发布2019-05-25 22:22:00
举报
文章被收录于专栏:10km的专栏10km的专栏

版权声明:本文为博主原创文章,转载请注明源地址。 /developer/article/1433677

这阵子在C语言环境做开发,写了大量宏函数,写得头疼,但使用宏函数模板的确可以提高开发效率及代码质量,所以还得硬着头皮写,在一个偶然的机会发现有个叫P99的开源项目,P99提供了大量的的宏和函数定义,用于简化C编程,。说白了,P99提供的就是一大堆.h头文件,.h文件中定义了大量的宏函数,利用这些宏函数可以简化C代码开发。

比如下面用了P99中提供的例程实现了C++中才有的try-catch-finally语句:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdatomic.h>
#include <p99_try.h>
void test_try(){
    unsigned char*volatile buffer = 0;
    P99_TRY {
      buffer = malloc(200);
      if (!buffer) P99_THROW(thrd_nomem);
      printf("return %s\n",__FUNCTION__);
      // do something complicated with buffer
      //favorite_func(buffer);
    } P99_FINALLY {
      free(buffer);
    }

}
int main(void) {
    test_try();
    return EXIT_SUCCESS;
}

定义enum

代码语言:javascript
复制
// 定义名为`enum_test`,包含`hello,world)`两个值的枚举类型
P99_DECLARE_ENUM(enum_test,hello,world);

宏展开后的代码

代码语言:javascript
复制
typedef enum enum_test { hello,world ,                                                \
               /*! upper bound of the @ref T constants */                     \
               enum_test_amount,                                        \
               /*! the largest @ref T constant */                             \
               enum_test_max = ((size_t)(enum_test_amount) - 1u), \
               /*! the smallest @ref T constant */                            \
               enum_test_min = 0                                        \
} enum_test;                                                                          \
__attribute__((__const__))                                             \
__attribute__((__always_inline__)) __inline__                                                     \
char const* enum_test_getname(enum_test p00_x) {                 \
  switch ((uintmax_t)p00_x) {                                  \
    case hello: return "hello"; case world: return "world";                       \
  default: return "((" "enum_test" ")unknown value)";                   \
  }                                                            \
}                                                              \
extern void p00_harmless_declaration_declare_enum_getnameenum_test(void);                                     \
__attribute__((__pure__))                                              \
__attribute__((__always_inline__)) __inline__                                                     \
enum_test enum_test_parse(char const p00_s[]) {                  \
  enum_test p00_ret = enum_test_amount;                          \
  if (p00_s) {                                                 \
    size_t p00_c = 0;                                          \
    size_t const p00_len = strlen(p00_s);                      \
    if (!memcmp("hello", p00_s, p00_len)) {               \
  ++p00_c;                                                     \
  p00_ret = hello;                                                 \
 }; if (!memcmp("world", p00_s, p00_len)) {               \
  ++p00_c;                                                     \
  p00_ret = world;                                                 \
 };                      \
    if (p00_c > 1) p00_ret = enum_test_amount;           \
  }                                                            \
  return p00_ret;                                              \
}                                                              \
extern void p00_harmless_declaration_declare_enum_parseenum_test(void)

定义struct

代码语言:javascript
复制
P99_DEFINE_STRUCT(struct_test,int hello,char* world);

展开后的代码

代码语言:javascript
复制
struct fl_buf_info {                                                  \
  int hello; char* world;                             \
};                                                             \
typedef int hello_P99_typedef_of_fl_buf_info; 
typedef char* world_P99_typedef_of_fl_buf_info

参数判断

P99_IS_ONE(first,...)可以检查first是否属于__VA_ARGS__参数列表中的一个

代码语言:javascript
复制
// 先定义一个包含所有参数名的enum
P99_DECLARE_ENUM(enum_names,tom,jerry,sam,smith,trump,bill)

    if (P99_IS_ONE(tom, jerry,sam,smith,trump,bill)) {
      // one of the guys is 23, do something special
    } else {
      // handle the base case
    }

函数声明

代码语言:javascript
复制
// 定义一个函数声明
P99_PROTOTYPE (void,hello,int,void*);

展开

代码语言:javascript
复制
void (hello)(int,void*);     \
  typedef void hello_prototype_ret;                   \
  typedef int hello_prototype_0; typedef void* hello_prototype_1

还有很多其他的功能不一一列举,参见p99手册 《P99 - Preprocessor macros and functions for C99 and C11

为了快速熟悉P99的内容建议从分类说明入手《Modules》

安装

p99提供的只是一堆头文件,所以从http://p99.gforge.inria.fr/ 这里下载p99.zipp99.tgz解压到自己的项目文件夹下,并添加到include搜索路径就算安装完成了。

建立下载说明文档p99-html.zip到本地以便随时查看,内容实在太多,不看文档搞不清楚。

参考资料

《P99_TRY》

《P99_IS_ONE》

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年06月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义enum
  • 定义struct
  • 参数判断
  • 函数声明
  • 安装
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com