Re: [問題] 指標問題

看板C_and_CPP (C/C++)作者 (小西風最乖了*^^*)時間12年前 (2011/07/23 22:10), 編輯推噓1(1016)
留言17則, 4人參與, 最新討論串8/13 (看更多)
這篇有點長,而且我怎麼想都覺得不引經據典一下不行 orz 這篇重點在於講 C++ 的規定(而不是回答第一篇的問題 xD)。 雖然我也覺得 dendrobium 圖畫得很精美,可是有錯還是想講。 (不好意思有些地方就把圖刪掉了) 一言以蔽之,指標的格式、物件的結構等等,標準給了編譯器 非常大的彈性去實作;許許多多的「逆向工程」只能了解自己用的 編譯器在自己電腦上怎麼實作的,而不是放諸四海 98% 準的標準... ※ 引述《dendrobium (石斛蘭)》之銘言: : ※ 引述《QQ29 (我愛阿蓉)》之銘言: : : 以下是我做的小小測試 不過我故意不寫成繼承 : : class AA{ : : public: : : AA():x(0),a(0){} : : int x; : : int a; : : void FOO(){cout<<"A"<<endl;} : : }; : : class BB{ : : public: : : BB():y(0.0),b(0.0){} : : double y; : : double b; : : int z; : : void FOO(){cout<<"B"<<endl;} : : }; : : int main() : : { : : BB *pb=new BB; : pb 指向 BB 物件的第一個位置 : ↙ : +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ : | | | | : +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ : \ / \ / \ / : y b z 這是剛好這個編譯器才這樣。 首先 BB 物件有自訂的建構子,所以不是 POD(就是那種只用來 擺資料的型態)。就我所知標準只有說 POD 結構用 reinterpret_cast 轉換後會指向第一個成員。(如果哪裡還有規定我漏看,歡迎指正) | A pointer to a POD-struct object, suitably converted | using a reinterpret_cast, points to its initial member @ C++98 9.2/17 即使是 POD 中間可能也有加空白喔(除了最開始不能加以外)。 : : AA* p=(AA*)pb; : 把pb這個位置當成是AA物件的位置丟給p 簡單來說,因為沒有繼承關係,就我理解是實作高興就好。(因 為 C++ 標準實在太複雜了,如果有人發現什麼我漏掉的規定歡迎指 正。) : : p->x=5; : p->x 是第一個位置 所以應該是 y 的前四個 byte 理由和結果同上兩點。 : : char *ptr=(char*)&pb->y; : y 是BB物件的第一個位置 所以等同於把 pb 所指的位置傳給 ptr 結果和理由還是一樣 orz : : ptr-=4; 未定義!完全看實作(其實光這行就會污染到整個程式)。 : 假如沒有 : : cout<<(int)*ptr; : 把 ptr 所指的位置當成 int 輸出 : 所以不意外會是 5 編譯器通常不管你的「企圖」是什麼,只會挑技術簡單,然後大家又 不會抱怨的方法實作。 : : return 0; : : } : 那如果 ptr -= 4 的話呢? : 就跑到前面了... 未定義。完全看實作。 === 推文時間 xDDD : 推 softwind:可是c++ primer裡面說 變數宣告和排列不一定相同 01/31 01:22 非常嚴格來說,實作只要模擬出標準定的那個虛擬機器的行為就好, 不過這裡就假設用正常的記憶體當作記憶體好了(否則沒完沒了)。 如果你是說成員在程式碼中的順序和記憶體中的順序的話,的確不一 定相同!但在這裡順序是一樣的,因為都是 public... | Nonstatic data members of a (non-union) class declared | without an intervening access-specifier are allocated | so that later members have higher addresses within a | class object. @ C++03 9.2/12 也就是說如果跟什麼 private 混在一起就不一定了。另外順序一樣 也不代表「緊密相接」。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.30.39 ※ 編輯: Favonia 來自: 140.112.30.39 (07/23 22:28)

07/24 01:19, , 1F
我愈來愈覺得你對UB抱持著很深的怨恨....
07/24 01:19, 1F
如果是我個人意見的話,我對於 C 語言有一堆 UB 還好,因為這語 言一開始就擺明了要追求無人可以超越的效率。代價是這語言放了很多責 任在程式設計師上。我比較在乎的是寫 C 語言的程式設計師有沒有意識 到這個語言放了一堆責任在程式設計師上。有趣的是,在我經驗中,大家 寫組語好像都滿小心的,可是 C 就沒那麼小心的樣子。我個人覺得這兩 個是差不多危險的東西。 UB 本身的意思只是說 C 語言沒有規定,但系統中還有其他文件可以 看啊。只要其他文件有規定,那在那系統中就不會引爆核彈。說起來我的 願望可能更像... 希望更多人可以意識到 C 語言很多都故意不規定清楚; 如果真的要玩底層,一定要閱讀平台或編譯器相關文件,不要把自己系統 的作法當作全世界的標準。 以上都跟技術無關,純粹個人看法。我平常盡量只談技術的事情 xD ※ 編輯: Favonia 來自: 140.112.30.39 (07/24 10:10)

