GCC: __attribute__((malloc))

15

引用自GCC文档(重点是我的):

malloc属性用于告诉编译器,一个函数可能会被处理为,任何它返回的非空指针在函数返回时不能与任何有效的其他指针别名,并且该内存的内容是未定义的。这通常可以提高优化效果。具有此属性的标准函数包括malloccallocrealloc-like函数没有此属性,因为所指向的内存没有未定义的内容。

我有以下代码:

struct buffer {
    size_t alloc;  // Allocated memory in bytes
    size_t size;   // Actual data size in bytes
    char data[];   // Flexible array member
};


#define ARRAY_SIZE <initial_value>

buffer *buffer_new(void) __attribute__((malloc))
{
    struct buffer *ret;

    ret = malloc(sizeof(struct buffer) + ARRAY_SIZE);
    if (!ret)
        fatal(E_OUT_OF_MEMORY);

    ret->alloc = ARRAY_SIZE;
    ret->size = 0;

    return ret;
}

现在我有些困惑:虽然我没有初始化data成员,但我仍将allocsize字段设置为它们各自的值。我是否仍然可以将此分配段视为“未定义内容”并使用malloc属性?


6
我认为你误解了这个属性的意思。比如,calloc 返回具有明确定义内容的内存。 - Kerrek SB
4
@KerrekSB,由于属性明确声明内容未定义,而calloc的内存非常明确定义,因此我认为我也可能存在误解...您能否详细说明一下? - mah
9
我认为这个属性用于辅助别名分析。编译器可以假设返回的内存不包含指向现有对象的指针,以便进行代码优化。 - Kerrek SB
3
@Kerrek 听起来很合理。我认为手册的措辞相当不幸。 - peter.slizik
3
或许向一些GCC开发人员的名单提出这个问题是一个不错的选择(以改进该文档)。 - dbrank0
2个回答

23

您可以将 buffer_new 函数标记为 __attribute__((malloc)),因为它返回的块不包含指针。

最新的 GCC 文档阐明了 __attribute__((malloc)) 的含义:被此标记的函数返回的块不得包含指向其他对象的任何指针。其意图是帮助编译器估计哪些指针可能指向同一对象:该属性告诉 GCC 不必担心您的函数返回的对象可能包含指向其他正在追踪的东西的指针。


是的,我可以确认在一个用属性标记的函数中分配内存区域并存在指针是一件不好的事情。我的双向链表代码出现了一个难以捉摸的bug,我花费了相当长的时间去寻找它。 - Patrick Schlüter

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接