gpt4 book ai didi

c - 哪些替代品可用于 C 标准未定义的以前广泛支持的行为

转载 作者:太空狗 更新时间:2023-10-29 16:36:36 25 4
gpt4 key购买 nike

在 C 标准化之前的早期,实现有多种方法来处理各种 Action 的异常和半异常情况。其中一些会触发陷阱,如果不先配置,可能会导致随机代码执行。因为此类陷阱的行为超出了 C 标准的范围(并且在某些情况下可能由运行程序控制之外的操作系统控制),并且避免要求编译器不允许依赖于此类的代码陷阱继续这样做,可能导致此类陷阱的操作行为完全由编译器/平台自行决定。

到 1990 年代末,虽然 C 标准没有要求这样做,但每个主流编译器都对其中许多情况采用了通用行为;使用此类行为将允许在代码速度、大小和可读性方面进行改进。

由于不再支持请求以下操作的“明显”方式,在使用旧编译器时,应该如何以不妨碍可读性或对代码生成产生不利影响的方式替换它们?出于描述的目的,假设 int是 32 位,ui是一个无符号整数,si是有符号整数,和 b是无符号字符。

  • 给定 uib , 计算 ui << b对于 b==0..31,或一个可以任意表现为 ui << (b & 31) 的值或值 32..255 为零。请注意,如果每当右侧操作数超过 31 时左侧操作数为零,则两种行为将相同。
  • 对于只需要在处理器上运行的代码,当右移或左移 32 到 255 的量时产生零,计算 ui << b对于 b==0..31 和 0 对于 b==32..255。虽然编译器可能能够优化旨在跳过值 32..255 的移位的条件逻辑(因此代码将简单地执行将产生正确行为的移位),但我不知道任何方法来制定这样的条件逻辑这将保证编译器不会为它生成不必要的代码。
  • 与 1 和 2 一样,但用于右移。
  • 给定 sib使得 b0..30 和 si*(1<<b)不会溢出,计算 si*(1<<b) .请注意,乘法运算符的使用会严重损害许多旧编译器的性能,但如果移位的目的是缩放有符号值,则在操作数在整个移位过程中保持为负的情况下强制转换为无符号感觉是错误的。
  • 给定各种整数值,执行加法、减法、乘法和移位,这样的方式如果没有溢出,结果将是正确的,如果有溢出,代码将生成其高位表现为非捕获和非捕获的值-UB 但以其他方式不确定的方式或将以可识别的平台定义方式陷入困境(并且在不支持陷阱的平台上,只会产生不确定的值(value))。
  • 给定一个指向已分配区域的指针和一些指向其中内容的指针,请使用 realloc更改分配大小并调整上述指针以匹配,同时避免在 realloc 的情况下进行额外的工作返回原始块。不一定适用于所有平台,但 1990 年代主流平台都允许代码确定是否realloc导致事物移动,并通过减去该对象的先前基地址来确定指针到死对象的偏移量(请注意,调整需要通过计算与每个死指针关联的偏移量来完成,然后将其添加为新指针,而不是尝试计算旧指针和新指针之间的“差异”——这在许多分段架构上会合法地失败)。

  • “超现代”编译器是否为上述编译器提供了任何不会降低代码大小、速度或可读性中至少一项的良好替代品,同时对其他任何一项都没有任何改进?据我所知,整个 1990 年代,不仅 99% 的编译器可以完成上述所有操作,而且对于每个示例,几乎所有的编译器都能够以相同的方式编写代码。一些编译器可能会尝试使用不 protected 跳转表来优化左移和右移,但这是我能想到的唯一情况,用于 1990 年代平台的 1990 年代编译器在“明显”编码方式方面存在任何问题以上任何一项。如果超现代编译器不再支持经典形式,它们会提供什么替代品?

    最佳答案

    现代标准 C 以这样一种方式指定,当且仅当您编写代码时对运行的底层硬件没有比 C 抽象机隐式和显式给出的标准更多的期望时,才能保证它是可移植的描述。

    您仍然可以为给定的 objective-c PU 和体系结构在给定优化级别具有特定行为的特定编译器编写代码,但不要期望任何其他编译器(现代或其他编译器,甚至是您编写的编译器的小修订版)如果您的代码违反了标准说期望任何明确定义的实现不可知行为是不合理的条件,则竭尽全力尝试直觉您的期望。

    关于c - 哪些替代品可用于 C 标准未定义的以前广泛支持的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29655664/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com