## Sunday, November 30, 2008

### CLRS ex5.1-2 之 我的想法

{0,1}^3的3-串，相当于binary的0-7

without loss of generality，设为前5个数。

Proposition:

Prove:

P(a)=(3/8)^{k-1} * 5/8
P(ab)=(3/8)^{k-1} * 1/8

function: R(a,b)
input: int a,b
let: L = floor(lg(b-a))+1, size=2^L, result=0
repeat{
result = 0;
for i in [1 .. L]
temp = temp << 1 + R(0,1);
endfor
}until (temp < b-a+1);
return temp+a;

for loop的运行时间为2^L
E[n] = sum( i*P(i) ) * 2^L

sum里面展开后大概是个这样的东西：
1*5/8 + 2*3/8*5/8+3*(3/8)^2*5/8+....+n*(3/8)^{n-1}*5/8

E(n) = 1 + 上一步算法没结束的概率 * E(n-1)

### [zz]读博和大便的相同点

11:21 PM xxx: 标 题: 读博和大便的相同点

1.都是憋出来的
2.肚子里有货才爽，否则很痛苦
3.即便肚子里面有货，也得有paper才行
4.paper越多心里越踏实
5.paper上的都是屎
6.paper不能是别人用过的
7.paper虽然是别人用过的，但是看不出来就行
8.运气够好的话可以借到paper
9.没有paper的话，如果你很有钱也能解决问题
10.实在没有paper，直接拍拍屁股走人是很需要勇气的

## Saturday, November 29, 2008

### 灰姑娘书(Cinderella Book)

Introduction to Automata Theory, Languages and Computation (Addison-Wesley Series in Computer Science)

## Friday, November 28, 2008

### 给你n个数，其中有且仅有两个数出现了奇数次，其余的数都出现了偶数次。用线性时间常数空间找出出现了奇数次的那两个数。

(给你n个数，其中有且仅有一个数出现了奇数次，其余的数都出现了偶数次。用线性时间常数空间找出出现了奇数次的那一个数。)

pongba很详细地记录了我们大脑思考时所做的一些细节。

http://www.matrix67.com/blog/archives/511

## Thursday, November 27, 2008

### 磨练UNIX工具技艺：.......盗链

http://gh.ffshrine.org/soundtracks/599

http://gh.ffshrine.org/song/599/1

