为什么c++使用memset(addr,0,sizeof(T))来构造一个对象?标准或编译器错误?

2023-12-09

这个问题和我的另一篇文章有​​关:为什么 allocate_shared 和 make_shared 这么慢

在这里我可以更清楚地描述这个问题。

考虑下面的代码:

struct A {
    char data_[0x10000];
};

class C {
public:
    C() : a_() { }
    A a_;
};

int main() {
    C c;
    return 0;
}

我找到了代码C() : a_(),编译器使用memset(addr,0,0x10000)作为 A 的构造函数。如果类型 A 有一个空构造函数,则 asm 代码是正确的。

为了更清楚地描述问题,我写了一些测试代码:

#include <stdlib.h>

struct A {
    //A() {}
    char data_[0x10000];
    void dummy() { // avoid optimize erase by compiler
        data_[rand() % sizeof(data_)] = 1;
    }
    int dummy2() { // avoid optimize erase by compiler
        return data_[0];
    }
};

class B {
public:
    template<class ... T> B(T&...t) 
        : a_(std::forward<T>(t)...) {
    }
    A a_;
};

class C {
public:
    C() : a_() {
    }
    A a_;
};

template<class ... T>
int test(T&...t) {
    A a(t...);
    a.dummy();
    return a.dummy2();
}

int main() {
    A a;
    a.dummy();
    auto r1 = a.dummy2();

    auto r2 = test();

    B b;
    b.a_.dummy();
    auto r3 = b.a_.dummy2();

    C c;
    c.a_.dummy();
    auto r4 = c.a_.dummy2();
    return r1 + r2 + r3 + r4;
}

我使用 vs2017 在 Windows 10 x86 发行版本中编译了代码。 然后我检查了asm代码:

template<class ... T>
int test(T&...t) {
00E510B8  call        _chkstk (0E51CE0h)  
00E510BD  mov         eax,dword ptr [__security_cookie (0E53004h)]  
00E510C2  xor         eax,ebp  
00E510C4  mov         dword ptr [ebp-4],eax  
    A a(t...);
00E510C7  push        10000h  
00E510CC  lea         eax,[a]  
00E510D2  push        0  
00E510D4  push        eax  
00E510D5  call        _memset (0E51C3Ah)  
00E510DA  add         esp,0Ch  
    a.dummy();
00E510DD  call        dword ptr [__imp__rand (0E520B4h)]  
}
00E510E3  mov         ecx,dword ptr [ebp-4]  

功能很清楚了test() calls memset(p, 0, 0x10000).

如果我在 A 中添加一个空构造函数(行A(){}),编译器删除 memset。

那么为什么当类型 A 没有构造函数时代码会调用 memset 而当 A 有构造函数时代码不会调用 memset 呢?

它是 C++ 标准的一部分,还是只是一个编译器错误?

显然 memset(p, 0, sizeof(T)) 是无用且有害的,它会减慢程序速度。我该如何解决这个问题?


A a(t...);

Will be parsed as initializing a with t.... When t... is empty, as when you call it, this will be understood as value-initializing a.

For A没有用户提供的默认构造函数,值初始化是将其所有成员归零,因此memset.

当您提供构造函数时A, 值初始化是调用默认构造函数,您定义它不执行任何操作,因此不memset将被调用。

这不是编译器中的错误,这是必需的行为。去除多余的memset,你可以写A a;。在这种情况下a is 默认初始化无论有或没有用户提供的构造函数,都不会发生自动归零。

