Are compilers allowed to optimize-out realloc?












37















I came across a situation where it would be useful to have unnecessary calls to realloc being optimized out. However, it seems like neither clang nor gcc do such a thing (godbolt). - Although I see optimizations being made with multiple calls to malloc.



The example:



void *myfunc() {
void *data;
data = malloc(100);
data = realloc(data, 200);
return data;
}


I expected it to be optimized to something like the following:



void *myfunc() {
return malloc(200);
}


Why is neither clang nor gcc optimizing it out? - Are they not allowed to do so?










share|improve this question




















  • 10





    I would be really surprised it a compiler was allowed to remove calls to external functions. What if you link with your own library that implements malloc?

    – Gerhardh
    Nov 19 '18 at 11:26






  • 10





    @Gerhardh malloc is not an external function, it's a part of the standard library. Compilers are allowed to inline it or otherwise implement it however they wish.

    – n.m.
    Nov 19 '18 at 12:04






  • 10





    @Lundin: It is not true that a compiler is not allowed to optimize out a function call if the function contains any side effects. A compiler is not allowed to optimize away observable behavior. If a side effect (and its consequences) is not observable, it may be removed.

    – Eric Postpischil
    Nov 19 '18 at 12:38








  • 3





    @Lundin It would make sense, but, why are two consecutive calls to malloc/free optimized out (godbolt.org/z/gBVXcp)? That wouldn't be allowed if it had a side effect, would it?

    – Julius
    Nov 19 '18 at 12:49








  • 12





    @Lundin: An unobservable side effect is not needed.

    – Eric Postpischil
    Nov 19 '18 at 12:56
















37















I came across a situation where it would be useful to have unnecessary calls to realloc being optimized out. However, it seems like neither clang nor gcc do such a thing (godbolt). - Although I see optimizations being made with multiple calls to malloc.



The example:



void *myfunc() {
void *data;
data = malloc(100);
data = realloc(data, 200);
return data;
}


I expected it to be optimized to something like the following:



void *myfunc() {
return malloc(200);
}


Why is neither clang nor gcc optimizing it out? - Are they not allowed to do so?










share|improve this question




















  • 10





    I would be really surprised it a compiler was allowed to remove calls to external functions. What if you link with your own library that implements malloc?

    – Gerhardh
    Nov 19 '18 at 11:26






  • 10





    @Gerhardh malloc is not an external function, it's a part of the standard library. Compilers are allowed to inline it or otherwise implement it however they wish.

    – n.m.
    Nov 19 '18 at 12:04






  • 10





    @Lundin: It is not true that a compiler is not allowed to optimize out a function call if the function contains any side effects. A compiler is not allowed to optimize away observable behavior. If a side effect (and its consequences) is not observable, it may be removed.

    – Eric Postpischil
    Nov 19 '18 at 12:38








  • 3





    @Lundin It would make sense, but, why are two consecutive calls to malloc/free optimized out (godbolt.org/z/gBVXcp)? That wouldn't be allowed if it had a side effect, would it?

    – Julius
    Nov 19 '18 at 12:49








  • 12





    @Lundin: An unobservable side effect is not needed.

    – Eric Postpischil
    Nov 19 '18 at 12:56














37












37








37


7






I came across a situation where it would be useful to have unnecessary calls to realloc being optimized out. However, it seems like neither clang nor gcc do such a thing (godbolt). - Although I see optimizations being made with multiple calls to malloc.



The example:



void *myfunc() {
void *data;
data = malloc(100);
data = realloc(data, 200);
return data;
}


I expected it to be optimized to something like the following:



void *myfunc() {
return malloc(200);
}


Why is neither clang nor gcc optimizing it out? - Are they not allowed to do so?










share|improve this question
















I came across a situation where it would be useful to have unnecessary calls to realloc being optimized out. However, it seems like neither clang nor gcc do such a thing (godbolt). - Although I see optimizations being made with multiple calls to malloc.



The example:



void *myfunc() {
void *data;
data = malloc(100);
data = realloc(data, 200);
return data;
}


I expected it to be optimized to something like the following:



void *myfunc() {
return malloc(200);
}


Why is neither clang nor gcc optimizing it out? - Are they not allowed to do so?







c gcc clang language-lawyer compiler-optimization






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 12:00









Florian Weimer

16.1k31145




16.1k31145










asked Nov 19 '18 at 11:14









JuliusJulius

42028




42028








  • 10





    I would be really surprised it a compiler was allowed to remove calls to external functions. What if you link with your own library that implements malloc?

    – Gerhardh
    Nov 19 '18 at 11:26






  • 10





    @Gerhardh malloc is not an external function, it's a part of the standard library. Compilers are allowed to inline it or otherwise implement it however they wish.

    – n.m.
    Nov 19 '18 at 12:04






  • 10





    @Lundin: It is not true that a compiler is not allowed to optimize out a function call if the function contains any side effects. A compiler is not allowed to optimize away observable behavior. If a side effect (and its consequences) is not observable, it may be removed.

    – Eric Postpischil
    Nov 19 '18 at 12:38








  • 3





    @Lundin It would make sense, but, why are two consecutive calls to malloc/free optimized out (godbolt.org/z/gBVXcp)? That wouldn't be allowed if it had a side effect, would it?

    – Julius
    Nov 19 '18 at 12:49








  • 12





    @Lundin: An unobservable side effect is not needed.

    – Eric Postpischil
    Nov 19 '18 at 12:56














  • 10





    I would be really surprised it a compiler was allowed to remove calls to external functions. What if you link with your own library that implements malloc?

    – Gerhardh
    Nov 19 '18 at 11:26






  • 10





    @Gerhardh malloc is not an external function, it's a part of the standard library. Compilers are allowed to inline it or otherwise implement it however they wish.

    – n.m.
    Nov 19 '18 at 12:04






  • 10





    @Lundin: It is not true that a compiler is not allowed to optimize out a function call if the function contains any side effects. A compiler is not allowed to optimize away observable behavior. If a side effect (and its consequences) is not observable, it may be removed.

    – Eric Postpischil
    Nov 19 '18 at 12:38








  • 3





    @Lundin It would make sense, but, why are two consecutive calls to malloc/free optimized out (godbolt.org/z/gBVXcp)? That wouldn't be allowed if it had a side effect, would it?

    – Julius
    Nov 19 '18 at 12:49








  • 12





    @Lundin: An unobservable side effect is not needed.

    – Eric Postpischil
    Nov 19 '18 at 12:56








