gcc:如何正确使用 __attribute((__may_alias__)) 以避免“取消引用类型双关指针”警告

2024-01-28

我有一些代码使用类型双关来避免调用成员“对象”的构造函数和析构函数,除非/直到实际上需要使用该对象。

它工作正常,但在 g++ 4.4.3 下,我收到这个可怕的编译器警告:

jaf@jeremy-desktop:~$ g++ -O3 -Wall puns.cpp 
puns.cpp: In instantiation of ‘Lightweight<Heavyweight>’:
puns.cpp:68:   instantiated from here 
puns.cpp:12: warning: ignoring attributes applied to ‘Heavyweight’ after definition
puns.cpp: In destructor ‘Lightweight<T>::~Lightweight() [with T = Heavyweight]’:
puns.cpp:68:   instantiated from here
puns.cpp:20: warning: dereferencing type-punned pointer will break strict-aliasing rules
puns.cpp: In member function ‘void Lightweight<T>::MethodThatGetsCalledRarely() [with T = Heavyweight]’:
puns.cpp:70:   instantiated from here
puns.cpp:36: warning: dereferencing type-punned pointer will break strict-aliasing rules

我的代码尝试使用 gcc 的 __attribute((__may_alias__)) 让 gcc 了解潜在的别名,但 gcc 似乎不理解我想告诉它的内容。我是否做错了什么,或者 gcc 4.4.3 只是在 __may_alias__ 属性上存在一些问题?

重现编译器警告的玩具代码如下:

#include <stdio.h>
#include <memory>    // for placement new
#include <stdlib.h>  // for rand()

/** Templated class that I want to be quick to construct and destroy.
  * In particular, I don't want to have T's constructor called unless
  * I actually need it, and I also don't want to use dynamic allocation.
  **/
template<class T> class Lightweight
{
private:
   typedef T __attribute((__may_alias__)) T_may_alias;

public:
   Lightweight() : _isObjectConstructed(false) {/* empty */}

   ~Lightweight()
   {
      // call object's destructor, only if we ever constructed it
      if (_isObjectConstructed) (reinterpret_cast<T_may_alias *>(_optionalObject._buf))->~T_may_alias();
   }

   void MethodThatGetsCalledOften()
   {
      // Imagine some useful code here
   }

   void MethodThatGetsCalledRarely()
   {
      if (_isObjectConstructed == false)
      {
         // demand-construct the heavy object, since we actually need to use it now
         (void) new (reinterpret_cast<T_may_alias *>(_optionalObject._buf)) T();
         _isObjectConstructed = true;
      }
      (reinterpret_cast<T_may_alias *>(_optionalObject._buf))->DoSomething();
   }

private:
   union {
      char _buf[sizeof(T)];
      unsigned long long _thisIsOnlyHereToForceEightByteAlignment;
   } _optionalObject;

   bool _isObjectConstructed;
};

static int _iterationCounter = 0;
static int _heavyCounter     = 0;

/** Example of a class that takes (relatively) a lot of resources to construct or destroy. */
class Heavyweight
{
public:
   Heavyweight()
   {
      printf("Heavyweight constructor, this is an expensive call!\n");
      _heavyCounter++;
   }

   void DoSomething() {/* Imagine some useful code here*/}
};

static void SomeMethod()
{
   _iterationCounter++;

   Lightweight<Heavyweight> obj;
   if ((rand()%1000) != 0) obj.MethodThatGetsCalledOften();
                      else obj.MethodThatGetsCalledRarely();
}

int main(int argc, char ** argv)
{
   for (int i=0; i<1000; i++) SomeMethod();
   printf("Heavyweight ctor was executed only %i times out of %i iterations, we avoid %.1f%% of the ctor calls!.\n", _heavyCounter, _iterationCounter, 100.0f*(1.0f-(((float)_heavyCounter)/((float)_iterationCounter))));
   return 0;
}

我觉得typedef令人困惑的是海湾合作委员会。当直接应用于变量定义时,这些类型的属性似乎效果最好。

你的这个版本的课程适合我(GCC 4.6.0):

