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

2019-05-25 22:22:00 浏览数 (2)

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/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 %sn",__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.zip或p99.tgz解压到自己的项目文件夹下,并添加到include搜索路径就算安装完成了。

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

参考资料

《P99_TRY》

《P99_IS_ONE》

0 人点赞