← Back to context

Comment by aw1621107

2 months ago

> Again, could you please explain how compiler can decide to remove call to a function in an external dynamically loaded library, that is not known at compile time, simply based on the name of the function (i.e. not because the call is unreachable)? I do not see any such language in the standard.

> And yes, calling unknown function from a dynamically loaded library totally is a side effect.

The thing is that malloc/free aren't "unknown function[s]". From the C89 standard:

> All external identifiers declared in any of the headers are reserved, whether or not the associated header is included.

And from the C23 standard:

> All identifiers with external linkage in any of the following subclauses (including the future library directions) and errno are always reserved for use as identifiers with external linkage

malloc/free are defined in <stdlib.h> and so are reserved names, so compilers are able to optimize under the assumption that malloc/free will have the semantics dictated by the standard.

In fact, the C23 standard explicitly provides an example of this kind of thing:

> Because external identifiers and some macro names beginning with an underscore are reserved, implementations can provide special semantics for such names. For example, the identifier _BUILTIN_abs could be used to indicate generation of in-line code for the abs function. Thus, the appropriate header could specify

    #define abs(x) _BUILTIN_abs(x)

> for a compiler whose code generator will accept it.