【问题标题】:Side-effects: Is strcmp() a pure function副作用:strcmp() 是纯函数吗
【发布时间】:2019-12-04 13:24:35
【问题描述】:

我正在学习副作用纯函数。我知道纯函数没有副作用,并且它们的返回值对于相同的参数是相同的。我想知道C函数strcmp()是否是纯函数。我相信它是纯粹的,因为给定相同的两个字符串作为参数,结果总是相同的。此外,strcmp() 不修改任何变量或调用任何函数,因此它没有任何副作用。

但是我不确定我的推理是否正确。

【问题讨论】:

  • given the same two strings as parameters你不给字符串,你给指针。
  • @KamilCuk 嗯,这很有趣。如果您向strcmp 提供相同的指针,则不一定会得到相同的结果,因为在这些末尾可能会有不同的数据。而且,如果您将指针指向相同的 strings,则对于 strcmp 而言,这不一定是相同的输入值。
  • 例如 gcc 编译器有“const”和“pure”function attribute。在该描述中,memcmp 可能是“纯”,但可能不是“常量”。 “const”函数无法访问指针后面的值。
  • @KamilCuk memcmpstrcmp 都有相同的“纯粹性”问题,因为它传递了指向数据的指针。两个调用可能具有相同的指针,但如果指针指向的数据在调用之间发生了变化,则可能会给出不同的结果。这使得它们在某种程度上不纯。

标签: c functional-programming strcmp side-effects


【解决方案1】:

strcmp() 是一个纯函数,因为结果仅取决于参数,此外,它不会修改全局状态。

当然,strcmp() 的不当使用可能会引发未定义的行为,但这与它是纯的还是不纯的无关。

编辑:

当引用的全局内存也相同时,纯函数只会产生相同的结果。 需要的函数称为常量函数

GCC 文档提供了 strlen() 作为纯函数的示例。实际上,这个函数接受一个指针作为参数,并访问它以找到它的长度。该函数读取全局内存(参数指向的内存不认为是参数),但不改变它,返回的值来源于访问的全局内存。

【讨论】:

    【解决方案2】:

    它不是纯粹的,因为参数是可变的。这意味着调用strcmp(a, b) 的结果将取决于这些指针指向的内容。返回值应该取决于参数的值。

    对纯函数的另一个要求是它没有副作用。这实现了。嗯,在实践中确实如此。这取决于你如何看待它。我几乎可以保证它的所有实现都没有副作用,但标准本身并不要求它们没有副作用。

    一般而言,您可以出于所有相关目的假设它没有副作用。唯一的例外是调用调用了未定义的行为,但无论如何你都应该避免这种情况。

    进一步的 strcmp() 不修改任何变量或调用任何函数,因此它没有任何副作用。

    你不能肯定地说它不调用任何函数。这是实现细节。

    【讨论】:

    • 当然你是对的,但如果strcmp() 真的做了其他事情,即修改了导致程序行为与纯实现不同的全局状态,那么实现就不是标准的了符合。
    • @Ctx 在标准的什么地方我可以读到它不符合标准?
    • 这不是必须的。您只需提供一个示例,其中带有副作用的 strcmp() 版本会导致程序的行为与没有副作用的版本不同。
    • @Ctx 一些函数修改了全局errno。据我所知,实现为类似的东西添加额外的全局是完全可以的。
    • 仅当它被记录时,它不适用于 strcmp()
    【解决方案3】:

    strcmp() 的行为与strlen() 的行为类似,仅取决于const char * 参数指向的内存内容。不会产生任何副作用,如果虚拟内存管理系统中的潜在变化被认为对程序不可见,则可以认为它是

    但请注意,密切相关的函数 strcoll() 可能会产生副作用,具体取决于语言环境处理实现,不应被视为纯函数。

    同样isdigit() 是纯的,但isalpha() 不是。

    【讨论】:

      猜你喜欢
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-27
      • 2018-04-12
      • 2011-05-22
      • 2021-05-15
      相关资源
      最近更新 更多