_Znwm 和 _Znam 在 C++ 中的功能是否相同?
Are the functionality of _Znwm and _Znam the same in c++?
我最近在使用 llvm,我发现 cpp 中的新语句在 llvm IR 中被翻译成 _Znam
,我知道
new
在cpp中也调用了函数_Znwm
,而new []
调用了_Znam
,那么这两个函数的功能有什么区别呢?
如果我使用 _Znwm
为数组分配 space 怎么办?
例子
a = new int*[10];
编译为
%2 = call i8* @_Znam(i64 80) #2
_Znwm
和 _Znam
只是函数的错位名称
operator new(std::size_t)
和
operator new[](std::size_t)
分别
(非放置)数组new表达式调用后者,而(非放置)非数组new表达式调用前者分配内存。
这些函数可以由用户替换,但标准库提供了默认实现。数组版本的默认实现简单地调用非数组版本,因为 C++11 和非数组版本分配传递大小的内存,以某种未指定的方式为所有非过度对齐类型适当对齐,抛出异常 std::bad_alloc
如果分配失败,否则返回一个指向分配块开头的非空指针。
所以它的行为类似于std::malloc
,除了后者returns如果分配失败是一个空指针,而不是抛出异常。默认的 operator new
实现只是在内部使用 malloc
来进行分配,这是未指定的,但很可能。
malloc
不应该调用 operator new
或 operator new[]
,所以我不知道为什么你认为它会在 IR 中转换为那个。
我认为这里没有任何特定于 LLVM 的内容。调用哪个分配函数是由C++标准规定的。只有名称以实现定义的方式被破坏。
另请注意,这些调用不是新表达式转换成的 all。在调用 operator new
/operator new[]
之后,新表达式还将在内存中构造对象,这可能需要构造函数调用值存储。
我最近在使用 llvm,我发现 cpp 中的新语句在 llvm IR 中被翻译成 _Znam
,我知道
new
在cpp中也调用了函数_Znwm
,而new []
调用了_Znam
,那么这两个函数的功能有什么区别呢?
如果我使用 _Znwm
为数组分配 space 怎么办?
例子
a = new int*[10];
编译为
%2 = call i8* @_Znam(i64 80) #2
_Znwm
和 _Znam
只是函数的错位名称
operator new(std::size_t)
和
operator new[](std::size_t)
分别
(非放置)数组new表达式调用后者,而(非放置)非数组new表达式调用前者分配内存。
这些函数可以由用户替换,但标准库提供了默认实现。数组版本的默认实现简单地调用非数组版本,因为 C++11 和非数组版本分配传递大小的内存,以某种未指定的方式为所有非过度对齐类型适当对齐,抛出异常 std::bad_alloc
如果分配失败,否则返回一个指向分配块开头的非空指针。
所以它的行为类似于std::malloc
,除了后者returns如果分配失败是一个空指针,而不是抛出异常。默认的 operator new
实现只是在内部使用 malloc
来进行分配,这是未指定的,但很可能。
malloc
不应该调用 operator new
或 operator new[]
,所以我不知道为什么你认为它会在 IR 中转换为那个。
我认为这里没有任何特定于 LLVM 的内容。调用哪个分配函数是由C++标准规定的。只有名称以实现定义的方式被破坏。
另请注意,这些调用不是新表达式转换成的 all。在调用 operator new
/operator new[]
之后,新表达式还将在内存中构造对象,这可能需要构造函数调用值存储。