† This is important since A a() will be parsed as a function called a with return type A

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么c++使用memset(addr,0,sizeof(T))来构造一个对象?标准或编译器错误? 的相关文章

  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

  • Joomla 模块可以“知道”它所处的位置吗?

    我对 Joomla 相当陌生 我更喜欢 WordPress 我有一个关于模块位置的问题 模块可以知道它所处的位置吗 例如我可以这样做 if modulePosition left Do this else Do that 这看起来很简单 但
  • 如何将存储为bigint的Java时间戳转换为Presto中的时间戳?

    几天来我一直没有找到这个 如果我的 hive 表中数据的 avro 模式是 type record name messages namespace com company messages fields name timeStamp typ
  • ZF2 表单中的按钮内容

    如何编辑 ZF2 表单的 Button 元素的按钮内容 我可以设置一个标签 但我想在其中插入一些 html 代码 this gt add array type gt Button name gt submit options gt arra
  • 使用 async 时,bcrypt.hash 函数返回 undefined,但与 .then 一起工作正常

    这是异步代码 返回undefined userService register username password gt return bcrypt hash password saltRounds async err hash gt co
  • 在 Windows 窗体中以编程方式添加新的用户控件

    嘿 首先我想指出 我知道这里还有关于这个主题的其他几个问题 我什至以前自己也做过这件事 我在这里问是因为我不知道我的问题是什么 这是我尝试显示新用户控件的代码 private void ValidationLabel Click objec
  • 使用 jQuery 更改下拉列表的选定值

    我有一个包含已知值的下拉列表 我想做的是将下拉列表设置为我知道存在的特定值jQuery 使用常规JavaScript 我会做类似的事情 ddl document getElementById ID of element goes here
  • 我们可以将 Laravel 项目作为库集成到 CodeIgniter 中吗?

    我想通过集成一些用 laravel 编写的代码来增加 CodeIgniter 项目的功能 我该如何接近 我可以通过 CodeIgniter 库包含代码吗 如果是的话怎么办 我只想将控制器和 ORM 包含到 CI 中 Laravel 代码是一
  • R 中 apply 中的 equal() 行为

    这很奇怪 apply matrix c 1 NA 2 3 NA NA 2 4 ncol 2 1 function x identical x 1 x 2 1 FALSE TRUE TRUE FALSE apply data frame a
  • 在这种情况下,iPhone 上的“发布”是什么意思?

    我想问一个关于 iPhone 应用程序的愚蠢问题 我是iPhone应用程序的绿色 我在Apple网站上阅读了以下代码 MyViewController aViewController MyViewController alloc initW
  • 设计模式 - 理解外观模式

    我是设计模式的新手 正在尝试了解它们通常的样子 现在我正在尝试理解外观模式 我觉得外观模式是一个相当广泛的概念 所以我想知道我的第二个图是否会被视为外观模板的一部分 我知道一个典型的外观模式基本上是这样的 A 级是外观 但是如果我们有一个更
  • 密钥不得包含 . pymongo 中的错误

    我试图通过 pymongo 获取 serverStatus 命令的输出 然后将其插入到 mongodb 集合中 这是字典 u metrics u getLastError u wtime u num 0 u totalMillis 0 u
  • PHP Constant() 不适用于名称空间?

    以下不起作用 use application components auditor AuditLevel public function actionAudit data unserialize POST data message data
  • 如何更新由另一个组合框触发的组合框中的值?

    我的表单中有 2 个组合框 我希望在组合框 2 中的列表更新时更改组合框 1 中的选定值 例如 ComboBox1 包含移动公司的名称 ComboBox2 包含该公司的所有手机列表 假设您有一个将手机型号与其制造商关联起来的字典 Dicti
  • 流星:云中

    我正在尝试上传 Lepozepo cloudinary 的照片 这是我的服务器和客户端配置 server Cloudinary config cloud name api key api secret client cloudinary c
  • UIViewController 的背景到分组表视图颜色

    在 UITableView 分组样式中 表格视图的背景有点像浅灰色的纹理颜色 如何获取该值以便将 UIViewController 的整个背景设置为该颜色 如果您正在为 iPhone 和 iPod touch 进 行开发 UIColor定义
  • 搜索文本文件并插入行

    我想要做的是 以下面的文本为例 在文本文件中搜索字符串 Text2 然后在 Text 2 后两行插入一行 插入文本 文本 2 可以位于文本文件中的任何行 但我知道它会在文本文件中出现一次 所以这是原始文件 Text1 Text2 Text3
  • 从存档导出 ipa 时 Xcode 9 崩溃

    我在 Xcode 9 中为任何项目创建了一个存档 然后我尝试创建一个 ipa 文件 开发文件或临时文件 我首先尝试导出存档 然后我选择 开发 或 临时分发 Xcode 9 崩溃 我什至在应用程序的 info plist 中添加了 编译位码
  • 向函数发送 stderr/stdout 消息并捕获退出信号

    我正在处理错误处理并登录我的 bash 脚本 下面我提供了一个简化的代码片段来举例说明用例 我想在我的脚本中实现以下目标 陷阱退出信号应触发下面代码中的 onexit 函数 stderr 和 stdout 应发送到 log 函数 该函数将确
  • R 中的嵌套 if-else 循环

    我有一个名为 crimes 的数据框 其中包含一个 pre rate 列 表示实施特定法律之前的犯罪率 我想使用嵌套的 if else 循环将每个费率放入 rate category 列中 我有以下代码 crimes rate catego
  • 为什么c++使用memset(addr,0,sizeof(T))来构造一个对象?标准或编译器错误?

    这个问题和我的另一篇文章有 关 为什么 allocate shared 和 make shared 这么慢 在这里我可以更清楚地描述这个问题 考虑下面的代码 struct A char data 0x10000 class C public