Re: [問題] 指標問題
看板C_and_CPP (C/C++)作者Favonia (小西風最乖了*^^*)時間12年前 (2011/07/23 22:10)推噓1(1推 0噓 16→)留言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
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
07/24 22:39, 3F
→
07/24 22:40, , 4F
07/24 22:40, 4F
→
07/24 22:42, , 5F
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
07/24 22:55, 7F
(我沒看懂上面這句 orz)
※ 編輯: Favonia 來自: 140.112.30.39 (07/25 00:28)
→
07/25 00:38, , 8F
07/25 00:38, 8F
→
07/25 00:41, , 9F
07/25 00:41, 9F
→
07/25 00:42, , 10F
07/25 00:42, 10F
→
07/25 00:42, , 11F
07/25 00:42, 11F
可以問一下 flac 是指什麼嗎?
→
07/25 04:55, , 12F
07/25 04:55, 12F
→
07/25 04:55, , 13F
07/25 04:55, 13F
先說我沒有反對去學特定編譯器或特定平台在幹麼 xDDD 我反對的是
錯把特定實作的行為當成全世界的標準 xD 另外 VC 也很愛宣稱自己符合
標準,一些地方也慢慢改成符合標準的作法了;所以我覺得學標準還是有
好處,因為現在不符合標準的地方可能以後就改掉了! xD
※ 編輯: Favonia 來自: 140.112.30.39 (07/25 07:39)
→
07/25 09:56, , 14F
07/25 09:56, 14F
→
07/25 10:00, , 15F
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
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)
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章