0

I'm using llvm lately, and I found that new statements in cpp are translated to _Znam in llvm IR, I know that new in cpp also call the function _Znwm, and new [] call _Znam, so what's the difference between the functionality of these two functions? What if I use _Znwm to allocate space for an array?

Example

a = new int*[10];

is compiled as

%2 = call i8* @_Znam(i64 80) #2
yujie6
  • 103
  • 3
  • 1
    Does this answer your question? [llinking @\_Znam and @\_Znwm](https://stackoverflow.com/questions/14301899/llinking-znam-and-znwm) – ggorlen Mar 22 '20 at 04:01
  • Well, I checked that question before. But what I want to know is the difference between them. Specifically, what 's the difference between their behaviours when allocating space. – yujie6 Mar 22 '20 at 04:10
  • @yujie6 These functions are user-replaceable, but in the default library implementation, if not replaced by the user, they behave identically. Since C++11, the array version is supposed to just call the non-array version in the default implementation. Please edit your question to specify in detail what you want to know to avoid the close-as-duplicate votes. – walnut Mar 22 '20 at 04:14

1 Answers1

0

_Znwm and _Znam are just mangled names for the functions

operator new(std::size_t)

and

operator new[](std::size_t)

respectively.

An (non-placement) array new expression calls the latter, while a (non-placement) non-array new expression calls the former to allocate memory.

These functions can be replaced by the user, but a default implementation is provided by the standard library. The default implementation of the array version simply calls the non-array version since C++11 and the non-array version allocates memory of the passed size, aligned suitably for all non-overaligned types, in some unspecified way, throwing the exception std::bad_alloc if allocation fails and otherwise returning a non-null pointer to the beginning of the allocated block.

So it behaves similar to std::malloc, except that the latter returns a null pointer if allocation fails, rather than throwing an exception. It is unspecified, but likely, that the default operator new implementation just uses malloc internally to do the allocation.

malloc should not call operator new or operator new[], so I don't know why you think that it would translate to that in IR.

I don't think there is anything LLVM-specific here. Which allocation function is called is specified by the C++ standard. Only the names are mangled in an implementation-defined manner.

Also note that these calls are not all that the new expressions translate to. After calling operator new/operator new[] the new expression will also construct objects in the memory, which may require constructor calls to stores of values.

walnut
  • 21,629
  • 4
  • 23
  • 59