Re: [閒聊] i++ is undefined behavior?

看板Soft_Job作者 (のヮの)時間9年前 (2015/04/26 04:05), 9年前編輯推噓5(507)
留言12則, 6人參與, 最新討論串6/6 (看更多)
※ 引述《xxtuoo (看樣子是壞掉了 :~)》之銘言: : ※ 引述《ah7675 (阿毛)》之銘言: : : ++operator對於字串操作是極其常見(其他暫不提) : : 所以我一直以為這是很稀鬆平常而且基礎的寫法 : : 這是第一次遇到有人告知我這種寫法不准用,老實說有點難接受 : : 我完全理解"不要為了語法的漂亮而使用少見難懂的語法" : : 我自己也常這樣告誡自己,可是"難懂"的分界到底在哪裡? : : 同樣一句話由Google工程師或是學生說出來可以說是完完全全兩個世界 : : 因為兩者對"難"的定義可說完全不一樣! : : 另外再問一個: : : function pointer/function object也是怪物嗎? : 好久沒學新的東西了...果然是落伍了嗎? : void strcpy(char *s, char *t) : { : while( (*s++ = *t++) != '\0') ; : } : 先不論strcpy的安全性 : 這種++應該是很常見 : 想不到現在已經是不能被人接受的東西了 void strcpy(char *dst, char *src) { while (*src != '\0') { *dst = *src; ++dst; ++src; } *dst = '\0'; } 這兩版翻成機器碼是幾乎一樣的 (來源:Visual Studio Express 2013 for Windows Desktop) while (*dst++ = *src++); while (*src != '\0') { mov eax,dword ptr [dst] mov eax,dword ptr [src] mov ecx,dword ptr [src] movsx ecx,byte ptr [eax] mov dl,byte ptr [ecx] test ecx,ecx mov byte ptr [eax],dl je strcpy2+46h (01221476h) mov eax,dword ptr [dst] *dst = *src; mov cl,byte ptr [eax] mov eax,dword ptr [dst] mov byte ptr [ebp-0C1h],cl mov ecx,dword ptr [src] mov edx,dword ptr [dst] mov dl,byte ptr [ecx] add edx,1 mov byte ptr [eax],dl mov dword ptr [dst],edx ++dst; mov eax,dword ptr [src] mov eax,dword ptr [dst] add eax,1 add eax,1 mov dword ptr [src],eax mov dword ptr [dst],eax movsx ecx,byte ptr [ebp-0C1h] ++src; test ecx,ecx mov eax,dword ptr [src] je strcpy1+52h (01221412h) add eax,1 jmp strcpy1+1Eh (012213DEh) mov dword ptr [src],eax } jmp strcpy2+1Eh (0122144Eh) *dst = '\0'; mov eax,dword ptr [dst] mov byte ptr [eax],0 甚至可以發現第一版為了在 dst 遞增之前保留原本的值,還多了一段 mov 再從迴圈數來看,第一版因為整段做完才 test,賦值跟遞增都要 n + 1 次 第二版則是 n + 1 次賦值(包含迴圈外面的 *dst = '\0';) 跟 n 次遞增 姑且不論這種細微差異,第二版可讀性絕對大於第一版吧 第一版看的時候可能會想一下遞增的時間點,可能會想一下 * 跟 ++ 的優先度 更何況條件式裡面的 = 不管何時都會讓人毛毛的,想要多看他兩眼 第二版我是想不到什麼曖昧的地方 說不准這樣寫我也是覺得有點超過啦 但是在不影響效能的情況下,有更好讀的寫法,何樂而不為呢 : 至於function pointer/funciton object : 有再用有排序效果泛用容器的..set/map : 傳一個funciton 或functor : 當自己訂製元件的比較function : 應該是很常用的寫法 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.163.98.63 ※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1429992338.A.CF2.html

04/26 05:56, , 1F
哈哈,我就知道會有人搬組語出來講。
04/26 05:56, 1F

04/26 10:48, , 2F
優化過後呢?
04/26 10:48, 2F

04/26 15:43, , 3F
我玩了一下VC release build..還真的比較短..不過這年頭多
04/26 15:43, 3F

04/26 15:43, , 4F
數決..老人認命服眾..
04/26 15:43, 4F

04/26 15:53, , 5F
可惡,被搶先了XD
04/26 15:53, 5F
我也試了一下 http://i.imgur.com/D4XfZ8Q.jpg
迴圈部分是完全一樣的,差別在於他們計算位址的方式 strcpy2 在迴圈開始前多了一段計算 dst 跟 src 的 offset 為什麼會有這個差別我也不知道,大概跟 inline 的方式有關 順便試了 g++ (4.8.2, g++ -std=c++11 -O2 main.cpp) http://i.imgur.com/k1BxyzY.jpg
這就是只有順序不同了 我自己判斷可讀性標準是"一行裡面做的事情越少越好讀"這樣啦 不曉得大家認為的好讀是如何 ※ 編輯: holydc (111.248.194.201), 04/26/2015 17:40:30

04/26 19:24, , 6F
一"行"改一個statement較好理解。
04/26 19:24, 6F
這我有想過 但有人會在一行塞好幾個 statement,我覺得這也會造成閱讀困難 所以後來還是決定以行為單位 ※ 編輯: holydc (111.248.194.201), 04/26/2015 20:32:53

04/27 01:41, , 7F
複雜的statements 可以抽象成一個概念的function/method
04/27 01:41, 7F

04/27 01:41, , 8F
比較好閱讀,好過通通塞一行或多行
04/27 01:41, 8F

04/27 01:48, , 9F
其實我的想法是code就是說故事啊。聽者不需要知道的細節
04/27 01:48, 9F

04/27 01:48, , 10F
都用一個function name描述我會覺得好懂。
04/27 01:48, 10F

04/27 01:50, , 11F
有點像是用function name寫註解的感覺
04/27 01:50, 11F

04/27 13:51, , 12F
推有實驗精神
04/27 13:51, 12F
文章代碼(AID): #1LE_EIpo (Soft_Job)
討論串 (同標題文章)
文章代碼(AID): #1LE_EIpo (Soft_Job)