template<class T> class Lightweight
{
private:
  //  typedef T __attribute((__may_alias__)) T_may_alias;

public:
  Lightweight() : _isObjectConstructed(false) {/* empty */}

  ~Lightweight()
  {
    // call object's destructor, only if we ever constructed it
    if (_isObjectConstructed) {
      T * __attribute__((__may_alias__)) p
        = (reinterpret_cast<T *>(_optionalObject._buf));
      p->~T();
    }
  }

  void MethodThatGetsCalledOften()
  {
    // Imagine some useful code here
  }

  void MethodThatGetsCalledRarely()
  {
    T * __attribute__((__may_alias__)) p
      = (reinterpret_cast<T *>(_optionalObject._buf));
    if (_isObjectConstructed == false)
      {
        // demand-construct the heavy object, since we actually need to use it now

        (void) new (p) T();
        _isObjectConstructed = true;
      }
      p->DoSomething();
  }

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

gcc:如何正确使用 __attribute((__may_alias__)) 以避免“取消引用类型双关指针”警告 的相关文章

  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • 进程何时获得 SIGABRT(信号 6)?

    C 中进程获得 SIGABRT 的场景有哪些 该信号是否始终来自进程内部 或者该信号可以从一个进程发送到另一个进程吗 有没有办法识别哪个进程正在发送该信号 abort 向调用进程发送SIGABRT信号 就是这样abort 基本上有效 abo
  • 使用具有现有访问令牌的 Google API .NET 客户端

    用例如下 移动应用程序正在通过 Google 对用户进行身份验证 并且在某些时候 我们需要将用户的视频发布到他的 YouTube 帐户 出于实际原因 实际发布应该由后端完成 已经存储在那里的大文件 由于用户已经通过应用程序的身份验证 因此应
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • C++:重写已弃用的虚拟方法时出现弃用警告

    我有一个纯虚拟类 它有一个纯虚拟方法 应该是const 但不幸的是不是 该接口位于库中 并且该类由单独项目中的其他几个类继承 我正在尝试使用这个方法const不会破坏兼容性 至少在一段时间内 但我找不到在非常量方法重载时产生警告的方法 以下
  • C# 中的接口继承

    我试图解决我在编写应用程序时遇到的相当大的 对我来说 问题 请看这个 为了简单起见 我将尝试缩短代码 我有一个名为的根接口IRepository
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • JSON 数组到 C# 列表

    如何将这个简单的 JSON 字符串反序列化为 C 中的列表 on4ThnU7 n71YZYVKD CVfSpM2W 10kQotV 这样 List
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • 暂停下载线程

    我正在用 C 编写一个非常简单的批量下载程序 该程序读取要下载的 URL 的 txt 文件 我已经设置了一个全局线程和委托来更新 GUI 按下 开始 按钮即可创建并启动该线程 我想要做的是有一个 暂停 按钮 使我能够暂停下载 直到点击 恢复
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 基于xsd模式生成xml(使用.NET)

    我想根据我的 xsd 架构 cap xsd 生成 xml 文件 我找到了这篇文章并按照说明进行操作 使用 XSD 文件生成 XML 文件 https stackoverflow com questions 6530424 generatin
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 如何在c#中的内部类中访问外部类的变量[重复]

    这个问题在这里已经有答案了 我有两个类 我需要声明两个类共有的变量 如果是嵌套类 我需要访问内部类中的外部类变量 请给我一个更好的方法来在 C 中做到这一点 示例代码 Class A int a Class B Need to access
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 当模板类不包含可用的成员函数时,如何在编译时验证模板参数?

    我有以下模板struct template
  • 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

    我知道有关此主题的多个问题 但是 我没有看到任何明确的答案或任何基准测量 因此 我创建了一个处理两个整数数组的简单程序 第一个数组a非常大 64 MB 第二个数组b很小 无法放入 L1 缓存 程序迭代a并将其元素添加到相应的元素中b在模块化
  • 转到定义:“无法导航到插入符号下的符号。”

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我今天突然开始在我的项目中遇到一个问题 单击 转到定义 会出现一个奇怪的错误 无法导航到
  • Googletest:如何异步运行测试?

    考虑到一个包含数千个测试的大型项目 其中一些测试需要几分钟才能完成 如果按顺序执行 整套测试需要一个多小时才能完成 通过并行执行测试可以减少测试时间 据我所知 没有办法直接从 googletest mock 做到这一点 就像 async选项

随机推荐

  • 使用 Excel VBA 运行 SQL 查询

    我对 SQL 和 VBA 相当陌生 我编写了一个 SQL 查询 我希望能够从 Excel 工作簿中的 VBA 子程序调用和运行该查询 然后将查询结果带入工作簿中 我在网上找到了一些潜艇 stackoverflow 和其他地方 声称可以这样做
  • 寻找家谱[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在为我的 Web 应用程序创建具有 HTML5 要求的家谱功能 我已经搜索并找到了一些 JS 示例 但没有找到符合我要求的 我已经尝试
  • 隐藏特定子页面上的 Ionic TabBar (IONIC 3)

    我想在多个特定页面上隐藏我的标签栏 我的主要重点是将其隐藏在我的登录页面 注册页面和评论页面上 我尝试过 tabsHideOnSubPages true 但是当我这样做时我的 UserProfile 页面 这是一个子页面 隐藏选项卡栏 选项
  • 如何在 SSL 下从 PDO 连接 MySQL

    我已经配置了MySQLubuntu 服务器中的 SSL show variables like ssl Variable name Value have openssl YES have ssl YES ssl ca etc mysql c
  • 配置 WEBUTIL 后 Oracle Form 冻结

    我正在使用 Oracle Forms 10g 它是基于 Web 的 Oracle 表单应用程序 我想从 Oracle Forms 10g 生成 Excel 报告 我配置了 WEBUTIL 并使用 CLIENT OLE2 包 在触发器 WHE
  • 查找矩阵中对角线的单词字母

    我有一个5 6的矩阵 所有的值都是英文字母 我必须在矩阵中从左到右 从右到左 从上到下 从上到对角线找到特定的单词 其实这是一个字谜 我能找到 左右 右左 上下 和 下上 这些词 当涉及到对角线查找单词时 事情会变得更加混乱 我提供了从左到
  • Ionic Framework 和 Firebase 3.x 版本:此域未获得对您的 Firebase 项目进行 OAuth 操作的授权

    我正在使用 Ionic Framework 和 Firebase 开发 iOS 应用程序 我已在我的项目中将 Firebase SDK 更新到版本 3 x 我想做的是在真实设备上使用 Facebook 对用户进行身份验证 当我在浏览器上测试
  • JpaRepository删除子元素

    我正在尝试执行一个非常简单的删除操作 但不知何故它不起作用 因为我将 DAO 更新到了 JpaRepository 基本上是这样的 A a aRepository findOne id a setSomeField someNewStrin
  • Google App Engine 为什么某些日志没有显示?

    在 Google App Engine 灵活环境中 许多日志正在跳过 并且没有显示在日志记录控制台中 并且这种情况总是发生 我正在检查它Stackdriver LoggingGoogle Cloud 仪表板上的部分 我使用的日志显示cons
  • ReactJS如何仅在向下滚动并到达页面上时渲染组件?

    我有一个反应组件Data其中包括几个图表组件 BarChart LineChart etc When Data组件开始渲染 需要一段时间才能从API接收到每个图表所需的数据 然后开始响应并渲染所有图表组件 我需要的是开始渲染每个图表only
  • 在 Vaadin 14 应用程序的服务器端通过 Java 获取用户 Web 浏览器的 IP 地址

    In 瓦丁流 https en wikipedia org wiki Vaadin Vaadin Flow 比如14 1版本 如何获取IP地址 https en wikipedia org wiki IP address用户的网络浏览器通过
  • python:生成器对象的属性

    是否可以在生成器对象上创建属性 这是一个非常简单的例子 def filter x for line in myContent if line x yield x 现在假设我有很多这样的过滤器生成器对象漂浮在周围 也许其中一些是匿名的 我想稍
  • 使用 awk 将大型复杂的一列文件拆分为多列

    我有一个由某些商业软件生成的文本文件 如下所示 它由括号分隔的部分组成 每个部分都有数百万个元素 但具体值因情况而异 1 2 3 11 22 33 111 222 333 我需要实现如下输出 1 11 111 2 22 222 3 33 3
  • Request.UrlReferrer 在 Internet Explorer 7、8、9 浏览器中返回“null”

    在 Internet Explorer 7 8 9 浏览器中 C 的 Request UrlReferrer 返回 null 其原因何在 它的解决办法是什么 页面上有一些 单击此处 按钮 单击该按钮后 将在新选项卡中打开一个新的 url 页
  • 在 JQGrid 中映射 JSON 数据

    我正在使用 jqGrid 3 6 4 和 jquery 1 4 2 在我的示例中 我得到以下 json 数据格式 我想将这些 json 数据映射到 jqgrid 的行中 page 1 total 1 records 6 rows head
  • poll() 超时为 0 时会做什么?

    我正在看poll man page http man7 org linux man pages man2 poll 2 html 它告诉我的行为poll 当超时参数传入正值和负值时 它没有告诉我如果超时会发生什么0 有任何想法吗 看着epo
  • 在 Autofac 中注册异步工厂

    我有一个从存储库获取的 Wallet 类 我正在尝试在 Autofac 中正确注册两者 以便使用钱包的类可以注入正确的实例 问题是存储库使用异步方法 返回任务 Autofac 支持这种情况吗 这不起作用 cb RegisterType
  • Coverity有Rest API吗

    我想存储结果覆盖性 http www coverity com 到 InfluxDB 我想知道 Coverity 是否有 REST API 如果您只是尝试将数据转储到 InfluxDB 则可以从 REST API 卷曲数据并将生成的 jso
  • 批量将 PDF 转换为 XPS

    我正在寻找一种廉价的方法将 1300 个 PDF 文档批量转换为 XPS 文档 我知道我可以简单地以这种格式打印它们 但这需要很长时间 有没有办法在 C 中以编程方式执行此操作 根据您对廉价的定义 有以下几种选择 便宜 低于 1000 美元
  • gcc:如何正确使用 __attribute((__may_alias__)) 以避免“取消引用类型双关指针”警告

    我有一些代码使用类型双关来避免调用成员 对象 的构造函数和析构函数 除非 直到实际上需要使用该对象 它工作正常 但在 g 4 4 3 下 我收到这个可怕的编译器警告 jaf jeremy desktop g O3 Wall puns cpp