赋值语句的执行顺序
来源:互联网 发布:178数据库7.0 编辑:程序博客网 时间:2024/06/05 14:40
I have just started to learn C, and I get that
*a = *b;a++;b++;
and
*a++ = *b++
are equivalent, but is that what's actually happening when the line
*a++ = *b++
is called? Can someone clarify how the compiler is interpreting the second line? I know about right-to-left precedence and such, but can someone precisely write the steps the compiler uses to interpret this line of code?
ANSWER:
You said that you believe that:
*a = *b; a++; b++;
is equivalent to
*a++ = *b++;
but that is false, so you have a false belief. Let's correct your false belief.
In the first case, the following things must happen:
- VAR:
*a
must be evaluated to produce a variable, call itvar
- VAL:
*b
must be evaluated to produce a value, call itval
- ASSIGN:
val
must be assigned tovar
. - INCA:
a
must be incremented. - INCB:
b
must be incremented.
What are the constraints on how the compiler may order those?
- VAR and VAL must happen before ASSIGN.
- ASSIGN must happen before INCA.
- INCA must happen before INCB.
The rule here is that all the side effects of one statement have to be complete before the next statement starts. So there are two legal orderings. VAR VAL ASSIGN INCA INCB, or VAL VAR ASSIGN INCA INCB.
Now let's consider the second case.
*a++ = *b++;
We have the same five operations, but the constraints on their ordering are completely different because these are all in the same statement, so the rule about statements does not apply. Now the constraints are:
- VAR and VAL must happen before ASSIGN.
- the evaluation of VAR must use the original value of
a
- the evaluation of VAL must use the original value of
b
Note that I did not say that the increments are required to happen afterwards. Rather, I said thatthe original values must be used. As long as the original value is used, the increment can happen at any time.
So for example, it would be perfectly legal to generate this as
var = a;a = a + 1; // increment a before assign*var = *b;b = b + 1; // increment b after assign
It would also be legal to do this:
val = *b;b = b + 1; // increment b before assign*a = val;a = a + 1; // increment a after assign
It would also be legal to do it as you suggest: do the assignment first, and then both increments in left-to right order. And it would also be legal to do the assignment first, and then both increments in right-to-left order.
A C compiler is given broad latitude to generate code however it likes for this kind of expression. Make sure this is very clear in your mind, because most people get this wrong: just because the ++
comes after the variable does not mean that the increment happens late. The increment can happen as early as the compiler likes as long as the compiler ensures that the original value is used.
That's the rule for C and C++. In C#, the language specification requires that the side effects of the left side of an assignment happen before the side effects of the right side of an assignment, and that both happen before the side effect of the assignment. That same code in C# would be required to be generated as:
var_a = a;a = a + 1;// must pointer check var_a herevar_b = b;b = b + 1;val = *var_b; // pointer checks var_b*var_a = val;
The "pointer check" is the point at which C# requires that the runtime verify that var_a
is a valid pointer; in other words, that *var_a
is actually a variable. If it is not then it must throw an exceptionbefore b
is evaluated.
Again, a C compiler is permitted to do it the C# way, but not required to.
- 赋值语句的执行顺序
- C++中赋值语句的执行顺序
- c#赋值的执行顺序
- SQL语句的执行顺序
- select语句的执行顺序
- select语句的执行顺序
- SQL语句的执行顺序
- MySQL的语句执行顺序
- SELECT语句的执行顺序
- SQL语句的执行顺序
- for语句的执行顺序
- SQL语句的执行顺序
- SQL语句的执行顺序
- sql语句的执行顺序
- sql语句的执行顺序
- SQL语句的执行顺序
- SELECT 语句的执行顺序
- MySQL的语句执行顺序
- 谷歌眼镜设计规范之书写
- linux下导入、导出mysql数据库命令(被人未验证)
- android:shape 图形处理
- 谷歌眼镜设计规范之排版
- python 库安装,安装 numpy matplotlib opencv wxpython PIL(linux环境下)
- 赋值语句的执行顺序
- Opencv 例程讲解8 ----如何实现Mat以及自定义类型的读写操作
- Java学习第五天:面向对象
- dispatch、onIntercept、onTouch三者对MotionEvent的分发、拦截机制分析
- jquery UI dialoag 窗口 建表 提交 (学习记录)
- 编译原理学习笔记06——(连连看—准备一下很多课件都演示的公式E → E+T | T )——2014_1_22
- db2导入导出表命令
- centos6 上用nginx 和 uwsgi 搭建 python web运行环境
- Construct Binary Tree from Preorder and Inorder Traversal