10




10





I would be really surprised it a compiler was allowed to remove calls to external functions. What if you link with your own library that implements malloc?

– Gerhardh
Nov 19 '18 at 11:26





I would be really surprised it a compiler was allowed to remove calls to external functions. What if you link with your own library that implements malloc?

– Gerhardh
Nov 19 '18 at 11:26




10




10





@Gerhardh malloc is not an external function, it's a part of the standard library. Compilers are allowed to inline it or otherwise implement it however they wish.

– n.m.
Nov 19 '18 at 12:04





@Gerhardh malloc is not an external function, it's a part of the standard library. Compilers are allowed to inline it or otherwise implement it however they wish.

– n.m.
Nov 19 '18 at 12:04




10




10





@Lundin: It is not true that a compiler is not allowed to optimize out a function call if the function contains any side effects. A compiler is not allowed to optimize away observable behavior. If a side effect (and its consequences) is not observable, it may be removed.

– Eric Postpischil
Nov 19 '18 at 12:38







@Lundin: It is not true that a compiler is not allowed to optimize out a function call if the function contains any side effects. A compiler is not allowed to optimize away observable behavior. If a side effect (and its consequences) is not observable, it may be removed.

– Eric Postpischil
Nov 19 '18 at 12:38






3




3





@Lundin It would make sense, but, why are two consecutive calls to malloc/free optimized out (godbolt.org/z/gBVXcp)? That wouldn't be allowed if it had a side effect, would it?

– Julius
Nov 19 '18 at 12:49







@Lundin It would make sense, but, why are two consecutive calls to malloc/free optimized out (godbolt.org/z/gBVXcp)? That wouldn't be allowed if it had a side effect, would it?

– Julius
Nov 19 '18 at 12:49






12




12





@Lundin: An unobservable side effect is not needed.

– Eric Postpischil
Nov 19 '18 at 12:56





@Lundin: An unobservable side effect is not needed.

– Eric Postpischil
Nov 19 '18 at 12:56












5 Answers
5






active

oldest

votes


















25















Are they not allowed to do so?




Maybe, but optimization not done in this case may be due to corner functional differences.





If 150 bytes of allocatable memory remain,
data = malloc(100); data = realloc(data, 200); returns NULL with 100 bytes consumed (and leaked) and 50 remain.



data = malloc(200); returns NULL with 0 bytes consumed (none leaked) and 150 remain.



Different functionality in this narrow case may prevent optimization.






Are compilers allowed to optimize-out realloc?




Perhaps - I would expect it is allowed. Yet it may not be worth the effect to enhance the compiler to determine when it can.



Successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory.



It might be beyond that compiler's design to ensure ..., even if empty code, did not set any memory.






share|improve this answer





















  • 3





    I was thinking of that as well. However, this example shows that a realloc between prevents the malloc/free from being optimized out. If you remove it, the compiler will optimize-out the malloc and free. - and as far as I can see there will be no difference in the result?

    – Julius
    Nov 19 '18 at 13:19








  • 2





    @Julius Per this code , I see no reason disbarring optimization. Yet consider if both codes started with char *data = malloc(100); if (data == NULL) { return NULL; } *data = 1, the functions are different. With realloc() copying the first 100 bytes, the compiler may not see that copying uninitialized was not important in your code. BTW: 2nd compiler is C++ not C. Suggest comparing C to C.

    – chux
    Nov 19 '18 at 17:21








  • 1





    @Julius IOWs, successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory. It might be beyond that compiler's design to insure ... code did not set any memory.

    – chux
    Nov 19 '18 at 17:37






  • 2





    @chux That's an interesting thought. I could imagine it to be quite difficult to prove that there were no changes to the specific memory region in some cases - although it is most likely simple in other cases.

    – Julius
    Nov 19 '18 at 17:47






  • 2





    How does malloc(n); ... realloc(p, 2*n) differ from malloc(2*n); ...?

    – Andrew Svietlichnyy
    Nov 19 '18 at 20:38



















10














A compiler which bundles its own self-contained versions of malloc/calloc/free/realloc could legitimately perform the indicated optimization if the authors thought doing so was worth the effort. A compiler that chains to externally-supplied functions could still perform such optimizations if it documented that it did not regard the precise sequence of calls to such functions as an observable side-effect, but such treatment could be a bit more tenuous.



If no storage is allocated or deallocated between the malloc() and realloc(), the size of the realloc() is known when the malloc() is performed, and the realloc() size is larger than the malloc() size, then it may make sense to consolidate the malloc() and realloc() operations into a single larger allocation. If the state of memory could change in the interim, however, then such an optimization might cause the failure of operations that should have succeeded. For example, given the sequence:



void *p1 = malloc(2000000000);
void *p2 = malloc(2);
free(p1);
p2 = realloc(p2, 2000000000);


a system might not have 2000000000 bytes available for p2 until after p1 is freed. If it were to change the code to:



void *p1 = malloc(2000000000);
void *p2 = malloc(2000000000);
free(p1);


that would result in the allocation of p2 failing. Because the Standard never guarantees that allocation requests will succeed, such behavior would not be non-conforming. On the other hand, the following would also be a "conforming" implementation:



void *malloc(size_t size) { return 0; }
void *calloc(size_t size, size_t count) { return 0; }
void free(void *p) { }
void *realloc(void *p, size_t size) { return 0; }


Such an implementation might arguably be regarded as more "efficient" than most others, but one would have to be rather obtuse to regard it as being very useful except, perhaps, in rare situations where the above functions are are called on code paths that are never executed.



I think the Standard would clearly allow the optimization, at least in cases that are as simple as those in the original question. Even in cases where it might cause operations to fail that could otherwise have succeeded, the Standard would still allow it. Most likely, the reason that many compilers don't perform the optimization is that the authors didn't think the benefits would be sufficient to justify the effort required to identify cases where it would be safe and useful.






