Re: [閒聊] i++ is undefined behavior?
※ 引述《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
04/26 15:43, 3F
→
04/26 15:43, , 4F
04/26 15:43, 4F
推
04/26 15:53, , 5F
04/26 15:53, 5F
迴圈部分是完全一樣的,差別在於他們計算位址的方式
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
04/26 19:24, 6F
這我有想過
但有人會在一行塞好幾個 statement,我覺得這也會造成閱讀困難
所以後來還是決定以行為單位
※ 編輯: holydc (111.248.194.201), 04/26/2015 20:32:53
→
04/27 01:41, , 7F
04/27 01:41, 7F
→
04/27 01:41, , 8F
04/27 01:41, 8F
→
04/27 01:48, , 9F
04/27 01:48, 9F
→
04/27 01:48, , 10F
04/27 01:48, 10F
→
04/27 01:50, , 11F
04/27 01:50, 11F
推
04/27 13:51, , 12F
04/27 13:51, 12F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 6 之 6 篇):