Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是「;“序列点”/&引用;在“之前排序”;铁锈规则? Pr>规则中的规则是什么,类似于C++中的规则?_C++_Rust - Fatal编程技术网

什么是「;“序列点”/&引用;在“之前排序”;铁锈规则? Pr>规则中的规则是什么,类似于C++中的规则?

什么是「;“序列点”/&引用;在“之前排序”;铁锈规则? Pr>规则中的规则是什么,类似于C++中的规则?,c++,rust,C++,Rust,目前,我从经验上发现, 1) 函数的参数按直接顺序计算 2)所有带有副作用的内置操作(=,+=,-=,等)返回单元,因此很难(但可能)编写表达式,这将显示C++中的ub。 一个例子: let mut a = 1i; let b = 2i; let c = 3i; let d = (a = b) == (a = c); // What is a? (a is actually 3) 3) 函数调用似乎是按C++中的顺序排列的 4) 似乎内置操作的顺序就像它们是函数(方法)调用一样,也就是说,求值

目前,我从经验上发现,
1) 函数的参数按直接顺序计算
2)所有带有副作用的内置操作(=,+=,-=,等)返回单元,因此很难(但可能)编写表达式,这将显示C++中的ub。 一个例子:

let mut a = 1i;
let b = 2i;
let c = 3i;
let d = (a = b) == (a = c); // What is a? (a is actually 3)
3) 函数调用似乎是按C++中的顺序排列的
4) 似乎内置操作的顺序就像它们是函数(方法)调用一样,也就是说,求值顺序与运算符优先级有关


我的结论正确吗?确切的评估模型是什么?

我不相信它已经被明确定义,我的grepping没有发现任何东西。但是,我可以保证这些东西不会是未定义的行为(Rust明确避免UB在
不安全的
代码之外),如果它不是“从左到右”,即您推断的顺序,我会感到惊讶。虽然,对的分辨率可能会导致最后评估接收器的方法(也可能不是,这只是一种可能性)

我打开了


顺便说一句,如果您正在研究这个问题,您可以使编译器按照精确的求值顺序拆分出漂亮的控制流图(注意:这是所有内部API,因此不可依赖,比正常情况更容易使编译器崩溃,并且不会隐藏编译器实现细节:它主要为使用
rustc
的人设计)

正如@pnkfelix指出的,编译器没有使用CFG生成代码(截至2014-07-02),这意味着CFG不能保证精确

例如,以@ChrisMorgan的一个示例的精简版本为例:

fn foo(_: (), x: int) -> int {
    x
}

fn main() {
    let mut a = 1;
    { // A
        a * foo(a = 3, a)
    };
}
我们希望编译器在某个块(即
{…}
)内拆分出语句/表达式的控制流图,这可以通过编译器的
--pretty flowgraph=
选项来完成,但为此,我们需要有感兴趣的块的ID。在这种情况下,我们想要的块是
A
。要获得ID,请使用
rustc编译--非常扩展、标识
(请注意,仅使用
标识
是一个毫无意义的遗物:ID现在仅在宏展开后分配):

许多令人讨厌的内部垃圾,但我们需要的是注释
/*block 26*/
rustc--pretty flowgraph=26
提供一个点文件,它呈现给以下内容。您可以参考上面的标识符注释源代码,以精确地计算每个表达式的内容(id=…
位):

(很抱歉,这段代码没有分支,所以只是一个长的操作链。)


FWIW,该表达式的计算结果为
9
,而我期望的是
3
(控制流图确认LHS上的隔离
a
在RHS之后进行计算,包括
a=3
)。我在15300上提出了这个问题(e:现在)我开始回答这个问题,但经过精心设计,我认为我最好做点别的事情……一些事情是相关的,虽然肯定不是完整的。谢谢,非常有趣。如果你需要,我可以根据C++标准的定义和RIST的预期语义学来产生一些简短的正式文本。注意代码生成步骤。在rustc中,当前由抽象语法树驱动,而不是由构造的控制流图驱动。(控制流图用作某些静态分析的基础。)这意味着bug可能潜入其中,其中执行的代码的行为与控制流图预测的不同。例如:@pnkfelix,哦!哇,我想我的答案现在是错的…我会澄清。新链接
#![feature(phase)]
#![no_std]
#![feature(globs)]
#[phase(plugin, link)]
extern crate std = "std#0.11.0-pre";
extern crate native = "native#0.11.0-pre";
use std::prelude::*;
fn foo(_ /* pat 7 */: (), x /* pat 11 */: int) -> int { (x /* 15 */) } /*
block 14 */ /* 4 */

fn main() {
    let mut a /* pat 22 */ = (1 /* 23 */);
    ({
         ((a /* 28 */) *
             ((foo /* 30
                  */)(((a /* 32 */) = (3 /* 33 */) /* 31 */), (a /* 34 */)) /*
                 29 */) /* 27 */)
     } /* block 26 */ /* 25 */);
} /* block 18 */ /* 16 */