<script>		var data = "var%20addr%20%3D%20%222  (此处删除若干)  0A%09%09";  		eval(unescape(data));</script>那么首先要decodeurl的encoding(what's this? refer here: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm)  (一开头我搞错了，以为是html的entity问题，这个可以使用perl的HTML::Entities模块来完成，具体如下：// data是形如"&nbsp; &lt;"这种东东use HTML::Entities;use decode_entities($data);) 使用python可以很方便地decode，具体如下： import urllib; urllib.unquote("%20%3D"); 于是得到了预期的东西： 'var addr = "http://dl1.ffshrine.org........ ' 接下来，则要使用javascript的eval功能来执行这段javascript代码了……这里我考虑了两种方法： 1. 使用某个实际的html engine，如php…… 来得到最终链接地址 2. 使用某个独立的html engine，我搜索到了javax.script 具体代码如下：(script.java) import javax.script.*; import java.net.URL; import java.io.*; class script{ public static void main(String [] args){ ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName("JavaScript"); try{ URL url = new URL( "http://gh.ffshrine.org/song/598/1" ); InputStreamReader reader = new FileReader( "/home/iveney/workspace/test.js" ); Object obj = engine.eval(reader); System.out.println(obj); }catch(Exception e){ e.printStackTrace(); } } } 最主要的一步是engine.eval，等同于原javascript中的eval. 编译能通过，但事实上他是有问题的。因为解码后我得到的是这样的东东（我把whitespace escape了）： var addr = "http://dl1.ffshrine.org/soundtracks/dl/598/00720b/Last Blade 2 Arrange/01_-_the_flower_that_blooms_in_the_moonlight.mp3"; function decode(address) { var Address = ""; Address = address; Address = unescape(Address); function unescapesome(thesome) { var newString = thesome; newString = newString.replace(/%3A/g, ":"); newString = newString.replace(/%27/g, "'"); newString = newString.replace(/%28/g, "("); newString = newString.replace(/%29/g, ")"); newString = newString.replace(/%21/g, "!"); newString = newString.replace(/%7E/g, "~"); return newString; } document.getElementById("linkcode").innerHTML = "<a href='" + unescapesome(escape(Address)) + "'>click here</a>";} decode(addr); 里面有用到DOM model的document，发觉不能正常运行…… 后来我没有深究究竟java这条路要怎么做，因为事实上我看到真实链接已经出来了 －。－ 就在第一行！！！ 于是马上用curl下载一系列的url，然后准备用相似步骤还原成原来的javascript得到地址。 但是没有得到预期的结果――还原成的是这样的东西： var addr = new Array() addr[0] = "http://dl1.f"; addr[1] = "fshrine.org/"; addr[2] = "soundtracks/"; addr[3] = "dl/598/00720"; addr[4] = "b/Last Blade"; addr[5] = " 2 Arrange/m"; addr[6] = "vovld01_-_th"; addr[7] = "e_flower_tha"; addr[8] = "t_blooms_in_"; addr[9] = "the_moonligh"; addr[10] = "t.mp3"; function decode(address) { var Address = ""; for (var i = 0; i != address.length; i++) { Address += address[i] } Address = unescape(Address); Address = Address.replace(/\/mvovld/, "/"); function unescapesome(thesome) { var newString = thesome; newString = newString.replace(/%3A/g, ":"); newString = newString.replace(/%27/g, "'"); newString = newString.replace(/%28/g, "("); newString = newString.replace(/%29/g, ")"); newString = newString.replace(/%21/g, "!"); newString = newString.replace(/%7E/g, "~"); return newString; } document.getElementById("linkcode").innerHTML = "<a href='" + unescapesome(escape(Address)) + "'>click here</a>";} decode(addr); 我日！原来地址还被一个function wrap着呢！ 难道又要我用java来解释吗？ 但是为什么我直接查看页面源代码会得到已经被解释过的javascript代码呢？ 我猜测原因是因为referer的问题。用curl我没有构造合适的http参数，也许原来的页面有检查我是从哪个referer进去的。 然后我换wget试了试，却惊讶的发觉问题解决了：我能用wget得到正确的解释过的url…… 由于最近忙，这里我先不深究，迟点问高手。 最后的shell代码如下： #!/bin/bash DIR=/tmp/mp3 #curl "http://gh.ffshrine.org/song/598/[1-12]" --create-dirs /tmp/mp3 -o "/tmp/mp3/#1.html" mkdir$DIR
for i in seq 1 48
do
wget http://gh.ffshrine.org/song/599/$i -O "$DIR/$i.html" done for i in seq 1 48 do str=grep "var data" "$DIR/$i.html" str=echo$str | cut -d '"' -f 2
#echo $str command="import urllib; js=urllib.unquote('$str'); print js"
# we get javascript now
js=echo $command | python addr=echo$js | head -n 1 | cut -d \" -f 2
echo $addr a=wget "$addr" -P /win/d/Music/LastBladeIIOST/
done

1.把该html文件中有用的那一段grep出来。
2.用cut把引号部分提取出来
3.用python decode之
4.再用cut把链接提取出来
5.用wget进行下载

## Wednesday, November 26, 2008

### 恭喜恭喜：我收到了一封钓鱼邮件

 发件人： Windows Live (WindowsLive@live.com) 发送时间： 2008年11月26日 11:56:59

您好！MSN中国网络为了回馈广大新老用户对我们的支持与厚爱。

领奖专网: http://msn.spasec.cn

----------------------------------------------------------------------------------

while(1) iveney.says("bs");

### 一道题目：2n+1个数中，n个数出现两次，1个数出现1次。O(n)求只出现一次的数

newsmth上的cfans给出了一个很好的解释，

N个数，只有一个出现奇数次，其它偶数次，基于

a xor b xor c
=(a xor b) xor c  = a xor (b xor c)

a xor b = b xor a

a^(2n)=0
a^(2n-1)=a
a xor 0 = a
a xor 1..1 = bitwise not a

<{0,a}, xor>构成一个群。
0是单位元，a是"0元"。

=…… xor 0 = ……
0对于异或操作是单位元。

## Saturday, November 15, 2008

### 永远的KOF

1.关于主角京的名字问题。
KYO KUSANAGI中文名字是草剃京，中间这个字读Ti第四声。草剃这个是日本姓氏实际意思基本没多大，和三神器有关。有种就是字面意思：割去草丛。日文"京"

（这个问题其实很老土了，但是就是很多朋友都把京说成草稚或草智，个人认为比较汗死~~）

2.关于漫画问题。

（其实这些漫画都是为了满足读者的需要，不然我们都没的看了，就靠官方发表的那点东西我们是会饥渴死的，但是有些东西还是最好参照官网，毕竟那更正版一点）

3.关于八神的女朋友问题

（不管你喜欢什么版本的都好，至少我们都是爱拳皇的，希望以后不要再骂人了。）

4.关于OROCHI的超必杀的问题。

5.关于K"，八神和小草的实力问题。

（我们都喜欢拳皇，这个问题就象你家有俩个哥哥，你都非常喜欢他们，要分出他们谁更厉害是不是要叫他们俩对打一次呢？）

６.京的真假问题。

（还有个非常明显的证据，只有真的京才有神尘吧，港漫也是这说的，但是游戏里为什么０１的京有神尘呢？很假吧）

７.关于爆走或失控的问题。

8.关于中国和日本的问题

（终于写完了哟！都是我一个字一个字打上去的，有同感或者也喜欢的拳皇的朋友就回复我一个啦！最好是留点意见哟，有问题也可以问我啦！祝我们和拳皇一起快乐成长） 相册 http://kyoming.photo.163.com
待继……
流浪的魔

## Thursday, November 13, 2008

### 河南女生发明世界最细网线 可穿入缝衣针,带宽100M

http://www.cnbeta.com/articles/69483.htm

### 19岁大学男生发明节能灯 研究所欲花5千万购买

http://www.cnbeta.com/articles/69147.htm

## Monday, November 10, 2008

### 屁放得响，能顶市长

"由"你们算个屁"说开去"
"一个屁的思考"
" 论"屁" "
"论民之屁"
… …

"你知道我是谁吗？我是北京交通部派下来的，级别和你们市长一样高，敢跟我斗!"
"我就是干了，怎么样？要多少钱你们开个价吧。我给钱嘛！"
"你们这些人算个屁呀！敢跟我斗，看我怎么收拾你们！"
"我掐了小孩的脖子又怎么样？！"

"别人愚我们，我们自己愚自己，愚得不亦乐乎！现在，林嘉祥老爷酒后吐真言，大量愚民才突然惊醒：闹了半个世纪，原来我们算个"屁"！"

"说我是个Ｐ，我呆住了，因为以前我是死要面子，不管愿意与否，他还是很给我面子的，但是今天我真的是愕然！"

"我忽然有点感动，历来我对党的干部千篇一律的面孔，虚伪的作风颇有反感，可林书记的出现让我知道，领导干部并不都是虚伪的，也有敢于表露自己的真实想法， 表达自己心声的，那句"我就是干了，你们算个屁啊"在我耳畔久久回响。"

"如果人民是屁的话，那人民政府就是屁政府，人民公仆就是屁公仆，人民法院就是屁法院，人民教师就是屁教师，全国人民代表大会就是全国屁代表大会！等等类推… …"

"热烈庆祝中华屁民共和国正式成立"

"你们算个屁啊！"------说出了所有公仆们的心声，明确了人民在他们心目中的地位。

"想想也滑稽，既然我等是个屁，那你等是管理我等的，自然亦只是个肛门罢了！实在也高不了多少。"

## Sunday, November 9, 2008

### LaTeX的画图宏包/工具太多了……

PSTricks, pgf/tikz, metapost, qtree, asymptote, graphviz .......

PSTricks: 没用过，不表。据说不是很通用
pgf/tikz: 功能很强大，可以直接嵌入在LaTeX里使用，可以画几乎任何的图，另外有专门画树的功能，还能画自动机。2.0的manual竟然有560页。
metapost: 最nb的东西，可惜觉得语法有点脑残，不想去学…… 也是可以画很多东西，得到的是mps文件可以直接includegraphics
graphviz：用一种叫DOT的语言，画图论的图、自动机、目录树、关系图、ER图最方便了，但是因为是自动计算坐标位置，所以有时可能不能完全得到自己想要的位置。

asymptote：据说很nb的工具，可以支持3d效果，但是还没用过。

dia：类似visio，当然没visio那么强大，不过已经能凑合着使用了。
kivio：同上，功能似乎还弱点。
inkscape：画矢量图的利器，以前用过一次，但是觉得java运行起来有点慢就没用了。

## Wednesday, November 5, 2008

### zz[电脑教程]令人目瞪口呆的四位世界级电脑大师

zz verycd.com 前面几段可以跳过去
g950g950 (楼主)  2007/8/9 顶楼 举报
「任何先进的科技一定是一种难以察觉的神奇力量。」

"潘朵拉的铁盒" ，知道他内部是如何运作来达成你的需求。如果这样可以解决你的问题或

=======================================================================
1.公元1998年在我�高二那年，那还是我用Windows 98的时候有次我系统崩溃了，

========================================================================
2.公元2000年在我�大一那年，那还是我用Windows Me的时候有次我系统崩溃了，

、Office、

Photoshop、魔兽世界的安装程序，我后来问我朋友那位高手的下落，

========================================================================
3.公元2001年在我�大二那年，那还是我用Windows XP的时候有次我不小心把D盘格式化了

========================================================================
4.就在最近，我刚装上的Vista突然自己崩溃了

Edition、

BT，以及他正在看的American片，我后来问我朋友那位高手的下落，我朋友说前几年去了

## Monday, November 3, 2008

### [zz]C/C++中的序列点

From newsmth:

0. 什么是副作用（side effects）

C99定义如下
Accessing a volatile object, modifying an object, modifying a file, or
calling a function that does any of those operations are all side effects,
which are changes in the state of the execution environment.

C++2003定义如下
Accessing an object designated by a volatile lvalue, modifying an object,
calling a library I/O function, or calling a function that does any of
those operations are all side effects, which are changes in the state of
the execution environment.

void foo() {
register int i = 0;  // 变量i被直接放入寄存器中，本文中被称为寄存器变量
// 注，register只是一个建议，不一定确实放入寄存器中
// 而且没有register关键字的auto变量也可能放入寄存器
// 这里只是用来示例，假设i确实放入了寄存器中
i = 1;  // 寄存器内容改变，对应了程序状态的改变，该语句有副作用
i + 1;  // 编译时该语句一般有警告："warning: expression has no effect"
// CPU如果执行这个语句，也肯定会改变某个寄存器的值，但是程序状态
// 并未改变，除了代表i的寄存器，程序状态不包含其他寄存器的内容，
// 因此该语句没有任何副作用
}

An actual implementation need not evaluate part of an expression if it
can deduce that its value is not used and that no needed side effects
are produced (including any caused by calling a function or accessing
a volatile object).

1. 什么是序列点（sequence points）

C99和C++2003对序列点的定义相同
At certain specified points in the execution sequence called sequence
points, all side effects of previous evaluations shall be complete and
no side effects of subsequent evaluations shall have taken place.

extern int i, j;
i = 0;
j = i;

0，如果i = 0的副作用发生在j = i之后，就会导致赋值后j的值是i的旧值，这显

2. 表达式求值（evaluation of expressions）与副作用发生的相互顺序

C99和C++2003都规定
Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions, and the order
in which side effects take place, is unspecified.

extern int *p;
extern int i;
*p = i++;  // (1)

i的地址；对于*p = i++，如果要先完整的计算子表达式i++，由于i++表达式的值

extern int i, j, k, x;
x = (i++) + (j++) + (k++);

3. 序列点对副作用的限制

C99和C++2003都有类似的如下规定
Between the previous and next sequence point a scalar object shall
have its stored value modified at most once by the evaluation of an
expression. Furthermore, the prior value shall be accessed only to
determine the value to be stored. The requirements of this paragraph
shall be met for each allowable ordering of the subexpressions of a
full expression; otherwise the behavior is undefined.

extern int i, a[];
extern int foo(int, int);
i = ++i + 1;  // 该表达式对i所做的两次修改都需要写回对象，i的最终值取决
// 于到底哪次写回最后发生，如果赋值动作最后写回，则i的值
// 是i的旧值加2，如果++i动作最后写回，则i的值是旧值加1，
// 因此该表达式的行为是undefined
a[i++] = i;  // 如果=左边的表达式先求值并且i++的副作用被完成，则右边的
// 值是i的旧值加1，如果i++的副作用最后完成，则右边的值是i
// 的旧值，这也导致了不确定的结果，因此该表达式的行为将是
// undefined
foo(foo(0, i++), i++);  // 对于函数调用而言，标准没有规定函数参数的求值
// 顺序，但是标准规定所有参数求值完毕进入函数体
// 执行之前有一个序列点，因此这个表达式有两种执
// 行方式，一种是先求值外层foo调用的i++然后求值
// foo(0, i++)，然后进入到foo(0, i++)执行，这之
// 前有个序列点，这种执行方式还是在两个相邻序列
// 点之间修改了i两次，undefined
// 另一种执行方式是先求值foo(0, i++)，由于这里
// 有一个序列点，随后的第二个i++求值是在新序列
// 点之后，因此不算是两个相邻的序列点之间修改i
// 两次
// 但是，前面已经指出标准规定任意可能的执行路径
// 都必须满足条件才是定义好的行为，这种代码仍然
// 是undefined

i = i++;  // 如果i是built-in类型对象，则该表达式在两个相邻的序列点之间对
// i修改了两次，undefined
// 如果i是UDT类型该表达式也许是i.operator=(i.operator++(int))，
// 函数参数求值完毕后会有一个序列点，因此该表达式并没有在两个
// 相邻的序列点之间修改i两次，OK

4. 编译器的跨序列点优化

A. 不读取，改写一次，例如
i = 0;
B. 读取一次或者多次，改写一次，但所有读取仅仅用于决定改写后的新值，例如
i = i + 1;  // 读取一次，改写一次
i = i & (i - 1);  // 读取两次，改写一次，感谢puke给出的例子
C. 不改写，读取一次或者多次，例如
j = i & (i - 1);

qualified类型对象多次仍旧是undefined behavior，原因在于该读取动作有副作

extern volatile int i;
if (i != i) {  // 探测很短的时间内i是否发生了变化
// ...
}

int j = i;
if (j != i) {  // 将对volatile-qualified类型变量的多次读取用序列点隔开
// ...
}

bool flag = true;
void foo() {
while (flag) {  // (2)
// ...
}
}

[Note: volatile is a hint to the implementation to avoid aggressive
optimization involving the object because the value of the object
might be changed by means undetectable by an implementation. See 1.9
for detailed semantics. In general, the semantics of volatile are
intended to be the same in C++ as they are in C. ]

5. C99定义的序列点列表

― The call to a function, after the arguments have been evaluated.
― The end of the first operand of the following operators:
logical AND && ;
logical OR || ;
conditional ? ;
comma , .
― The end of a full declarator:
declarators;
― The end of a full expression:
an initializer;
the expression in an expression statement;
the controlling expression of a selection statement (if or switch);
the controlling expression of a while or do statement;
each of the expressions of a for statement;
the expression in a return statement.
― Immediately before a library function returns.
― After the actions associated with each formatted input/output function
conversion specifier.
― Immediately before and immediately after each call to a comparison
function, and also between any call to a comparison function and any
movement of the objects passed as arguments to that call.

6. C++2003定义的序列点列表

（function-exit）各有一个序列点，即拷贝一个函数的返回值之后同样存在一个

7. C++2003中两处关于lvalue的修改对序列点的影响

operators的结果改成了lvalue，目前尚不清楚这一改动对于built-in类型有何意

extern int i;
extern int j;
i = j = 1;

to-rvalue conversion，这个conversion代表了一个读取语义，因此i = j = 1就

extern int i;
(i += 1) += 2;

extern int i;
extern int j;
i = ++j;

C++的这一改动显然是考虑不周的，导致了很多C语言的习惯写法都成了undefined
behavior，因此Andrew Koenig在1999年的时候就向C++标准委员会提交了一个建

222. Sequence points and lvalue-returning operators
Section: 5  expr     Status: drafting     Submitter: Andrew Koenig     Date: 20 Dec 1999

I believe that the committee has neglected to take into account one of the differences between C and C++ when defining sequence points. As an example, consider

(a += b) += c;

where a, b, and c all have type int. I believe that this expression has undefined behavior, even though it is well-formed. It is not well-formed in C, because += returns an rvalue there. The reason for the undefined behavior is that it modifies the value of a' twice between sequence points.

Expressions such as this one are sometimes genuinely useful. Of course, we could write this particular example as

a += b; a += c;

void scale(double* p, int n, double x, double y) {
for (int i = 0; i < n; ++i) {
(p[i] *= x) += y;
}
}

All of the potential rewrites involve multiply-evaluating p[i] or unobvious circumlocations like creating references to the array element.

One way to deal with this issue would be to include built-in operators in the rule that puts a sequence point between evaluating a function's arguments and evaluating the function itself. However, that might be overkill: I see no reason to require that in

x[i++] = y;

the contents of i' must be incremented before the assignment.

A less stringent alternative might be to say that when a built-in operator yields an lvalue, the implementation shall not subsequently change the value of that object as a consequence of that operator.

I find it hard to imagine an implementation that does not do this already. Am I wrong? Is there any implementation out there that does not do the right thing' already for (a += b) += c?

5.17  expr.ass paragraph 1 says,

The result of the assignment operation is the value stored in the left operand after the assignment has taken place; the result is an lvalue.
What is the normative effect of the words "after the assignment has taken place"? I think that phrase ought to mean that in addition to whatever constraints the rules about sequence points might impose on the implementation, assignment operators on built-in types have the additional constraint that they must store the left-hand side's new value before returning a reference to that object as their result.

One could argue that as the C++ standard currently stands, the effect of x = y = 0; is undefined. The reason is that it both fetches and stores the value of y, and does not fetch the value of y in order to compute its new value.

I'm suggesting that the phrase "after the assignment has taken place" should be read as constraining the implementation to set y to 0 before yielding the value of y as the result of the subexpression y = 0.

Note that this suggestion is different from asking that there be a sequence point after evaluation of an assignment. In particular, I am not suggesting that an order constraint be imposed on any side effects other than the assignment itself.
Francis Glassborow:

My understanding is that for a single variable:

Multiple read accesses without a write are OK
A single read access followed by a single write (of a value dependant on the read, so that the read MUST happen first) is OK
A write followed by an actual read is undefined behaviour
Multiple writes have undefined behaviour
It is the 3) that is often ignored because in practice the compiler hardly ever codes for the read because it already has that value but in complicated evaluations with a shortage of registers, that is not always the case. Without getting too close to the hardware, I think we both know that a read too close to a write can be problematical on some hardware.

