Customize Consent Preferences

We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.

The cookies that are categorized as "Necessary" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... 

Always Active

Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

No cookies to display.

Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

No cookies to display.

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

No cookies to display.

Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.

No cookies to display.

Advertisement cookies are used to provide visitors with customized advertisements based on the pages you visited previously and to analyze the effectiveness of the ad campaigns.

No cookies to display.

C/C ++的严格混叠规则是什么?

C ++中施放的普通指针会导致不确定的行为,从而导致崩溃或错误的输出。严格的混叠是一项规则,其次是最不知情的侵犯的编译器,导致了不可预测的行为。如果您曾经使用过Reinterpret_cast或类型铸造,那么您可能会很脆弱!通过允许安全的替代方案,例如 std :: memcpy,,,, std :: bit_cast,,,, 未签名的char*, 和 工会 存在。本文解释了什么是严格的混叠,为什么危险以及如何安全有效地编码。

目录:

C ++的严格混叠是什么?

严格的别名规则是C ++(和C)中的优化规则,该规则允许编译器假设不同类型的指针没有指向相同的内存。这可以由编译器进行积极的代码优化。如果您违反了,它可能会导致 “不确定的行为”, 而且您的程序可能会崩溃并给您错误的结果。

在C ++中严格混杂的工作

在C ++中, 严格的别名 指定指向不同类型的指针被假定为没有别名,即它们没有指向相同的内存位置。优化代码变得容易,但可能会导致 不确定的行为。

例如,如果我们将42存储在一个 int* 然后将其存储在3.14F中 漂浮* 指向同一位置,我们可能 违反编译器对内存访问的期望 因此,编译器不会重新加载 int 在打印时值,假设浮点写入没有影响它。这甚至可能导致输出不正确或崩溃。如果有必要将指针转换为不兼容类型的指针,请使用 std :: memcpy 或者 std :: bit_cast (因为C ++ 20)而不是在不兼容类型之间铸造以避免破坏严格的混叠。

让我们检查一个程序,看看严格的别名如何有效

例子:

输出:

在C ++中严格混杂的工作在C ++中严格混杂的工作

在此示例中 int* 漂浮* 重叠,但是编译器没有信息可以知道它们重叠,这导致它优化了 *IP = 42;线路可能会产生不良结果。要安全地访问跨类型的内存,请使用 std :: memcpy 或者 std :: bit_cast (C ++ 20)。作为副作用,这有助于防止不确定的行为以及提高性能。

编译器如何优化严格的混溶

编译器假设不同类型的类型永远不会别名,除非您明确允许它。这意味着:

  • 它基于类型信息来重新定位加载/存储。
  • 它消除了不必要的内存读取,因为它假定内存没有更改。
  • 它将值保持在寄存器中,而不是从内存中再次加载它们。

安全的替代方案,以避免严格的别名C ++

有一些安全的替代方法可以避免使用严格的别名 std :: memcpy,std :: bit_cast, 未签名的char*。

1。使用std :: memcpy避免严格的别名

std :: memcpy 是一种使用不同类型的相同内存的安全方法,而不会破坏严格的别名。使用memcpy,您是通过字节复制内存的,允许编译器正确处理它,而不是直接施放指针(这导致不确定的行为)。这也确保在原始数据仍然存在时不会进行错误的优化。

例子:

输出:

避免严格的混叠输出避免严格的混叠输出

在上面的代码中,我们使用 std :: memcpy 避免直接铸造 漂浮* 到一个 int* 复制原始内存 漂浮* 到一个 int。 为了避免不确定的行为,这要确保

2。使用std :: bit_cast避免严格的别名

std :: bit_cast (在C ++ 20中添加)允许重新解释内存,而不会破坏严格的混叠规则。它本身将源数据将源数据逐个地复制到新类型中,从而阻止编译器优化它。与指针铸造(reinterpret_cast)不同, std :: bit_cast 不会创建不确定的行为,因为它保留了原始数据的完整位模式。

例子:

笔记: 以上代码不支持普通编译器,它仅在C ++ 20编译器中起作用。

在上述代码中, std :: bit_cast(f) 安全地重新诠释 漂浮 作为 int 而不会违反严格的别名。此功能可确保转换在二进制级别上完成,并且不会被编译器优化,这可能导致不确定的行为。

3。使用未签名的char*避免严格的别名

在C ++中,严格的混叠规则,没有违反严格的混叠规则, 未签名的char* 可以访问任何对象的原始内存,这也使二进制数据操纵,序列化和调试变得容易。

例子:

输出:

未签名的char*以避免严格的混叠输出未签名的char*以避免严格的混叠输出

在上述代码中,我们声明 结构数据 int漂浮并将无符号字符*分配给构造数据,以读取其原始内存为字节。在这里,我们在十六进制中打印每个字节,以确保如何存储数据。这种方法可用于调试,序列化和分析低级内存。

4。使用联合类型的双关

