gpt4 book ai didi

c - Bash中的增减运算符是Undefined Behavior吗?

转载 作者:太空狗 更新时间:2023-10-29 11:27:15 26 4
gpt4 key购买 nike

在标准C99和C11中,类似U.B的表达式。 (未定义的行为):

 int x = 2;
int ans = x++ + x++;

在Bash中,定义了递增/递减运算符,并且 gnu.org中的官方文档说遵循标准C的约定。

另外,Bash主要符合POSIX,并且在其标准文档( http://pubs.opengroup.org/onlinepubs/9699919799/)中表示,对于算术运算,除非有相反说明,否则均假定为C标准。

由于我找不到更多信息,因此得出的结论是,在Bash中,我们还有使用增量运算符的Undefined Behavior:
x = 2
echo $(( x++ + x++ ))

我需要确定我的结论是否正确,或者相反,是否在Bash中存在取代C标准的约定。

附加说明:在我的系统(Ubuntu 14.04,Bash版本4.3.11)中尝试时,似乎执行了从左到右的评估,并在操作者 ++出现时立即进行了递增。

最佳答案

您似乎正在寻求为bash找到定义的标准,就像C一样。不幸的是,没有一个。

实际上只有两个指南:

公开组基本规范的

  • Volume 3 (Shell and Utilities),通常被称为“Posix”,其故意未指定。它确实指出算术评估“等同于ISO C标准的6.5节,表达式中所述”,但该标准并未为包含变数和同一变量的另一种用法的表达式指定任何值(例如作为x + x++x++ + x++)。
  • 特定版本的bash的实际行为和手册,都不符合正式的规范,也没有经过任何标准组织的认证或认可。

  • 因此,我不得不说,没有文件以 x++ + x++之类的表达式的算术评估形式定义结果。即使当前bash版本的bash手册指定了它(没有指定),即使可以通过检查当前bash版本的源代码来推断行为(确实如此,但不一定很容易) ),从任何意义上说,它都不是正式规范。

    从字面上的直觉上来说,这使结果“未定义”:未定义结果。

    当然,没有法律要求对每种编程语言都进行完全指定,而很多法律没有。确实,尽管C和C++都以ISO标准的形式享受详尽的定义,但标准故意故意定义了许多用法,部分原因是这样做会需要错误检测形式,从而妨碍性能。这些决定已经并将继续引起争议,我无意采取任何立场。

    我将简单地观察到,在正式规范的上下文中,以下内容并不相同:
  • 将评估特定程序结构的结果检测为错误的要求。
  • 明确声明特定构造的值是实现定义的。
  • 无法指定特定构造的值,或者未指定特定构造的显式语句。
  • 明确声明未评估特定构造的结果。

  • 前两个绝对是正式的规范,因为它们暗示评估的结果是明确定义的(在第二种情况下,定义应该/必须出现在实现手册中)。这样的构造绝对是可用的,尽管特定于实现的构造当然会使程序不可移植。

    尽管通常会提供一系列可能性,但第三个方法并没有准确定义其描述的构造的值。第四个是C/C++专业知识,它指定该构造无效,并且程序员有责任避免使用该构造,因为该标准对实现没有任何要求。绝对不要使用此类构造。

    从特定规范中提取的四种情况的示例:
  • 错误检测。 (Java)“如果整数除数中的除数的值为0,则抛出ArithmeticException。”
  • 特定于实现。 (Posix shell)“打开的文件用从零开始的十进制数字表示。最大的可能值是实现定义的;但是,所有实现都应支持至少0到9(含),以供应用程序使用。”
  • 未指定的行为。 (C/C++)“未指定行为的一个示例是对函数的参数进行评估的顺序。” (来自C99标准的定义部分)。
  • 未定义行为(C)“在两个操作[/和%]中,如果第二个操作数的值为零,则该行为未定义。” (与上面的Java对比。)

  • 最后两类似乎在某些程序员中引起了愤怒。不相信规范有可能使行为未指明,甚至不存在规范也是某种阴谋隐瞒真相(因此必须予以释放)。反过来,这又导致了对特定语言实现的随机试验,这必须是徒劳的,因为该标准并未将所有实现绑定(bind)到同一件事上,甚至没有将特定实现始终绑定(bind)到同一件事上。

    避免将“未定义的行为”视为特定行为也很重要。如果使用UB进行的计算具有特定的行为,则它不会是不确定的。即使计算具有一系列可能的特定行为,也只是未指定。

    “未定义的行为”不是规范或属性。您无法检测到“未定义的行为”,因为缺少定义意味着任何行为都是可能的,包括行为是某些其他构造的定义结果。

    特别是,“未定义的行为”与检测到的错误不同,因为实现没有义务检测到它。

    关于c - Bash中的增减运算符是Undefined Behavior吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27772768/

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