share|improve this answer
























  • Standards wise, no. C99 and C11 explicitly state the old object is deallocated and a new object is returned. Even with a private allocator the compiler cannot predict at compile time the pointer to a new allocation.

    – Greg A. Woods
    Nov 19 '18 at 20:50








  • 1





    @GregA.Woods: Under the as-if rule, a compiler would be allowed to consolidate the operations if the resulting behavior could have resulted from doing the operations separately. By what standard-defined means could a program observe whether realloc actually did anything other than yield a pointer to an allocation that might have already been as big as requested?

    – supercat
    Nov 19 '18 at 21:12






  • 1





    I suppose if the compiler's own allocator was known to always initially allocate more, say ten times as much, space as is required, and if the compiler could predict at compile time that the the allocated object's desired size was X, and also predict that the new size passed to realloc() was less than 10X then it could assume the object would not change location. However I don't know if the optimization would still be allowed by the current standard. Perhaps.

    – Greg A. Woods
    Nov 19 '18 at 21:48



















4














The compiler is allowed to optimize out multiple calls to functions which are considered pure functions, i.e. functions that do not have any side-effects.



So the question is whether realloc() is a pure function or not.



The C11 Standard Committee Draft N1570 states this about the realloc function:




7.22.3.5 The realloc function

...

2. The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.



Returns

4. The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.




Notice that the compiler cannot predict at compile time the value of the pointer that will be returned on each call.



This means that realloc() cannot be considered a pure function and multiple calls to it cannot be optimized out by the compiler.






share|improve this answer


























  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Yvette Colomb
    Nov 20 '18 at 16:11



















1














But you're not checking the return value of the first malloc() which you're then using in the second realloc(). It could just as well be NULL.



How could the compiler optimize the two calls into a single one without making unwarranted assumptions about the return value of the first?



Then there is another possible scenario. FreeBSD used to have a realloc() which was basically malloc + memcpy + free the old pointer.



Suppose that there are only 230 bytes left of free memory. In that implementation, ptr = malloc(100) followed by realloc(ptr, 200) will fail, but a single malloc(200) will succeed.






share|improve this answer
























  • You are right about the checking, but I have submitted at least one example in the comments which include checking the return value - it doesn't seem to make a difference. Actually, the compiler does make such assumptions sometimes which I could demonstrate.

    – Julius
    Nov 20 '18 at 7:59





















0














My understanding is that such an optimization might be forbidden (notably for the -indeed unlikely- case where the malloc succeeds but the following  realloc fails).



You could suppose that malloc and realloc always succeed (that is against the C11 standard, n1570; look also into my joke-implementation of malloc). In that hypothesis (stricto sensu wrong, but some Linux systems have memory overcommitment to give that illusion), if you use GCC, you might write your own GCC plugin to make such an optimization.



