一起使用盡管清理屬性是一個僅由GCC/Clang支持的擴展,我認爲它是純C中最接近RAII的擴展。爲什麼GCC/Clang的清理屬性不能與功能參數
#define loc_str __attribute__((cleanup(free_loc_str)))
void free_loc_str(char **str)
{ if(str && *str) free(*str); }
int main(void)
{
loc_str char *s = malloc(10);
return 0; // Great! s is freed when it exit its scope
}
雖然,該屬性只適用於自動範圍,但不適用於函數參數。即
void func(loc_str char *str)
{
return; // XXX - str will not be freed (compiled without any warning)
}
我已經知道上面的情況,但是,爲什麼?是否有任何理由製造這種限制?
- 更新 -
觸發此問題的一個完整的故事:
我試圖創建C.繼共享指針(或智能指針)是一個非線程安全的,簡單的代碼片段
struct impl_t;
struct impl_t* ctor();
void dtor(struct impl_t* inst);
struct shared_ptr_s
{
struct impl_t* inst;
int *use_cnt;
};
void free_shared(struct shared_ptr_s* ptr)
{
if(!ptr) return;
if(0 == --(*ptr->use_cnt)) {
dtor(ptr->inst);
free(ptr->use_cnt);
}
ptr->inst = 0;
ptr->use_cnt = 0;
}
#define shared_ptr struct shared_ptr_s __attribute__((cleanup(free_shared)))
void func(shared_ptr sp)
{
// shared_ptr loc_sp = sp; // works but make no sense
return; // sp will not be freed since cleanup function is not triggered
}
int main(void)
{
shared_ptr sp = {
.inst = ctor(),
.use_cnt = malloc(sizeof(int))
};
++*sp.use_cnt; // please bear this simplification.
{
++*sp.use_cnt;
shared_ptr sp2 = sp;
} // sp.inst is still there since use_cnt > 0
++*sp.use_cnt;
func(sp); // leak!
return 0;
}
這就是爲什麼我希望清理屬性可以使用函數參數 - 儘可能手動清除。
main'的'返回類型應該是'int'(我想你已經知道,因爲你有一個'返回0 ;'最後) – Praetorian
'loc_str char * s = malloc(10); FUNC(一個或多個);返回0;'雙免費的bug。 –
@Praetorian坦克供你修正。 – Acer