[LLVMdev] optimization assumes malloc return is non-null

David Vandevoorde daveed at vandevoorde.com
Wed Apr 30 12:25:23 PDT 2008

On Apr 30, 2008, at 2:47 PM, Jonathan S. Shapiro wrote:
> Daveed:
> Perhaps I am looking at the wrong version of the specification.  
> Section
> appears to refer to objects having volatile-qualified type.  
> The
> type of malloc() is not volatile qualified in the standard library
> definition.

More importantly, malloc() is not specified to access a volatile  
object, modify an object, or modifying a file (directly or  
indirectly); i.e., it has no side effect from the language point of  

> In general, calls to procedures that are outside the current unit of
> compilation are presumed to involve side effects performed in the body
> of the external procedure (at least in the absence of annotation).

That may often be done in practice, but it's not a language  
requirement.  In particular, for standard library functions (like  
malloc) an optimizer can exploit the known behavior of the function.

> Can you say what version of the standard you are referencing, and  
> (just
> so I know) why section makes a call to malloc() different from
> any other procedure call with respect to side effects?

I'm looking at ISO/IEC 9899:1999.

<begin quote>
1 The semantic descriptions in this International Standard describe  
the behavior of an abstract machine in which issues of optimization  
are irrelevant.

2 Accessing a volatile object, modifying an object, modifying a file,  
or calling a function that does any of those operations are all side  
effects, [footnote bout floating-point effects] which are changes in  
the state of the execution environment. Evaluation of an expression  
may produce side effects. At certain specified points in the execution  
sequence called sequence points, all side effects of previous  
evaluations shall be complete and no side effects of subsequent  
evaluations shall have taken place. (A summary of the sequence points  
is given in annex C.)

3 In the abstract machine, all expressions are evaluated as specified  
by the semantics. An actual implementation need not evaluate part of  
an expression if it can deduce that its value is not used and that no  
needed side effects are produced (including any caused by calling a  
function or accessing a volatile object).
<end quote>

The same concept exists in C++, and we often refer to it as the "as  
if" rule; i.e., implementations can do all kinds of things, as long as  
the effect is "as if" specified by the abstract machine.


> Thanks
> Jonathan
> On Wed, 2008-04-30 at 14:29 -0400, David Vandevoorde wrote:
>> On Apr 30, 2008, at 2:10 PM, Ryan M. Lefever wrote:
>>> Consider the following c code:
>>> #include <stdlib.h>
>>> int main(int argc, char** argv){
>>>  if(malloc(sizeof(int)) == NULL){ return 0; }
>>>  else{ return 1; }
>>> }
>>> When I compile it with -O3, it produces the following bytecode:
>>> define i32 @main(i32 %argc, i8** %argv) {
>>> entry:
>>>        ret i32 1
>>> }
>>> Is this an error?  It should be possible for malloc to return  
>>> NULL, if
>>> it can not allocate more space.  In fact, some programs should be  
>>> able
>>> to gracefully handle such situations.
>> It's an allowable program transformation because a call to malloc is
>> not in itself a side effect.  See e.g. in the C standard.
>> 	Daveed
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

More information about the llvm-dev mailing list