GCC: __attribute__((malloc))
Цитирование из документации GCC (выделено мое):
Атрибут malloc используется, чтобы сообщить компилятору, что функция может быть обработана так, как будто любой возвращаемый ей указатель, отличный от NULL, не может иметь псевдоним любого другого указателя, действительного, когда функция возвращается и что память имеет неопределенное содержимое. Это часто улучшает оптимизацию. Стандартные функции с этим свойством включают
malloc
а такжеcalloc
,realloc
-подобные функции не имеют этого свойства, так как указанная память не имеет неопределенного содержимого.
У меня есть следующий код:
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
член, я все еще установил alloc
а также size
поля к их соответствующим значениям. Могу ли я считать этот выделенный сегмент "неопределенным содержимым" и использовать атрибут malloc?
2 ответа
Это безопасно для маркировки buffer_new
функция с __attribute__((malloc))
потому что блок, который он возвращает, не содержит указателей.
Последняя документация GCC разъясняет значение __attribute__((malloc))
: блок, возвращаемый помеченной функцией, не должен содержать указателей на другие объекты. Цель состоит в том, чтобы помочь компилятору определить, какие указатели могут указывать на один и тот же объект: атрибут сообщает GCC, что не нужно беспокоиться о том, что возвращаемый вашей функцией объект может включать указатели на что-то еще, что он отслеживает.
Вот ссылка из обзора кода на форуме Ubuntu, и да, документация должна быть улучшена https://bugs.launchpad.net/ubuntu/+source/gcc-4.7/+bug/1123588