C语言中的Strict Aliasing Rule
文章目录
- 前言
- 没有警告不代表没有问题
- 目前的应对方法
前言
很久没写了,水一篇。
最近有个代码在gcc 4.8.5上编译失败。编译失败的提示是:
error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
查了下这个报错,有点复杂。大体是不要使用一个类型的指针,去操作另一种指针指向的空间。比如下面这样:
#include <inttypes.h>
#include <stdio.h>struct internet {__uint16_t ip;
};__uint8_t address[10];int main(int argc, char *argv[]) {address[0] = 1;address[1] = 2;struct internet *net = (struct internet *)address;__uint16_t ip = net->ip;printf("%" PRIu8 "\n", address[0]);printf("%" PRIu8 "\n", address[1]);printf("%" PRIu16 "\n", ip);
}
然而,上面这段代码在不同的gcc 11.4.1版本下编译,没有问题。
关于Strict Aliasing Rule的详细解释见:What is the Strict Aliasing Rule and Why do we care?、c when would you not want to use strict aliasing?
我也没有完全搞懂。下面示例,来自这个链接。
没有警告不代表没有问题
下面我们来看下这个示例。在常见的gcc版本下编译,都能复现。
#include <iostream>int foo(float *f, int *i) {*i = 1;*f = 0.f;return *i;
}int main() {int x = 0;std::cout << x << std::endl; // Expect 0int x_ret = foo(reinterpret_cast<float *>(&x), &x);std::cout << x_ret << "\n"; // Expect 0?std::cout << x << std::endl; // Expect 0?
}
首先,我们编译的时候不要开启优化,输出如下:
g++ -O0 demo-2.cpp -o demo-20
0
0
接着,我们编译的时候开启优化,输出如下:
g++ -O2 demo-2.cpp -o demo-20
1
0
这就比较脑壳痛了。日常开发编译的是debug版本,它没有优化。发布的时候,编译的是release版本,它有一定的编译优化。然后相同的代码,debug和release版本的运行不同。这个问题可能就很难排查。
为什么会出现这种情况?编译器也没有给出警告?
大概是因为优化的时候,编译器看到要返回的是i,和f又没有什么关系,给返回寄存器里面提前填入了i的值。
目前的应对方法
一般来说,日常编程中,即使不同类型的指针,操作相同的内存,也不会出现上面这种情况。所以正常使用就好,不用特地回避,出问题再解决问题。(为什么不事先回避这个问题呢?因为搞不清,那就先不管。)
如果遇到上面这种问题,或者因为这个问题编译失败,怎么办呢?
- 第一种方法是:使用memcpy进行拷贝,不要直接使用不同类型的指针,操作相同的内存。
- 第二种方法是:在gcc的构建选项中添加
-fno-strict-aliasing选项。但是这会导致整个构建过程都忽略了这个限制。 - 第三种是,可以尝试下使用
__attribute__((optimize("-fno-strict-aliasing")))修饰函数,但是这不一定有效。
相关文章:
C语言中的Strict Aliasing Rule
文章目录 前言没有警告不代表没有问题目前的应对方法 前言 很久没写了,水一篇。 最近有个代码在gcc 4.8.5上编译失败。编译失败的提示是: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werrorstrict-aliasing]查了下…...
单字符检测模型charnet使用方法,极简
Git链接 安装按照上面的说明,说下使用。 把tools下面的test做了一点修改,可以读取一张图片,把里面的单个字符都检测和识别出来。 然后绘制到屏幕上。 import torch from charnet.modeling.model import CharNet import cv2, os import num…...
Erlang、RabbitMQ下载与安装教程(windows超详细)
目录 安装Erlang 1.首先安装RabbitMQ需要安装Erlang环境 2.点击下载好的.exe文件进行傻瓜式安装,一直next即可 3.配置Erlang环境变量 安装RabbitMQ 1.给出RabbitMQ官网下载址:Installing on Windows — RabbitMQ,找到 2.配置RabbitMQ环境变量࿰…...
2023年终总结丨很苦,很酷!
文章目录 个人简介丨了解博主写在前面丨博主介绍年终总结丨博主成就年终总结丨博主想说年终总结丨学习芝士年终总结丨未来展望写在后面丨新年快乐 个人简介丨了解博主 主页地址:https://blog.csdn.net/m0_68111267 荣誉身份 ⭐2022年度CSDN 社区之星 Top6 ⭐2023年…...
鸿蒙 DevEco Studio 3.1 入门指南
本文主要记录开发者入门,从软件安装到项目运行,以及后续的学习 1,配置开发环境 1.1 下载安装包 官网下载链接 点击立即下载找到对应版版本 下载完成,按照提示默认安装即可 1.2 下载SDK及工具链 运行已安装的DevEco Studio&…...
ubuntu多用户环境dockerbug,卸载重装docker流程
之前不小心误操作删除重装docker,结果删除没成功,更没法重装,每次apt install都会报一个docker错误,虽然不影响软件的常规安装~但是现在还是需要装一个完整docker,还是选择删除一下,重点是关闭服…...
微信小程序开发系列-09自定义组件样式特性
微信小程序开发系列目录 《微信小程序开发系列-01创建一个最小的小程序项目》《微信小程序开发系列-02注册小程序》《微信小程序开发系列-03全局配置中的“window”和“tabBar”》《微信小程序开发系列-04获取用户图像和昵称》《微信小程序开发系列-05登录小程序》《微信小程序…...
数据结构 模拟实现LinkedList单向不循环链表
目录 一、链表的简单介绍 二、链表的接口 三、链表的方法实现 (1)display方法 (2)size得到单链表的长度方法 (3)addFirst头插方法 (4)addLast尾插方法 (5…...
2023-12-24 LeetCode每日一题(收集足够苹果的最小花园周长)
2023-12-24每日一题 一、题目编号 1954. 收集足够苹果的最小花园周长二、题目链接 点击跳转到题目位置 三、题目描述 给你一个用无限二维网格表示的花园,每一个 整数坐标处都有一棵苹果树。整数坐标 (i, j) 处的苹果树有 |i| |j| 个苹果。 你将会买下正中心坐…...
Oracle 19c OCP 1z0 082考场真题解析第17题
考试科目:1Z0-082 考试题量:90 通过分数:60% 考试时间:150min 本文为云贝教育郭一军guoyJoe原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。 17. Which three …...
掌握这十几个Python库才是爬虫界的天花板,没有你搞不定的网站!实战案例:Python全网最强电影搜索工具,自动生成播放链接
掌握这十几个Python库才是爬虫界的天花板,没有你搞不定的网站!实战案例:Python全网最强电影搜索工具,自动生成播放链接。 用来爬虫的十几个Python库。只要正确选择适合自己的Python库才能真正提高爬虫效率,到达高效爬虫目的。 1.PyQuery from pyquery import PyQuery as …...
模型 KANO卡诺模型
本系列文章 主要是 分享 思维模型,涉及各个领域,重在提升认知。需求分析。 1 卡诺模型的应用 1.1 餐厅需求分析故事 假设你经营一家餐厅,你想了解客户对你的服务质量的满意度。你可以使用卡诺模型来收集客户的反馈,并分析客户的…...
启明智显开源项目分享|基于Model 3c芯片的86中控面板ZX3D95CM20S-V11项目软硬件全开源
前言: 本文为4寸 480*480 RGB接口IPS全面触屏的86中控面板(RT-ThreadLVGL)软硬件开源干货内容,该项目是综合性非常强的RTOS系列项目!项目主控芯片使用 Model 3c,整体实现了简化版本的86中控面板的功能需求…...
Kind创建k8s - JAVA操作控制
kind 简介kind 架构安装 Kind (必备工具)docker官网kubectl官网kind官网校验安装结果 关于kind 命令 安装一个集群查看当前 Kubernetes 集群中的节点信息。查看当前命名空间下中的Pod(容器实例)的信息。使用 kind create cluster 安装,关于安…...
Qt sender()函数
sender函数原型: QObject *sender() const; 如果在由信号激活的插槽中调用该函数,返回指向发送信号的对象的指针,否则返回0,该指针仅在从该对象的线程上下文调用此函数的槽执行期间有效。 主要代码如下: 其中运用了Q…...
Java开发框架和中间件面试题(6)
目录 61.什么是Spring Batch? 62.请举例解释Required与Qualifier注解? 61.什么是Spring Batch? Spring batch是一个轻量级的,完善的批处理框架,他主要的目的在于帮助企业建立健壮,高效的批处理应用。Spri…...
附录E SQL入门之SQL保留字
本专栏目录 第1课 SQL入门之了解SQL 第2课 SQL入门之检索数据 第3课 SQL入门之排序检索数据 第4课 SQL入门之过滤数据 第5课 SQL入门之高级数据过滤 第6课 SQL入门之用通配符进行过滤 第7课 SQL入门之创建计算字段 第8课 SQL入门之使用数据处理函数 第9课 SQL入门之汇总数据 第…...
thinkphp6.0升级到8.0
目录 一:升级过程 二:报错处理 最近写的项目需要使用thinkphp8.0,之前的老项目需要从php6.0升级到8.0,特此记录下升级过程。 一:升级过程 查看版本: php think version,我目前的版本是6.1.4 生成thin…...
机器学习(一) -- 概述
系列文章目录 机器学习(一) -- 概述 机器学习(二) -- 数据预处理 未完待续…… 目录 系列文章目录 前言 一、机器学习定义(是什么) 二、机器学习的应用(能做什么) 三、***机器…...
SpringBoot定时监听RocketMQ的NameServer
问题分析 自己在测试环境部署了RocketMQ,发现namesrv很容易挂掉,于是就想着监控,挂了就发邮件通知。查看了rocketmq-dashboard项目,发现只能监控Broker,遂放弃这一路径。于是就从报错的日志入手,发现最终可…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