So, in x = y = 0;, the implementation must NOT fetch a value from y, instead it has to "know" what that value will be (easy because it has just computed that in order to know what it must, at some time, store in y). From this I deduce that computing the lvalue (to know where to store) and the rvalue to know what is stored are two entirely independent actions that can occur in any order commensurate with the overall requirements that both operands for an operator be evaluated before the operator is.

Erwin Unruh:

C distinguishes between the resulting value of an assignment and putting the value in store. So in C a compiler might implement the statement x=y=0; either as x=0;y=0; or as y=0;x=0; In C the statement (x += 5) += 7; is not allowed because the first += yields an rvalue which is not allowed as left operand to +=. So in C an assignment is not a sequence of write/read because the result is not really "read".

In C++ we decided to make the result of assignment an lvalue. In this case we do not have the option to specify the "value" of the result. That is just the variable itself (or its address in a different view). So in C++, strictly speaking, the statement x=y=0; must be implemented as y=0;x=y; which makes a big difference if y is declared volatile.

Furthermore, I think undefined behaviour should not be the result of a single mentioning of a variable within an expression. So the statement (x +=5) += 7; should NOT have undefined behaviour.

In my view the semantics could be:

if the result of an assignment is used as an rvalue, its value is that of the variable after assignment. The actual store takes place before the next sequence point, but may be before the value is used. This is consistent with C usage.
if the result of an assignment is used as an lvalue to store another value, then the new value will be stored in the variable before the next sequence point. It is unspecified whether the first assigned value is stored intermediately.
if the result of an assignment is used as an lvalue to take an address, that address is given (it doesn't change). The actual store of the new value takes place before the next sequence point.
Jerry Schwarz:

My recollection is different from Erwin's. I am confident that the intention when we decided to make assignments lvalues was not to change the semantics of evaluation of assignments. The semantics was supposed to remain the same as C's.

Ervin seems to assume that because assignments are lvalues, an assignment's value must be determined by a read of the location. But that was definitely not our intention. As he notes this has a significant impact on the semantics of assignment to a volatile variable. If Erwin's interpretation were correct we would have no way to write a volatile variable without also reading it.

Lawrence Crowl:

For x=y=0, lvalue semantics implies an lvalue to rvalue conversion on the result of y=0, which in turn implies a read. If y is volatile, lvalue semantics implies both a read and a write on y.

The standard apparently doesn't state whether there is a value dependence of the lvalue result on the completion of the assignment. Such a statement in the standard would solve the non-volatile C compatibility issue, and would be consistent with a user-implemented operator=.

Another possible approach is to state that primitive assignment operators have two results, an lvalue and a corresponding "after-store" rvalue. The rvalue result would be used when an rvalue is required, while the lvalue result would be used when an lvalue is required. However, this semantics is unsupportable for user-defined assignment operators, or at least inconsistent with all implementations that I know of. I would not enjoy trying to write such two-faced semantics.

Erwin Unruh:

The intent was for assignments to behave the same as in C. Unfortunately the change of the result to lvalue did not keep that. An "lvalue of type int" has no "int" value! So there is a difference between intent and the standard's wording.

So we have one of several choices:

live with the incompatibility (and the problems it has for volatile variables)
make the result of assignment an rvalue (only builtin-assignment, maybe only for builtin types), which makes some presently valid programs invalid
introduce "two-face semantics" for builtin assignments, and clarify the sequence problematics
make a special rule for assignment to a volatile lvalue of builtin type
I think the last one has the least impact on existing programs, but it is an ugly solution.

Andrew Koenig:

Whatever we may have intended, I do not think that there is any clean way of making

volatile int v;
int i;

i = v = 42;

have the same semantics in C++ as it does in C. Like it or not, the subexpression v = 42 has the type reference to volatile int,'' so if this statement has any meaning at all, the meaning must be to store 42 in v and then fetch the value of v to assign it to i.

Indeed, if v is volatile, I cannot imagine a conscientious programmer writing a statement such as this one. Instead, I would expect to see

v = 42;
i = v;

if the intent is to store 42 in v and then fetch the (possibly changed) value of v, or
v = 42;
i = 42;

if the intent is to store 42 in both v and i.

What I do want is to ensure that expressions such as `i = v = 42'' have well-defined semantics, as well as expressions such as (i = v) = 42 or, more realistically, (i += v) += 42 .

I wonder if the following resolution is sufficient:

Append to 5.17  expr.ass paragraph 1:

There is a sequence point between assigning the new value to the left operand and yielding the result of the assignment expression.
I believe that this proposal achieves my desired effect of not constraining when j is incremented in x[j++] = y, because I don't think there is a constraint on the relative order of incrementing j and executing the assignment. However, I do think it allows expressions such as (i += v) += 42, although with different semantics from C if v is volatile.

Notes on 10/01 meeting:

There was agreement that adding a sequence point is probably the right solution.

Notes from the 4/02 meeting:

The working group reaffirmed the sequence-point solution, but we will look for any counter-examples where efficiency would be harmed.

For drafting, we note that ++x is defined in 5.3.2  expr.pre.incr as equivalent to x+=1 and is therefore affected by this change. x++ is not affected. Also, we should update any list of all sequence points.

Notes from October 2004 meeting:

Discussion centered around whether a sequence point "between assigning the new value to the left operand and yielding the result of the expression" would require completion of all side effects of the operand expressions before the value of the assignment expression was used in another expression. The consensus opinion was that it would, that this is the definition of a sequence point. Jason Merrill pointed out that adding a sequence point after the assignment is essentially the same as rewriting

b += a

as

b += a, b

Clark Nelson expressed a desire for something like a "weak" sequence point that would force the assignment to occur but that would leave the side effects of the operands unconstrained. In support of this position, he cited the following expression:

j = (i = j++)

With the proposed addition of a full sequence point after the assignment to i, the net effect is no change to j. However, both g++ and MSVC++ behave differently: if the previous value of j is 5, the value of the expression is 5 but j gets the value 6.

Clark Nelson will investigate alternative approaches and report back to the working group.

int a,b,c;
int *p;
a=100;
c=10;
p=&c;
b=a/*p;
printf("%d",b);