15

Quoting from GCC documentation (emphasis mine):

The malloc attribute is used to tell the compiler that a function may be treated as if any non-NULL pointer it returns cannot alias any other pointer valid when the function returns and that the memory has undefined content. This often improves optimization. Standard functions with this property include malloc and calloc. realloc-like functions do not have this property as the memory pointed to does not have undefined content.

I have the following code:

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;
}

Now I'm a bit puzzled here: though I didn't initialize the data member, I still set the alloc and size fields to their respective values. Can I still consider this allocated segment to be of "undefined content" and use the malloc attribute?

peter.slizik
  • 2,015
  • 1
  • 17
  • 29
  • 6
    I think you're misunderstanding the meaning of the attribute. For example, `calloc` returns memory with well-defined content. – Kerrek SB Aug 28 '13 at 10:42
  • 4
    @KerrekSB since the attribute explicitly states the content is undefined, and since `calloc`'s memory is very plainly defined, I think I must be misunderstanding something too... could you expand on this? – mah Aug 28 '13 at 10:47
  • 9
    I think the attribute is for assisting with aliasing analysis. The compiler can assume that the returned memory does *not* contain, say, the pointer to an existing object. – Kerrek SB Aug 28 '13 at 10:53
  • 3
    @Kerrek Seams reasonable. I think the manual's wording is quite unfortunate. – peter.slizik Aug 28 '13 at 11:02
  • 3
    Probably a good question to some gcc developers list (to improve that document) – dbrank0 Aug 28 '13 at 11:04

2 Answers2

22

It is safe to mark your buffer_new function with __attribute__((malloc)), because the block it returns contains no pointers.

The latest GCC documentation clarifies the meaning of __attribute__((malloc)): the block returned by a function so marked must not contain any pointers to other objects. The intention is to help the compiler estimate which pointers might possibly point into the same object: the attribute tells GCC it needn't worry that the object your function returns might include pointers to something else it's tracking.

sparticvs
  • 562
  • 5
  • 14
Jim Blandy
  • 1,536
  • 10
  • 17
  • Yes, I can confirm that having pointers in a memory area allocated in a function marked with the attribute is a bad thing. I had a Heisenbug in a double linked list code that I searched for quite some time now. – Patrick Schlüter Oct 06 '17 at 16:27
1

Here is a link from a code review in the Ubuntu forum and yes the documentation needs to be improved https://bugs.launchpad.net/ubuntu/+source/gcc-4.7/+bug/1123588

Parag Paul
  • 51
  • 7