2013-04-18 38 views
2

我有一个函数宏来检查,如果一个函数的返回值被检查

void *custom_get_value(ObjectPtr) 

此功能传统上从未使用过返回NULL.It可以返回以下任何一个值的

uint32_t 
int32_t 
uint64_t 
int64_t 
uint8_t 

由于函数从未使用返回NULL我有很多的代码,不会

 *(uint32_t*)custom_get_value(ObjectPtr) 

        OR 

     *(uint64_t*)custom_get_value(ObjectPtr) 

近日w^E具有决定修改的

void *custom_get_value(ObjectPtr) in such a way that it can return NULL.So all occourances of the above scenario (de-referencing to specific types without checking the return value) can result in segmentation fault. 

我可以使用一些宏观的行为idendify出代码中的

void *custom_get_value(ObjectPtr) 

返回值是不是被checked.If是怎么做我所有的地方去做?

回答

2

您不容易编写一个宏,它可以跟踪返回值后发生的情况,因为数据流分析超出了预处理器的能力。然而,旨在帮助如上述这种情况,这是定义要检查作为一种自我指涉的微距功能的有用的技术:

#define custom_get_value(...) (0, custom_get_value(__VA_ARGS__)) 

这个例子本身并不做任何事情,但是它展示了一些有用的东西:当宏名称作为其自己的替换列表的一部分出现时,名称的嵌套出现是“被涂成蓝色”并且不会再次扩展。因此,通过将现有的函数名称定义为宏,您可以“包装”(或“建议”)该函数的所有现有调用 - 大概分散在未知数量的代码中 - 除了保留原始调用。

这时你有几种选择,如:

#define custom_get_value(...) ({ \ 
    _Pragma("message \"custom_get_value called\""); \ 
    custom_get_value(__VA_ARGS__); \ 
}) 

...如果你是在GCC或铛,应该列出每一个地方custom_get_value被称为点的文件和行号,在编译时。 (#pragma message和声明表达式表单都是非标准的GCC扩展 - 但是如果您只是在清理旧调用时使用此功能,那么这可能没有关系?一旦检查完所有调用,就可以删除非标准代码。)

或替代应用运行时消息:

#define custom_get_value(...) \ 
    custom_wrap(custom_get_value(__VA_ARGS__), __FILE__, __LINE__) 

void * custom_wrap(void * val, char * f, int l) { 
    printf("custom_get_value called in %s on line %d\n", f, l); return val; 
} 

...这将推动你疯了每一个函数被调用时打印的消息,但至少为标准。

你甚至可以用一个函数来包装所有的调用,这个函数会使得到的指针再次保证为非空,尽管这可能不是处理这种情况的最好方法。

0

将新功能命名为custom_get_value_ex并删除旧功能。然后你的编译器会非常好地指出旧函数的所有用途,所以你可以查看它们。

当您更改已使用的函数的语义时,通常最好查看对函数的所有调用。也许你可以将这些调用的一部分包装在一个更易维护的包装中,例如:

inline uint32_t custom_get_uint32(.....) 
{ 
    void *value = custom_get_value(.....); 
    if (!value) 
      return 0; // or some other error handling 
    return *(uint32_t *)value; 
} 

然后,如果你再次改变custom_get_value,你只需要狐狸这个包装。

即使整洁。将有一个功能让你感兴趣的项目:

inline uint32_t get_propeller_setting(.....) 
{ 
    void *value = custom_get_value(PROPELLER_SETTING,........) 
    // .... 
} 

然后你就可以有当每个价值得到一个空指针返回的特定处理。

相关问题