I am not sure it is worth spending a few weeks or months to code such a GCC plugin (in practice, you probably want it to handle sometimes some code between malloc and realloc, and then it is not that simple, since you have to characterize and detect what such in-between code is acceptable), but that choice is yours.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53373421%2fare-compilers-allowed-to-optimize-out-realloc%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    25















    Are they not allowed to do so?




    Maybe, but optimization not done in this case may be due to corner functional differences.





    If 150 bytes of allocatable memory remain,
    data = malloc(100); data = realloc(data, 200); returns NULL with 100 bytes consumed (and leaked) and 50 remain.



    data = malloc(200); returns NULL with 0 bytes consumed (none leaked) and 150 remain.



    Different functionality in this narrow case may prevent optimization.






    Are compilers allowed to optimize-out realloc?




    Perhaps - I would expect it is allowed. Yet it may not be worth the effect to enhance the compiler to determine when it can.



    Successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory.



    It might be beyond that compiler's design to ensure ..., even if empty code, did not set any memory.






    share|improve this answer





















    • 3





      I was thinking of that as well. However, this example shows that a realloc between prevents the malloc/free from being optimized out. If you remove it, the compiler will optimize-out the malloc and free. - and as far as I can see there will be no difference in the result?

      – Julius
      Nov 19 '18 at 13:19








    • 2





      @Julius Per this code , I see no reason disbarring optimization. Yet consider if both codes started with char *data = malloc(100); if (data == NULL) { return NULL; } *data = 1, the functions are different. With realloc() copying the first 100 bytes, the compiler may not see that copying uninitialized was not important in your code. BTW: 2nd compiler is C++ not C. Suggest comparing C to C.

      – chux
      Nov 19 '18 at 17:21








    • 1





      @Julius IOWs, successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory. It might be beyond that compiler's design to insure ... code did not set any memory.

      – chux
      Nov 19 '18 at 17:37






    • 2





      @chux That's an interesting thought. I could imagine it to be quite difficult to prove that there were no changes to the specific memory region in some cases - although it is most likely simple in other cases.

      – Julius
      Nov 19 '18 at 17:47






    • 2





      How does malloc(n); ... realloc(p, 2*n) differ from malloc(2*n); ...?

      – Andrew Svietlichnyy
      Nov 19 '18 at 20:38
















    25















    Are they not allowed to do so?




    Maybe, but optimization not done in this case may be due to corner functional differences.





    If 150 bytes of allocatable memory remain,
    data = malloc(100); data = realloc(data, 200); returns NULL with 100 bytes consumed (and leaked) and 50 remain.



    data = malloc(200); returns NULL with 0 bytes consumed (none leaked) and 150 remain.



    Different functionality in this narrow case may prevent optimization.






    Are compilers allowed to optimize-out realloc?




    Perhaps - I would expect it is allowed. Yet it may not be worth the effect to enhance the compiler to determine when it can.



    Successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory.



    It might be beyond that compiler's design to ensure ..., even if empty code, did not set any memory.






    share|improve this answer





















    • 3





      I was thinking of that as well. However, this example shows that a realloc between prevents the malloc/free from being optimized out. If you remove it, the compiler will optimize-out the malloc and free. - and as far as I can see there will be no difference in the result?

      – Julius
      Nov 19 '18 at 13:19








    • 2





      @Julius Per this code , I see no reason disbarring optimization. Yet consider if both codes started with char *data = malloc(100); if (data == NULL) { return NULL; } *data = 1, the functions are different. With realloc() copying the first 100 bytes, the compiler may not see that copying uninitialized was not important in your code. BTW: 2nd compiler is C++ not C. Suggest comparing C to C.

      – chux
      Nov 19 '18 at 17:21








    • 1





      @Julius IOWs, successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory. It might be beyond that compiler's design to insure ... code did not set any memory.

      – chux
      Nov 19 '18 at 17:37






    • 2





      @chux That's an interesting thought. I could imagine it to be quite difficult to prove that there were no changes to the specific memory region in some cases - although it is most likely simple in other cases.

      – Julius
      Nov 19 '18 at 17:47






    • 2





      How does malloc(n); ... realloc(p, 2*n) differ from malloc(2*n); ...?

      – Andrew Svietlichnyy
      Nov 19 '18 at 20:38














    25












    25








    25








    Are they not allowed to do so?




    Maybe, but optimization not done in this case may be due to corner functional differences.





    If 150 bytes of allocatable memory remain,
    data = malloc(100); data = realloc(data, 200); returns NULL with 100 bytes consumed (and leaked) and 50 remain.



    data = malloc(200); returns NULL with 0 bytes consumed (none leaked) and 150 remain.



    Different functionality in this narrow case may prevent optimization.






    Are compilers allowed to optimize-out realloc?




    Perhaps - I would expect it is allowed. Yet it may not be worth the effect to enhance the compiler to determine when it can.



    Successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory.



    It might be beyond that compiler's design to ensure ..., even if empty code, did not set any memory.






    share|improve this answer
















    Are they not allowed to do so?




    Maybe, but optimization not done in this case may be due to corner functional differences.





    If 150 bytes of allocatable memory remain,
    data = malloc(100); data = realloc(data, 200); returns NULL with 100 bytes consumed (and leaked) and 50 remain.



    data = malloc(200); returns NULL with 0 bytes consumed (none leaked) and 150 remain.



    Different functionality in this narrow case may prevent optimization.






    Are compilers allowed to optimize-out realloc?




    Perhaps - I would expect it is allowed. Yet it may not be worth the effect to enhance the compiler to determine when it can.



    Successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory.



    It might be beyond that compiler's design to ensure ..., even if empty code, did not set any memory.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Dec 14 '18 at 11:22









    DaveInCaz

    3,22931938




    3,22931938










    answered Nov 19 '18 at 13:14









    chuxchux

    82.9k872149




    82.9k872149








    • 3





      I was thinking of that as well. However, this example shows that a realloc between prevents the malloc/free from being optimized out. If you remove it, the compiler will optimize-out the malloc and free. - and as far as I can see there will be no difference in the result?

      – Julius
      Nov 19 '18 at 13:19








    • 2





      @Julius Per this code , I see no reason disbarring optimization. Yet consider if both codes started with char *data = malloc(100); if (data == NULL) { return NULL; } *data = 1, the functions are different. With realloc() copying the first 100 bytes, the compiler may not see that copying uninitialized was not important in your code. BTW: 2nd compiler is C++ not C. Suggest comparing C to C.

      – chux
      Nov 19 '18 at 17:21








    • 1





      @Julius IOWs, successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory. It might be beyond that compiler's design to insure ... code did not set any memory.

      – chux
      Nov 19 '18 at 17:37






    • 2





      @chux That's an interesting thought. I could imagine it to be quite difficult to prove that there were no changes to the specific memory region in some cases - although it is most likely simple in other cases.

      – Julius
      Nov 19 '18 at 17:47






    • 2





      How does malloc(n); ... realloc(p, 2*n) differ from malloc(2*n); ...?

      – Andrew Svietlichnyy
      Nov 19 '18 at 20:38














    • 3





      I was thinking of that as well. However, this example shows that a realloc between prevents the malloc/free from being optimized out. If you remove it, the compiler will optimize-out the malloc and free. - and as far as I can see there will be no difference in the result?

      – Julius
      Nov 19 '18 at 13:19








    • 2





      @Julius Per this code , I see no reason disbarring optimization. Yet consider if both codes started with char *data = malloc(100); if (data == NULL) { return NULL; } *data = 1, the functions are different. With realloc() copying the first 100 bytes, the compiler may not see that copying uninitialized was not important in your code. BTW: 2nd compiler is C++ not C. Suggest comparing C to C.

      – chux
      Nov 19 '18 at 17:21








    • 1





      @Julius IOWs, successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory. It might be beyond that compiler's design to insure ... code did not set any memory.

      – chux
      Nov 19 '18 at 17:37






    • 2





      @chux That's an interesting thought. I could imagine it to be quite difficult to prove that there were no changes to the specific memory region in some cases - although it is most likely simple in other cases.

      – Julius
      Nov 19 '18 at 17:47






    • 2





      How does malloc(n); ... realloc(p, 2*n) differ from malloc(2*n); ...?

      – Andrew Svietlichnyy
      Nov 19 '18 at 20:38








    3




    3





    I was thinking of that as well. However, this example shows that a realloc between prevents the malloc/free from being optimized out. If you remove it, the compiler will optimize-out the malloc and free. - and as far as I can see there will be no difference in the result?

    – Julius
    Nov 19 '18 at 13:19







    I was thinking of that as well. However, this example shows that a realloc between prevents the malloc/free from being optimized out. If you remove it, the compiler will optimize-out the malloc and free. - and as far as I can see there will be no difference in the result?

    – Julius
    Nov 19 '18 at 13:19






    2




    2





    @Julius Per this code , I see no reason disbarring optimization. Yet consider if both codes started with char *data = malloc(100); if (data == NULL) { return NULL; } *data = 1, the functions are different. With realloc() copying the first 100 bytes, the compiler may not see that copying uninitialized was not important in your code. BTW: 2nd compiler is C++ not C. Suggest comparing C to C.

    – chux
    Nov 19 '18 at 17:21







    @Julius Per this code , I see no reason disbarring optimization. Yet consider if both codes started with char *data = malloc(100); if (data == NULL) { return NULL; } *data = 1, the functions are different. With realloc() copying the first 100 bytes, the compiler may not see that copying uninitialized was not important in your code. BTW: 2nd compiler is C++ not C. Suggest comparing C to C.

    – chux
    Nov 19 '18 at 17:21






    1




    1





    @Julius IOWs, successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory. It might be beyond that compiler's design to insure ... code did not set any memory.

    – chux
    Nov 19 '18 at 17:37





    @Julius IOWs, successful malloc(n); ... realloc(p, 2*n) differs from malloc(2*n); when ... may have set some of the memory. It might be beyond that compiler's design to insure ... code did not set any memory.

    – chux
    Nov 19 '18 at 17:37




    2




    2





    @chux That's an interesting thought. I could imagine it to be quite difficult to prove that there were no changes to the specific memory region in some cases - although it is most likely simple in other cases.

    – Julius
    Nov 19 '18 at 17:47





    @chux That's an interesting thought. I could imagine it to be quite difficult to prove that there were no changes to the specific memory region in some cases - although it is most likely simple in other cases.

    – Julius
    Nov 19 '18 at 17:47




    2




    2





    How does malloc(n); ... realloc(p, 2*n) differ from malloc(2*n); ...?

    – Andrew Svietlichnyy
    Nov 19 '18 at 20:38





    How does malloc(n); ... realloc(p, 2*n) differ from malloc(2*n); ...?

    – Andrew Svietlichnyy
    Nov 19 '18 at 20:38













    10














    A compiler which bundles its own self-contained versions of malloc/calloc/free/realloc could legitimately perform the indicated optimization if the authors thought doing so was worth the effort. A compiler that chains to externally-supplied functions could still perform such optimizations if it documented that it did not regard the precise sequence of calls to such functions as an observable side-effect, but such treatment could be a bit more tenuous.



    If no storage is allocated or deallocated between the malloc() and realloc(), the size of the realloc() is known when the malloc() is performed, and the realloc() size is larger than the malloc() size, then it may make sense to consolidate the malloc() and realloc() operations into a single larger allocation. If the state of memory could change in the interim, however, then such an optimization might cause the failure of operations that should have succeeded. For example, given the sequence:



    void *p1 = malloc(2000000000);
    void *p2 = malloc(2);
    free(p1);
    p2 = realloc(p2, 2000000000);


    a system might not have 2000000000 bytes available for p2 until after p1 is freed. If it were to change the code to:



    void *p1 = malloc(2000000000);
    void *p2 = malloc(2000000000);
    free(p1);


    that would result in the allocation of p2 failing. Because the Standard never guarantees that allocation requests will succeed, such behavior would not be non-conforming. On the other hand, the following would also be a "conforming" implementation:



    void *malloc(size_t size) { return 0; }
    void *calloc(size_t size, size_t count) { return 0; }
    void free(void *p) { }
    void *realloc(void *p, size_t size) { return 0; }


    Such an implementation might arguably be regarded as more "efficient" than most others, but one would have to be rather obtuse to regard it as being very useful except, perhaps, in rare situations where the above functions are are called on code paths that are never executed.



    I think the Standard would clearly allow the optimization, at least in cases that are as simple as those in the original question. Even in cases where it might cause operations to fail that could otherwise have succeeded, the Standard would still allow it. Most likely, the reason that many compilers don't perform the optimization is that the authors didn't think the benefits would be sufficient to justify the effort required to identify cases where it would be safe and useful.






    share|improve this answer
























    • Standards wise, no. C99 and C11 explicitly state the old object is deallocated and a new object is returned. Even with a private allocator the compiler cannot predict at compile time the pointer to a new allocation.

      – Greg A. Woods
      Nov 19 '18 at 20:50








    • 1





      @GregA.Woods: Under the as-if rule, a compiler would be allowed to consolidate the operations if the resulting behavior could have resulted from doing the operations separately. By what standard-defined means could a program observe whether realloc actually did anything other than yield a pointer to an allocation that might have already been as big as requested?

      – supercat
      Nov 19 '18 at 21:12






    • 1





      I suppose if the compiler's own allocator was known to always initially allocate more, say ten times as much, space as is required, and if the compiler could predict at compile time that the the allocated object's desired size was X, and also predict that the new size passed to realloc() was less than 10X then it could assume the object would not change location. However I don't know if the optimization would still be allowed by the current standard. Perhaps.

      – Greg A. Woods
      Nov 19 '18 at 21:48
















    10














    A compiler which bundles its own self-contained versions of malloc/calloc/free/realloc could legitimately perform the indicated optimization if the authors thought doing so was worth the effort. A compiler that chains to externally-supplied functions could still perform such optimizations if it documented that it did not regard the precise sequence of calls to such functions as an observable side-effect, but such treatment could be a bit more tenuous.



    If no storage is allocated or deallocated between the malloc() and realloc(), the size of the realloc() is known when the malloc() is performed, and the realloc() size is larger than the malloc() size, then it may make sense to consolidate the malloc() and realloc() operations into a single larger allocation. If the state of memory could change in the interim, however, then such an optimization might cause the failure of operations that should have succeeded. For example, given the sequence:



    void *p1 = malloc(2000000000);
    void *p2 = malloc(2);
    free(p1);
    p2 = realloc(p2, 2000000000);


    a system might not have 2000000000 bytes available for p2 until after p1 is freed. If it were to change the code to:



    void *p1 = malloc(2000000000);
    void *p2 = malloc(2000000000);
    free(p1);


    that would result in the allocation of p2 failing. Because the Standard never guarantees that allocation requests will succeed, such behavior would not be non-conforming. On the other hand, the following would also be a "conforming" implementation:



    void *malloc(size_t size) { return 0; }
    void *calloc(size_t size, size_t count) { return 0; }
    void free(void *p) { }
    void *realloc(void *p, size_t size) { return 0; }


    Such an implementation might arguably be regarded as more "efficient" than most others, but one would have to be rather obtuse to regard it as being very useful except, perhaps, in rare situations where the above functions are are called on code paths that are never executed.



    I think the Standard would clearly allow the optimization, at least in cases that are as simple as those in the original question. Even in cases where it might cause operations to fail that could otherwise have succeeded, the Standard would still allow it. Most likely, the reason that many compilers don't perform the optimization is that the authors didn't think the benefits would be sufficient to justify the effort required to identify cases where it would be safe and useful.






    share|improve this answer
























    • Standards wise, no. C99 and C11 explicitly state the old object is deallocated and a new object is returned. Even with a private allocator the compiler cannot predict at compile time the pointer to a new allocation.

      – Greg A. Woods
      Nov 19 '18 at 20:50








    • 1





      @GregA.Woods: Under the as-if rule, a compiler would be allowed to consolidate the operations if the resulting behavior could have resulted from doing the operations separately. By what standard-defined means could a program observe whether realloc actually did anything other than yield a pointer to an allocation that might have already been as big as requested?

      – supercat
      Nov 19 '18 at 21:12






    • 1





      I suppose if the compiler's own allocator was known to always initially allocate more, say ten times as much, space as is required, and if the compiler could predict at compile time that the the allocated object's desired size was X, and also predict that the new size passed to realloc() was less than 10X then it could assume the object would not change location. However I don't know if the optimization would still be allowed by the current standard. Perhaps.

      – Greg A. Woods
      Nov 19 '18 at 21:48














    10












    10








    10







    A compiler which bundles its own self-contained versions of malloc/calloc/free/realloc could legitimately perform the indicated optimization if the authors thought doing so was worth the effort. A compiler that chains to externally-supplied functions could still perform such optimizations if it documented that it did not regard the precise sequence of calls to such functions as an observable side-effect, but such treatment could be a bit more tenuous.



    If no storage is allocated or deallocated between the malloc() and realloc(), the size of the realloc() is known when the malloc() is performed, and the realloc() size is larger than the malloc() size, then it may make sense to consolidate the malloc() and realloc() operations into a single larger allocation. If the state of memory could change in the interim, however, then such an optimization might cause the failure of operations that should have succeeded. For example, given the sequence:



    void *p1 = malloc(2000000000);
    void *p2 = malloc(2);
    free(p1);
    p2 = realloc(p2, 2000000000);


    a system might not have 2000000000 bytes available for p2 until after p1 is freed. If it were to change the code to:



    void *p1 = malloc(2000000000);
    void *p2 = malloc(2000000000);
    free(p1);


    that would result in the allocation of p2 failing. Because the Standard never guarantees that allocation requests will succeed, such behavior would not be non-conforming. On the other hand, the following would also be a "conforming" implementation:



    void *malloc(size_t size) { return 0; }
    void *calloc(size_t size, size_t count) { return 0; }
    void free(void *p) { }
    void *realloc(void *p, size_t size) { return 0; }


    Such an implementation might arguably be regarded as more "efficient" than most others, but one would have to be rather obtuse to regard it as being very useful except, perhaps, in rare situations where the above functions are are called on code paths that are never executed.



    I think the Standard would clearly allow the optimization, at least in cases that are as simple as those in the original question. Even in cases where it might cause operations to fail that could otherwise have succeeded, the Standard would still allow it. Most likely, the reason that many compilers don't perform the optimization is that the authors didn't think the benefits would be sufficient to justify the effort required to identify cases where it would be safe and useful.






    share|improve this answer













    A compiler which bundles its own self-contained versions of malloc/calloc/free/realloc could legitimately perform the indicated optimization if the authors thought doing so was worth the effort. A compiler that chains to externally-supplied functions could still perform such optimizations if it documented that it did not regard the precise sequence of calls to such functions as an observable side-effect, but such treatment could be a bit more tenuous.



    If no storage is allocated or deallocated between the malloc() and realloc(), the size of the realloc() is known when the malloc() is performed, and the realloc() size is larger than the malloc() size, then it may make sense to consolidate the malloc() and realloc() operations into a single larger allocation. If the state of memory could change in the interim, however, then such an optimization might cause the failure of operations that should have succeeded. For example, given the sequence:



    void *p1 = malloc(2000000000);
    void *p2 = malloc(2);
    free(p1);
    p2 = realloc(p2, 2000000000);


    a system might not have 2000000000 bytes available for p2 until after p1 is freed. If it were to change the code to:



    void *p1 = malloc(2000000000);
    void *p2 = malloc(2000000000);
    free(p1);


    that would result in the allocation of p2 failing. Because the Standard never guarantees that allocation requests will succeed, such behavior would not be non-conforming. On the other hand, the following would also be a "conforming" implementation:



    void *malloc(size_t size) { return 0; }
    void *calloc(size_t size, size_t count) { return 0; }
    void free(void *p) { }
    void *realloc(void *p, size_t size) { return 0; }


    Such an implementation might arguably be regarded as more "efficient" than most others, but one would have to be rather obtuse to regard it as being very useful except, perhaps, in rare situations where the above functions are are called on code paths that are never executed.



    I think the Standard would clearly allow the optimization, at least in cases that are as simple as those in the original question. Even in cases where it might cause operations to fail that could otherwise have succeeded, the Standard would still allow it. Most likely, the reason that many compilers don't perform the optimization is that the authors didn't think the benefits would be sufficient to justify the effort required to identify cases where it would be safe and useful.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 19 '18 at 17:25









    supercatsupercat

    56.9k3117151




    56.9k3117151













    • Standards wise, no. C99 and C11 explicitly state the old object is deallocated and a new object is returned. Even with a private allocator the compiler cannot predict at compile time the pointer to a new allocation.

      – Greg A. Woods
      Nov 19 '18 at 20:50








    • 1





      @GregA.Woods: Under the as-if rule, a compiler would be allowed to consolidate the operations if the resulting behavior could have resulted from doing the operations separately. By what standard-defined means could a program observe whether realloc actually did anything other than yield a pointer to an allocation that might have already been as big as requested?

      – supercat
      Nov 19 '18 at 21:12






    • 1





      I suppose if the compiler's own allocator was known to always initially allocate more, say ten times as much, space as is required, and if the compiler could predict at compile time that the the allocated object's desired size was X, and also predict that the new size passed to realloc() was less than 10X then it could assume the object would not change location. However I don't know if the optimization would still be allowed by the current standard. Perhaps.

      – Greg A. Woods
      Nov 19 '18 at 21:48



















    • Standards wise, no. C99 and C11 explicitly state the old object is deallocated and a new object is returned. Even with a private allocator the compiler cannot predict at compile time the pointer to a new allocation.

      – Greg A. Woods
      Nov 19 '18 at 20:50








    • 1





      @GregA.Woods: Under the as-if rule, a compiler would be allowed to consolidate the operations if the resulting behavior could have resulted from doing the operations separately. By what standard-defined means could a program observe whether realloc actually did anything other than yield a pointer to an allocation that might have already been as big as requested?

      – supercat
      Nov 19 '18 at 21:12






    • 1





      I suppose if the compiler's own allocator was known to always initially allocate more, say ten times as much, space as is required, and if the compiler could predict at compile time that the the allocated object's desired size was X, and also predict that the new size passed to realloc() was less than 10X then it could assume the object would not change location. However I don't know if the optimization would still be allowed by the current standard. Perhaps.

      – Greg A. Woods
      Nov 19 '18 at 21:48

















    Standards wise, no. C99 and C11 explicitly state the old object is deallocated and a new object is returned. Even with a private allocator the compiler cannot predict at compile time the pointer to a new allocation.

    – Greg A. Woods
    Nov 19 '18 at 20:50







    Standards wise, no. C99 and C11 explicitly state the old object is deallocated and a new object is returned. Even with a private allocator the compiler cannot predict at compile time the pointer to a new allocation.

    – Greg A. Woods
    Nov 19 '18 at 20:50






    1




    1





    @GregA.Woods: Under the as-if rule, a compiler would be allowed to consolidate the operations if the resulting behavior could have resulted from doing the operations separately. By what standard-defined means could a program observe whether realloc actually did anything other than yield a pointer to an allocation that might have already been as big as requested?

    – supercat
    Nov 19 '18 at 21:12





    @GregA.Woods: Under the as-if rule, a compiler would be allowed to consolidate the operations if the resulting behavior could have resulted from doing the operations separately. By what standard-defined means could a program observe whether realloc actually did anything other than yield a pointer to an allocation that might have already been as big as requested?

    – supercat
    Nov 19 '18 at 21:12




    1




    1





    I suppose if the compiler's own allocator was known to always initially allocate more, say ten times as much, space as is required, and if the compiler could predict at compile time that the the allocated object's desired size was X, and also predict that the new size passed to realloc() was less than 10X then it could assume the object would not change location. However I don't know if the optimization would still be allowed by the current standard. Perhaps.

    – Greg A. Woods
    Nov 19 '18 at 21:48





    I suppose if the compiler's own allocator was known to always initially allocate more, say ten times as much, space as is required, and if the compiler could predict at compile time that the the allocated object's desired size was X, and also predict that the new size passed to realloc() was less than 10X then it could assume the object would not change location. However I don't know if the optimization would still be allowed by the current standard. Perhaps.

    – Greg A. Woods
    Nov 19 '18 at 21:48











    4














    The compiler is allowed to optimize out multiple calls to functions which are considered pure functions, i.e. functions that do not have any side-effects.



    So the question is whether realloc() is a pure function or not.



    The C11 Standard Committee Draft N1570 states this about the realloc function:




    7.22.3.5 The realloc function

    ...

    2. The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.



    Returns

    4. The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.




    Notice that the compiler cannot predict at compile time the value of the pointer that will be returned on each call.



    This means that realloc() cannot be considered a pure function and multiple calls to it cannot be optimized out by the compiler.






    share|improve this answer


























    • Comments are not for extended discussion; this conversation has been moved to chat.

      – Yvette Colomb
      Nov 20 '18 at 16:11
















    4














    The compiler is allowed to optimize out multiple calls to functions which are considered pure functions, i.e. functions that do not have any side-effects.



    So the question is whether realloc() is a pure function or not.



    The C11 Standard Committee Draft N1570 states this about the realloc function:




    7.22.3.5 The realloc function

    ...

    2. The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.



    Returns

    4. The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.




    Notice that the compiler cannot predict at compile time the value of the pointer that will be returned on each call.



    This means that realloc() cannot be considered a pure function and multiple calls to it cannot be optimized out by the compiler.






    share|improve this answer


























    • Comments are not for extended discussion; this conversation has been moved to chat.

      – Yvette Colomb
      Nov 20 '18 at 16:11














    4












    4








    4







    The compiler is allowed to optimize out multiple calls to functions which are considered pure functions, i.e. functions that do not have any side-effects.



    So the question is whether realloc() is a pure function or not.



    The C11 Standard Committee Draft N1570 states this about the realloc function:




    7.22.3.5 The realloc function

    ...

    2. The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.



    Returns

    4. The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.




    Notice that the compiler cannot predict at compile time the value of the pointer that will be returned on each call.



    This means that realloc() cannot be considered a pure function and multiple calls to it cannot be optimized out by the compiler.






    share|improve this answer















    The compiler is allowed to optimize out multiple calls to functions which are considered pure functions, i.e. functions that do not have any side-effects.



    So the question is whether realloc() is a pure function or not.



    The C11 Standard Committee Draft N1570 states this about the realloc function:




    7.22.3.5 The realloc function

    ...

    2. The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.



    Returns

    4. The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.




    Notice that the compiler cannot predict at compile time the value of the pointer that will be returned on each call.



    This means that realloc() cannot be considered a pure function and multiple calls to it cannot be optimized out by the compiler.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 20 '18 at 5:16

























    answered Nov 19 '18 at 12:00









    P.WP.W

    14k31248




    14k31248













    • Comments are not for extended discussion; this conversation has been moved to chat.

      – Yvette Colomb
      Nov 20 '18 at 16:11



















    • Comments are not for extended discussion; this conversation has been moved to chat.

      – Yvette Colomb
      Nov 20 '18 at 16:11

















    Comments are not for extended discussion; this conversation has been moved to chat.

    – Yvette Colomb
    Nov 20 '18 at 16:11





    Comments are not for extended discussion; this conversation has been moved to chat.

    – Yvette Colomb
    Nov 20 '18 at 16:11











    1














    But you're not checking the return value of the first malloc() which you're then using in the second realloc(). It could just as well be NULL.



    How could the compiler optimize the two calls into a single one without making unwarranted assumptions about the return value of the first?



    Then there is another possible scenario. FreeBSD used to have a realloc() which was basically malloc + memcpy + free the old pointer.



    Suppose that there are only 230 bytes left of free memory. In that implementation, ptr = malloc(100) followed by realloc(ptr, 200) will fail, but a single malloc(200) will succeed.






    share|improve this answer
























    • You are right about the checking, but I have submitted at least one example in the comments which include checking the return value - it doesn't seem to make a difference. Actually, the compiler does make such assumptions sometimes which I could demonstrate.

      – Julius
      Nov 20 '18 at 7:59


















    1














    But you're not checking the return value of the first malloc() which you're then using in the second realloc(). It could just as well be NULL.



    How could the compiler optimize the two calls into a single one without making unwarranted assumptions about the return value of the first?



    Then there is another possible scenario. FreeBSD used to have a realloc() which was basically malloc + memcpy + free the old pointer.



    Suppose that there are only 230 bytes left of free memory. In that implementation, ptr = malloc(100) followed by realloc(ptr, 200) will fail, but a single malloc(200) will succeed.






    share|improve this answer
























    • You are right about the checking, but I have submitted at least one example in the comments which include checking the return value - it doesn't seem to make a difference. Actually, the compiler does make such assumptions sometimes which I could demonstrate.

      – Julius
      Nov 20 '18 at 7:59
















    1












    1








    1







    But you're not checking the return value of the first malloc() which you're then using in the second realloc(). It could just as well be NULL.



    How could the compiler optimize the two calls into a single one without making unwarranted assumptions about the return value of the first?



    Then there is another possible scenario. FreeBSD used to have a realloc() which was basically malloc + memcpy + free the old pointer.



    Suppose that there are only 230 bytes left of free memory. In that implementation, ptr = malloc(100) followed by realloc(ptr, 200) will fail, but a single malloc(200) will succeed.






    share|improve this answer













    But you're not checking the return value of the first malloc() which you're then using in the second realloc(). It could just as well be NULL.



    How could the compiler optimize the two calls into a single one without making unwarranted assumptions about the return value of the first?



    Then there is another possible scenario. FreeBSD used to have a realloc() which was basically malloc + memcpy + free the old pointer.



    Suppose that there are only 230 bytes left of free memory. In that implementation, ptr = malloc(100) followed by realloc(ptr, 200) will fail, but a single malloc(200) will succeed.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 20 '18 at 6:41









    pizdelectpizdelect

    1191




    1191













    • You are right about the checking, but I have submitted at least one example in the comments which include checking the return value - it doesn't seem to make a difference. Actually, the compiler does make such assumptions sometimes which I could demonstrate.

      – Julius
      Nov 20 '18 at 7:59





















    • You are right about the checking, but I have submitted at least one example in the comments which include checking the return value - it doesn't seem to make a difference. Actually, the compiler does make such assumptions sometimes which I could demonstrate.

      – Julius
      Nov 20 '18 at 7:59



















    You are right about the checking, but I have submitted at least one example in the comments which include checking the return value - it doesn't seem to make a difference. Actually, the compiler does make such assumptions sometimes which I could demonstrate.

    – Julius
    Nov 20 '18 at 7:59







    You are right about the checking, but I have submitted at least one example in the comments which include checking the return value - it doesn't seem to make a difference. Actually, the compiler does make such assumptions sometimes which I could demonstrate.

    – Julius
    Nov 20 '18 at 7:59













    0














    My understanding is that such an optimization might be forbidden (notably for the -indeed unlikely- case where the malloc succeeds but the following  realloc fails).



    You could suppose that malloc and realloc always succeed (that is against the C11 standard, n1570; look also into my joke-implementation of malloc). In that hypothesis (stricto sensu wrong, but some Linux systems have memory overcommitment to give that illusion), if you use GCC, you might write your own GCC plugin to make such an optimization.



    I am not sure it is worth spending a few weeks or months to code such a GCC plugin (in practice, you probably want it to handle sometimes some code between malloc and realloc, and then it is not that simple, since you have to characterize and detect what such in-between code is acceptable), but that choice is yours.






    share|improve this answer




























      0














      My understanding is that such an optimization might be forbidden (notably for the -indeed unlikely- case where the malloc succeeds but the following  realloc fails).



      You could suppose that malloc and realloc always succeed (that is against the C11 standard, n1570; look also into my joke-implementation of malloc). In that hypothesis (stricto sensu wrong, but some Linux systems have memory overcommitment to give that illusion), if you use GCC, you might write your own GCC plugin to make such an optimization.



      I am not sure it is worth spending a few weeks or months to code such a GCC plugin (in practice, you probably want it to handle sometimes some code between malloc and realloc, and then it is not that simple, since you have to characterize and detect what such in-between code is acceptable), but that choice is yours.






      share|improve this answer


























        0












        0








        0







        My understanding is that such an optimization might be forbidden (notably for the -indeed unlikely- case where the malloc succeeds but the following  realloc fails).



        You could suppose that malloc and realloc always succeed (that is against the C11 standard, n1570; look also into my joke-implementation of malloc). In that hypothesis (stricto sensu wrong, but some Linux systems have memory overcommitment to give that illusion), if you use GCC, you might write your own GCC plugin to make such an optimization.



        I am not sure it is worth spending a few weeks or months to code such a GCC plugin (in practice, you probably want it to handle sometimes some code between malloc and realloc, and then it is not that simple, since you have to characterize and detect what such in-between code is acceptable), but that choice is yours.






        share|improve this answer













        My understanding is that such an optimization might be forbidden (notably for the -indeed unlikely- case where the malloc succeeds but the following  realloc fails).



        You could suppose that malloc and realloc always succeed (that is against the C11 standard, n1570; look also into my joke-implementation of malloc). In that hypothesis (stricto sensu wrong, but some Linux systems have memory overcommitment to give that illusion), if you use GCC, you might write your own GCC plugin to make such an optimization.



        I am not sure it is worth spending a few weeks or months to code such a GCC plugin (in practice, you probably want it to handle sometimes some code between malloc and realloc, and then it is not that simple, since you have to characterize and detect what such in-between code is acceptable), but that choice is yours.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 14 '18 at 11:32









        Basile StarynkevitchBasile Starynkevitch

        178k13170366




        178k13170366






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53373421%2fare-compilers-allowed-to-optimize-out-realloc%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Academy of Television Arts & Sciences

            L'Équipe

            1995 France bombings