07/24 08:40, , 2F
看來即使我看懂那三篇,還是遠遠不夠阿
07/24 08:40, 2F
※ 編輯: Favonia 來自: 140.112.30.39 (07/24 10:11) ※ 編輯: Favonia 來自: 140.112.30.39 (07/24 10:12) ※ 編輯: Favonia 來自: 140.112.30.39 (07/24 10:20)

07/24 22:39, , 3F
你有沒有想過 假如compiler不鳥所謂的"標準"的話
07/24 22:39, 3F

07/24 22:40, , 4F
因為C的歷史比"標準"的出現還古老....
07/24 22:40, 4F

07/24 22:42, , 5F
即使是以新的"標準"寫的code 但不見得compiler會支援呀
07/24 22:42, 5F

07/24 22:43, , 6F
"標準"本身也似乎沒啥強制力的....
07/24 22:43, 6F
現在大部分編譯器都有支援大部分的 C99 / C++98, 就連 POSIX 都 像基於 C 標準之上了。許多編譯器也都喜歡往自己臉上貼金說「我有支 援標準」,然後很多教學文件也把 C90 和 K&R 視為舊時代標準...所以 我想在大家愛面子(?)的情況下會努力支援新標準的。另一方面,標準 委員會也很在乎新功能是不是「成熟」,所以我想不至於訂出太離譜的標 準。像是 C1X Charter 有寫: | Additional Principles for C1X | | 13. Unlike for C9X, the consensus at the London meeting | was that there should be no invention, without exception. | Only those features that have a history and are in common | use by a commercial implementation should be considered. | Also there must be care to standardize these features | in a way that would make the Standard and the commercial | implementation compatible. 總之我認為實務上學習標準是可行的。我覺得問題反而是標準很多東 西故意不講清楚,而不是規定太多大家不想實作...

07/24 22:55, , 7F
一份code在外在條件足夠下可以跨平台
07/24 22:55, 7F
(我沒看懂上面這句 orz) ※ 編輯: Favonia 來自: 140.112.30.39 (07/25 00:28)

07/25 00:38, , 8F
sorry 我那句是打錯的XD
07/25 00:38, 8F

07/25 00:41, , 9F
不過標準的發展較其他編譯器or平台所支援的較晚...
07/25 00:41, 9F

07/25 00:42, , 10F
有時會為了platform反而會有限制...
07/25 00:42, 10F

07/25 00:42, , 11F
比方說flac
07/25 00:42, 11F
可以問一下 flac 是指什麼嗎?

07/25 04:55, , 12F
我推 firejox 大,沒要戰之意,但若為vc愛好者,compiler
07/25 04:55, 12F

07/25 04:55, , 13F
如何實做了解後,似乎比了解標準怎做來得有意義 XD
07/25 04:55, 13F
先說我沒有反對去學特定編譯器或特定平台在幹麼 xDDD 我反對的是 錯把特定實作的行為當成全世界的標準 xD 另外 VC 也很愛宣稱自己符合 標準,一些地方也慢慢改成符合標準的作法了;所以我覺得學標準還是有 好處,因為現在不符合標準的地方可能以後就改掉了! xD ※ 編輯: Favonia 來自: 140.112.30.39 (07/25 07:39)

07/25 09:56, , 14F
flac對於超過2GB的檔案(大檔案)處理會有問題
07/25 09:56, 14F

07/25 10:00, , 15F
裏面有用到fseek (雖然我不確定現在有沒有改)
07/25 10:00, 15F

07/25 10:01, , 16F
雖然說是標準 但有時候反而沒辦法符合現實需求
07/25 10:01, 16F
剛才稍微查一下,這好像比較像是 32 位元作業系統本身的限制耶。 如果是 POSIX 已經加了這個東西: @ http://www.opengroup.org/platform/lfs.html 然後 FLAC 好像也改了: | FLAC 1.1.3 (27-Nov-2006) | General: | Large file (>2GB) support everywhere @ http://flac.sourceforge.net/changelog.html 所以雖然 C 語言標準沒辦法做到,作業系統的標準好像可以處理了。 ※ 編輯: Favonia 來自: 140.112.30.39 (07/25 14:52) ※ 編輯: Favonia 來自: 140.112.30.39 (07/25 15:13)

07/25 16:32, , 17F
又沒人規定一定要遵守(最新)的標準XD
07/25 16:32, 17F
雖然我不知道原因,但 VC++ 一直暗中提昇跟標準的契合度是事實 xD ※ 編輯: Favonia 來自: 140.112.30.39 (07/25 23:03) ※ 編輯: Favonia 來自: 140.112.30.39 (07/25 23:03) ※ 編輯: Favonia 來自: 140.112.30.39 (07/30 10:30)
文章代碼(AID): #1EAjP7Qe (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 8 之 13 篇):
1
1
4
13
5
21
13
58
5
39
1
28
1
9
文章代碼(AID): #1EAjP7Qe (C_and_CPP)