在C ++中,这是访问与不同类型相同内存的另一种安全方法,而不会引起 不确定的行为 。在联合类型的双关词中,一个不同的成员 联盟 共享相同的内存,而不会违反严格的别名规则。

例子:

输出:

使用联合类型的双关使用联合类型的双关

工会可以通过允许使用类型的双张力来为其他类型的内存共享,而不会违反严格的混叠。推杆 3.14f DF 并将其读出来 di 产生意想不到的整数值,因为它读取了浮子的二进制形式。

例外摘要

例外 安全的? 原因
char*,unsigned char*,std :: byte* 是的 可以安全别名
联合类型双关 或许 在某些编译器中工作,但不能保证便携式
std :: memcpy 是的 复制数据而不是混音
std :: bit_cast(C ++ 20) 是的 安全类型重新解释

检测严格的混叠违规行为

严格的别名违规行为可能是默默的 不确定的行为而不是编译器错误,标志可以帮助定位潜在的故障点。在GCC和Clang中,-fstrict -oliasing可以实现严格的混叠优化,并且 – Wtrict -Oliasing发出有关违反严格异化规则的代码的警告。

如果您面临混叠问题,则运行以下代码以及这些标志可以捕获您:

例子:

输出:

检测严格的混叠违规行为检测严格的混叠违规行为

1078523331是读取3.14F的二进制表示的结果,该表示为int。这就是为什么行为与我们期望的相反的原因,因为reinterpret_cast不会修改对象的位表示,而对象也不可恶,因此编译器根据完全不同的规则来优化,破坏所有严格的别名规则。在这里,这取决于浮点值3.14F如何存储在内存中,然后从内存中以int的形式获取。

检测违规行为的方法

使用GCC或Clang使用:

g++ -std=c++17 -O2 -Wall -Wstrict-aliasing test.cpp

编译器诊断在编译时严格违反违规行为,发出警告或导致运行时不确定的行为。使用std :: memcpy或std :: bit_cast(C ++ 20),以避免此问题。

结论

严格的混叠是一个很棒的C ++优化规则,因为它会导致有效的内存访问,但如果违反规则,也会导致不确定的行为。使用不同类型的类型不适当地违反严格的混溶,可以生成任何形式的编译器优化(但这是一个边缘案例,因为它被引用了可移植性问题),但是可以使用一些成年人来保证安全的类型,例如STD :: memcpy,memcpy,std :: bit_bit_cast :: bit_cast(c+++carteccast cartect cartect(c++carlignect),以实现carlias carrip for varrias for varia varias way way way varias。另一方面,用编译器标志(例如 – wstrict -oliasing)标记违规行为可以帮助调试问题。由于编程模型的正确性越正确,因此,严格的混叠是使用最佳实践的低级编程,嵌入式系统和关键性能程序的关键。

关于C ++严格的混叠规则的常见问题

1。定义C ++中的严格混叠

严格的别名规则是C ++(和C)中的优化规则,该规则允许编译器假设不同类型的指针没有指向相同的内存。如果您违反了,它可能会导致 “未定义的行为”。

2。为什么破坏严格的混叠会导致不确定的行为?

当不同的指针类型类型时,这些优化可能导致结果不正确或崩溃。

3。如何避免严格的违规违规?

使用安全替代方案,例如std :: memcpy,std :: bit_cast(C ++ 20),未签名的char*,工会。

4。我可以使用reinterpret_cast逃脱严格的别名吗?

不,reinterpret_cast并不能阻止严格的别名违规行为,并导致不确定的行为。

5。为什么char*和未签名的char*对严格的混叠有特殊含义?

在法律上允许它们别名任何类型,这些类型可用于安全访问原始内存。



Related Posts

[Review] 最好的PC清洁软件是什么? »Tekraze

[Review] 最好的PC清洁软件是什么? »Tekraze

最好的PC清洁软件是什么? PC清洁软件是一种专门的工…

Roblox Cali枪战代码赎回:2025年更新

Roblox Cali枪战代码赎回:2025年更新

在快节奏的世界中 卡利枪战这是一款在Roblox上的流…

Cadence与Nvidia Grace Blackwell一起加速AI驱动的工程设计和科学

Cadence与Nvidia Grace Blackwell一起加速AI驱动的工程设计和科学

组合设计专业知识和加速计算推动创新,提高能源效率,提高…

SSD vs HDD可靠性:最适合长期存储?

SSD vs HDD可靠性:最适合长期存储?

SSD与HDD可靠性相比。发现哪种存储选项最适合长期数…

Bybit任命明日世界巴西2025-26的独家支付合作伙伴,推出持卡人预售

Bybit任命明日世界巴西2025-26的独家支付合作伙伴,推出持卡人预售

该帖子最初发表在此网站上 迪拜,阿联酋,,,, 202…

固定metAmask不连接或工作的前9种方法

固定metAmask不连接或工作的前9种方法

关键要点 MetAmask是以太坊区块链访问的浏览器扩…