Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Clang is too clever and gives malloc the correct implicit declaration even when you don't have an explicit prototype:

    test.c:10:12: warning: implicitly declaring library function 'malloc' with type 'void *(unsigned long)'
      [-Wimplicit-function-declaration]
I think that having a prototype mismatch with the actual declared function is undefined behavior, so this is a legal way to resolve it, but not every compiler will. Older compilers tended to treat malloc as just another function and wouldn't do this.

I was able to replicate the older behavior by wrapping malloc in my own function. In one file:

    int main()
    {
        int* p;
        p = (int*)wrapped_malloc(sizeof(int));
        *p = 10;
        return 0;
    }
    
And in another file:

    void *wrapped_malloc(int size) {
        return malloc(size);
    }
Compiling them into one program results in a crash. The relevant bit of assembly is:

    0000000100000f4f	movslq	%eax, %rdi
So it is indeed only extracting the lower 32 bits of the returned pointer.

The page looks pretty old (the IA-64 reference sure is dated, anyway) so I'd guess that it was referring to an older compiler that didn't have a special case for malloc like this.



Right, C compilers will automatically known it's part of libc. You didn't need to do the separate file thing, you could just have the wrapper and it will trigger the movslq, or a cltq.


With the wrapper in the same file, clang threw an error because the definition conflicted with the implied prototype.


Doesn't happen for me. Both GCC and Clang compile it fine.


Strange. Here's my erroring code:

    int main()
    {
        int* p;
        p = (int*)wrapped_malloc(sizeof(int));
        *p = 10;
        return 0;
    }
    
    void *wrapped_malloc(int size) {
        return malloc(size);
    }
And the actual error:

    test.c:9:11: error: conflicting types for 'wrapped_malloc'
        void *wrapped_malloc(int size) {
              ^
    test.c:4:19: note: previous implicit declaration is here
            p = (int*)wrapped_malloc(sizeof(int));
Are you doing anything differently?


Try putting wrapped_malloc above main. Or at least declaring it above main.


If it's above main then there's no longer an implicit prototype and you're no longer replicating the problem.


No, I am not sure why this happens.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: