• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            那誰的技術(shù)博客

            感興趣領(lǐng)域:高性能服務(wù)器編程,存儲,算法,Linux內(nèi)核
            隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
            數(shù)據(jù)加載中……

            解讀google C++ code style談對C++的理解

            C++是一門足夠復(fù)雜的語言.說它"足夠復(fù)雜",是因為C++提供了足夠多編程范式--泛型, 模板, 面向?qū)ο? 異常,等等.順便說說,我已經(jīng)很久沒有跟進C++的最新發(fā)展了(比如C++0x), 所以前面列舉出來的特性應(yīng)該只是C++所有特性的一個部分罷了.C++特性過多很難駕馭好C++的原因之一.另一個原因是C++過于"自作聰明",在很多地方悄無聲息的做了很多事情, 比如隱式的類型轉(zhuǎn)換, 重載, 模板推導(dǎo)等等.而很多時候,這些動作難以察覺,有時候會在你意想不到的地方發(fā)生,即使是熟練的C++程序員也難免被誤傷.(關(guān)于了解C++編譯器自作聰明做了哪些事情, <<深入理解C++物件模型>>是不錯的選擇).

            世界上有很多問題, 人們知道如何去解決.但是, 似乎這還不算是最高明的,更高明的做法是學(xué)會避免問題的發(fā)生.而如何避免問題的發(fā)生, 需要經(jīng)驗的積累--曾經(jīng)犯下錯誤,吃一塹長一智,于是知道哪些事情是不該做的或者是不應(yīng)該這么做的.

            google C++ code style是google對外公布的一份google內(nèi)部編寫C++的代碼規(guī)范文檔.與其他很多我曾經(jīng)看過的編碼文檔一樣,里面有一些關(guān)于代碼風格的規(guī)定,也就是代碼的外觀,這一部分不在這里過多討論,畢竟代碼如何才叫"美觀"是一個見仁見智的話題.在這里專門討論這份文檔中對一些C++特性該如何使用的討論,最后再做一個總結(jié).注意其中的序號并不是文檔中的序號,如果要詳細了解,可以自己去看這份文檔.

            1) Static and Global Variables
               Static or global variables of 
            class type are forbidden: they cause hard-to-find bugs due to indeterminate order of construction and destruction.
            google明確禁止全局對象是類對象, 只能是所謂POD(Plain Old Data,如int char等)數(shù)據(jù)才行.因為C++標準中沒有明確規(guī)定全局對象的初始化順序, 假設(shè)全局類對象A,B,其中A的初始化依賴于B的值, 那么將無法保證最后的結(jié)果.如果非要使用全局類對象, 那么只能使用指針, 在main等函數(shù)入口統(tǒng)一進行初始化.

            2) Doing Work in Constructors
            In general, constructors should merely 
            set member variables to their initial values. Any complex initialization should go in an explicit Init() method. 
            文檔規(guī)定, 在類構(gòu)造函數(shù)中對類成員對象做基本的初始化操作, 所有的復(fù)雜初始化操作集中一個比如Init()的函數(shù)中,理由如下:
            • There is no easy way for constructors to signal errors, short of using exceptions (which are forbidden).
            • If the work fails, we now have an object whose initialization code failed, so it may be an indeterminate state.
            • If the work calls virtual functions, these calls will not get dispatched to the subclass implementations. Future modification to your class can quietly introduce this problem even if your class is not currently subclassed, causing much confusion.
            • If someone creates a global variable of this type (which is against the rules, but still), the constructor code will be called before main(), possibly breaking some implicit assumptions in the constructor code. For instance, gflags will not yet have been initialized.
            簡單的概括起來也就是:構(gòu)造函數(shù)沒有返回值, 難以讓使用者感知錯誤;假如在構(gòu)造函數(shù)中調(diào)用虛擬函數(shù), 則無法按照使用者的想法調(diào)用到對應(yīng)子類中實現(xiàn)的虛擬函數(shù)(理由是構(gòu)造函數(shù)還未完成意味著這個對象還沒有被成功構(gòu)造完成).

            3) Default Constructors
            You must define a 
            default constructor if your class defines member variables and has no other constructors. Otherwise the compiler will do it for you, badly. 
            當程序員沒有為類編寫一個默認構(gòu)造函數(shù)的時候, 編譯器會自動生成一個默認構(gòu)造函數(shù),而這個編譯器生成的函數(shù)如何實現(xiàn)(比如如何初始化類成員對象)是不確定的.這樣,假如出現(xiàn)問題時將給調(diào)試跟蹤帶來困難.所以, 規(guī)范要求每個類都需要編寫一個默認構(gòu)造函數(shù)避免這種情況的出現(xiàn).

            4) Explicit Constructors
            Use the C
            ++ keyword explicit for constructors with one argument.
            假如構(gòu)造函數(shù)只有一個參數(shù), 使用explicit避免隱式轉(zhuǎn)換, 因為隱式轉(zhuǎn)換可能在你并不需要的時候出現(xiàn).

            5) Copy Constructors
            Provide a copy constructor and assignment 
            operator only when necessary. Otherwise, disable them with DISALLOW_COPY_AND_ASSIGN.
            只有當必要的時候才需要定義拷貝構(gòu)造函數(shù)和賦值操作符. 同上一條理由一樣, 避免一些隱式的轉(zhuǎn)換.另一條理由是,"="難以跟蹤,如果真的要實現(xiàn)類似的功能,可以提供比如名為Copy()的函數(shù),這樣子一目了然,不會像賦值操作符那樣可能在每個"="出現(xiàn)的地方出現(xiàn).

            6) Operator Overloading
            Do not overload operators except 
            in rare, special circumstances.
            不要重載操作符.同樣, 也是避免莫名其妙的調(diào)用了一些函數(shù).同上一條一樣, 比如要提供對"=="的重載, 可以提供一個名為Equal()的函數(shù), 如果需要提供對"+"的重載, 可以提供一個名為Add()的函數(shù).

            7) Function Overloading
            Use overloaded functions (including constructors) only 
            in cases where input can be specified in different types that contain the same information. Do not use function overloading to simulate default function parameters.
            只有在不同的類型表示同樣的信息的時候, 可以使用重載函數(shù).其他情況下,一律不能使用.使用重載, 也可能出現(xiàn)一些隱式出現(xiàn)的轉(zhuǎn)換.所以, 在需要對不同函數(shù)進行同樣操作的時候, 可以在函數(shù)名稱上進行區(qū)分, 而不是使用重載,如可以提供針對string類型的AppendString()函數(shù), 針對int類型的AppendInt()函數(shù),而不是對string和int類型重載Append()函數(shù).另一個好處在于, 在閱讀代碼時,通過函數(shù)名稱可以一目了然.

            8) Exceptions
            We 
            do not use C++ exceptions.
            不使用異常.理由如下:
            • When you add a throw statement to an existing function, you must examine all of its transitive callers. Either they must make at least the basic exception safety guarantee, or they must never catch the exception and be happy with the program terminating as a result. For instance, if f() calls g() calls h(), and h throws an exception that f catches, g has to be careful or it may not clean up properly.
            • More generally, exceptions make the control flow of programs difficult to evaluate by looking at code: functions may return in places you don't expect. This results maintainability and debugging difficulties. You can minimize this cost via some rules on how and where exceptions can be used, but at the cost of more that a developer needs to know and understand.
            • Exception safety requires both RAII and different coding practices. Lots of supporting machinery is needed to make writing correct exception-safe code easy. Further, to avoid requiring readers to understand the entire call graph, exception-safe code must isolate logic that writes to persistent state into a "commit" phase. This will have both benefits and costs (perhaps where you're forced to obfuscate code to isolate the commit). Allowing exceptions would force us to always pay those costs even when they're not worth it.
            • Turning on exceptions adds data to each binary produced, increasing compile time (probably slightly) and possibly increasing address space pressure.
            • The availability of exceptions may encourage developers to throw them when they are not appropriate or recover from them when it's not safe to do so. For example, invalid user input should not cause exceptions to be thrown. We would need to make the style guide even longer to document these restrictions!
            上面提到的理由中, 我認為使用異常最大的害處就是:異常的使用導(dǎo)致了程序無法按照代碼所展現(xiàn)的流程去走的, 比如代碼里面寫了步驟一二三,但是假如有異常出現(xiàn), 這就不好預(yù)知代碼真正步進的步驟了, 在出現(xiàn)問題時, 給調(diào)試和跟蹤帶來困難.
            另外, 我更喜歡unix API的設(shè)計.熟悉unix編程的人都知道, unix API基本上都遵守下列規(guī)則:
            a) 返回0表示成功, 其他(一般是-1)表示失敗.
            b) 在失敗時, 可以根據(jù)errno判斷失敗的原因, 這些在man手冊中都是會清楚的描述.

            總結(jié)一下, 這份規(guī)范中規(guī)避的C++特性大致分為以下幾類:
            a) 避免使用那些沒有確定行為的特性:如全局變量不能是類對象(初始化順序不確定), 不使用編譯器生成的默認構(gòu)造函數(shù)(構(gòu)造行為不確定), 異常(代碼走向不確定).
            b) 避免使用那些隱式發(fā)生的操作:如聲明單參數(shù)構(gòu)造函數(shù)為explict以避免隱式轉(zhuǎn)換, 不定義拷貝構(gòu)造函數(shù)避免隱式的拷貝行為, 不使用操作符重載避免隱式的轉(zhuǎn)換
            c) 對模棱兩可的特性給予明確的規(guī)定:不使用函數(shù)重載而是定義對每個類型明確的函數(shù).
            d) 即使出錯了程序也有辦法知道: 比如不能在類構(gòu)造函數(shù)中進行復(fù)雜的構(gòu)造操作, 將這些移動到類Init()的函數(shù)中.

            同時, 這份文檔中描述的大部分C++特性, 都是我之前所熟悉的(除了RTTI之外, 不過這里提到它也是要說明不使用它,另外還提到boost, 不過也是說的要對它"有限制"的使用,比如里面的智能指針).可以看到, 面對這樣一門復(fù)雜同時還在不停的發(fā)展更新特性的語言, google的態(tài)度是比較"保守"的.這與我之前對C++的理解也是接近的, 我一直認為C++中需要使用到的特性有基本的面向?qū)ο?STL就夠了(經(jīng)過最近的編碼實踐,我認為還得加個智能指針).我對這個"保守"態(tài)度的理解是, 以C++當前的應(yīng)用場景來看, 這些特性已經(jīng)足夠, 如果使用其他一些更加復(fù)雜的, 對人的要求提高了, 代碼的可讀性以及以后的可維護性就下降了.

            前面說過, 避免問題的出現(xiàn)比解決問題來的更加高明些, 而面對C++這一個提供了眾多特性, google C++ code style給予了明確的規(guī)定, 也就是每個行為, 如果都能做到有明確的動作, 同時結(jié)果也都是可以預(yù)知的, 那么會將出問題的概率最大可能的降低, 即使出了問題, 也容易跟蹤.

            上面描述的并不是這份文檔中有關(guān)C++的所有內(nèi)容, 只不過我覺得這些更加有同感些, 詳細的內(nèi)容, 可以參看這份文檔.都知道google的作品,質(zhì)量有保證, 除了人的素質(zhì)確實高之外, 有規(guī)范的制度保證也是重要的原因, 畢竟只要是人就會犯錯, 為了最大限度的避免人犯錯, 有一份詳盡的代碼規(guī)范, 寫好哪些該做哪些不該做哪些不該這么做, 也是制度上的保證.另外, 假如每個人都能以一個比較高的標準要求自己所寫的代碼, 久而久之, 獲得進步也是必然的結(jié)果.

            從這套規(guī)范里面, 我的另一個感悟是, 不論是什么行業(yè), "學(xué)會如何正確的做事情", 都是十分必要的.這個"正確的做事情", 具體到編碼來說, 就是代碼規(guī)范里面提到的那些要求.而除去編碼, 做任何的事情, 使用正確的方式做事, 都是盡可能少的避免錯誤的方法.但是, "錯"與"對"是相對而言的, 沒有之前"錯"的經(jīng)歷, 就不好體會什么叫"對".所以, "如何正確的做事", 說到了最后, 還得看個人的經(jīng)驗積累, 有了之前"錯誤"的經(jīng)歷,才能吃一塹長一智, "錯誤"并不是一無是處的, 只不過, 并不是誰都去嘗試著從中學(xué)習.


            posted on 2010-05-29 20:34 那誰 閱讀(38165) 評論(43)  編輯 收藏 引用 所屬分類: C\C++

            評論

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            因噎廢食
            2010-05-29 22:59 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @OwnWaterloo
            又學(xué)了一個成語"因噎廢食 ( yīn yē fèi shí )":原意是說,因為有人吃飯噎住了,索性連飯也不吃了,這太荒謬了。比喻要做的事情由于出了點小毛病或怕出問題就索性不去干

            能解釋一下在這里針對這個帖子做這個回復(fù)的含義么?

            2010-05-29 23:02 | 那誰

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @那誰
            "C++某特性不理解,產(chǎn)生畏錯心理(或者已經(jīng)得到教訓(xùn));
            對此采取的措施不是去學(xué)習與理解這些特性, 而是放棄這些特性。"


            對筷子不熟悉,不嘗試學(xué)習與熟練,而是放棄 —— 這也不是不行, 畢竟用刀叉(甚至手抓)也算是吃飯 —— 但是, 如果是中餐的話, 這并不是什么值得為之感到光榮的事。


            吃飯不同于軟件開發(fā)的地方是:
            餐桌上的同伴吃中餐不用筷子最多最多讓人感到難堪。
            而項目中的隊員如果做不到步調(diào)一致, 就可能導(dǎo)致項目失敗。
            但是, 相比這飯吃得是否得體, 步調(diào)一致更為重要。
            所以, 為了那些因噎廢食的人, 不得不同他們一起"吃手抓飯", 從而達到步調(diào)一致, 也是很無奈的事。
            —— 這依然不是什么值得炫耀的事情。


            在正常控制流中插入的另一條控制流是異常的關(guān)鍵。
            正是這條非尋常的控制流, 導(dǎo)致學(xué)習成本。
            如果愿意去學(xué)習這條控制流的規(guī)則, 就能得到這條控制流帶來的好處:
            它確實將“錯誤的檢測與處理”給分開了。
            —— 中餐是否值得吃,就是在學(xué)習成本與所有層次上的所有錯誤都必須“手工地”檢測并向上報告(即使不處理任何錯誤)之前做選擇。


            越來越多的語言加入異常處理機制(甚至是一些原本沒有的語言)。
            并且, 在正常控制流之外的控制流并不只在異常處理中出現(xiàn): 信號, thread_cancel都有,

            要么“永遠逃避所有使用非正常控制流的技術(shù)”。
            —— 永遠不去學(xué)習如何使用筷子。

            要么去學(xué)習任意一種, 并舉一反三。
            —— 學(xué)習筷子的使用后, 品嘗中餐的諸多菜系都有基礎(chǔ)了。


            關(guān)于google, 我感到困惑的是: 對google中的python和java程序員是否也有不許使用異常的規(guī)定。
            我想應(yīng)該是沒有的。
            那么, 換來的結(jié)論就是: goolge中的C++程序員, 對異常這種編程思想的理解, 還不如google中的python和java程序員。
            2010-05-29 23:59 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @那誰
            一說就起勁了……

            再說說操作符重載。 equals add vs ==, +

            記號系統(tǒng)的嚴謹與簡潔都很重要。
            以前我也只注重記號系統(tǒng)的嚴謹, 認為嚴謹?shù)木褪且鬃x、易理解的。
            直到讀了這篇文章:
            http://www.ibm.com/developerworks/cn/xml/x-matters/part24/index.html

            清單3中的xml就是嚴謹而不簡潔的。 即使不學(xué)習任何新事物, 也大致能猜出清單3表示的是什么內(nèi)容。
            而清單2的記號系統(tǒng)就是簡潔的, 同時也是嚴謹?shù)?—— 只是需要學(xué)習這套記號系統(tǒng)。

            如果不學(xué)習清單2中的記號系統(tǒng), 那清單2可能就是天書。
            如果學(xué)習了, 那清單2就幾乎是"用極少廢話作輔助, 表達作者的意思"。

            而清單3,無論是否學(xué)習, 都是很羅嗦的在表達作者的含義, 包含了太多的噪音。

            我覺得(只是覺得, 因為歷史不能重演), 如果微積分的記號系統(tǒng)不是隨微積分一起產(chǎn)生, 微積分是發(fā)展不起來的。
            將表達式中的Sx 全部替換成 interal(x); 記號是不需要學(xué)了, 但這表達式根本沒法讀。

            所以, 不是簡潔的記號系統(tǒng)不可取, 而是記號系統(tǒng)在簡潔的同時還要保持直觀, 嚴謹, 無歧義。
            要設(shè)計出這樣的記號系統(tǒng)是需要精心的、 全局的、 周詳?shù)臏蕚洹?br>而C++的操作符重載讓記號的引入變得太容易, 獲得簡潔的同時容易丟失其他方面的因素。

            上面回復(fù)已經(jīng)說到google中C++程序員的素質(zhì)。
            與其于讓他們理解直觀、嚴謹、無歧義, 直接讓他們不許使用新的記號系統(tǒng)可能更省事。
            但無論如何, 這所謂的"高標準"的規(guī)范, 其實只是"無奈"之舉, 而非"進步"。
            2010-05-30 00:23 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            目前 Google 公開的大量 C++ 代碼都遵循了這份規(guī)范。
            這些公開的代碼的質(zhì)量都很高,值得借鑒。
            2010-05-30 08:36 | 陳碩

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @OwnWaterloo
            那你能對規(guī)范中描述的異常的缺陷進行回復(fù)么?我里面提到的,由于引入了異常,導(dǎo)致代碼走向難以預(yù)測,這一點如何解決?類似unix API那樣的,根據(jù)返回值判斷是否成功,根據(jù)errno判斷失敗原因,是非常簡潔明了的做法,我更傾向于設(shè)計出這樣的API.
            2010-05-30 08:43 | 那誰

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @OwnWaterloo
            另外,我見到的google開源出來的python代碼不多,java我不會,就更沒看過了,但是這份python代碼:
            http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py
            里面似乎就沒有使用到異常.
            2010-05-30 08:45 | 那誰

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @那誰
            "我里面提到的,由于引入了異常,導(dǎo)致代碼走向難以預(yù)測,這一點如何解決?"
            你這個問題就像:
            由于引入了指針(甚至雙指針), 導(dǎo)致代碼難以理解,充滿bug, 這一點應(yīng)該如何解決?
            難道我們應(yīng)該放棄指針(和雙指針)?

            "指針"還可以替換成很多東西。

            一句話, 不學(xué), 什么都難以理解。
            如何解決?
            1. 讓代碼保持異常安全 —— 無論異常是否發(fā)生。
            什么游戲都需要規(guī)則,這是使用異常的最關(guān)鍵規(guī)則。
            pthread_cancel有相應(yīng)的cancellation safety。
            信號有相應(yīng)的可重入。

            2. 如果沒有異常需要處理, 讓異常直接向上報告 —— 無須任何額外代碼
            而使用狀態(tài)代碼, 即使某個層次不能處理錯誤, 也必須編寫代碼去檢測, 并向上報告(除非想吞掉這個錯誤)。
            "每一層", "每一個調(diào)用點"。

            狀態(tài)代碼不優(yōu)美的地方之一 —— 太多重復(fù)代碼, 這些代碼并不是為了處理這個錯誤, 僅僅是為了向上報告錯誤, 所以不得不編寫代碼去檢測。

            不優(yōu)美的地方之二 —— 檢測代碼和happy path代碼混雜在一起, 使得happy path中至少一半代碼都是和邏輯無關(guān)的, 所謂的噪音。
            上面記號系統(tǒng)中說過, 積分記號確實需要學(xué)習成本, 但換來的好處就是用最少的噪音表達出盡可能多的信息。

            不優(yōu)美的地方之三 —— caller和callee之間報告錯誤所使用契約的耦合。
            當caller是一個普通的函數(shù)這個問題還不突出。當caller是一個函數(shù)模板, 對應(yīng)的callee根本不知道是何物時, 如何定義callee和caller之間的報告錯誤的契約?
            "0表示Ok, 非0表示有問題, 問題寫在errno" 而errno這種全局的東西帶有全局的一切毛病, 比如:如何分配一個獨一無二的code?

            3. 如果需要處理當中的部分異常, try之, 并僅僅catch感興趣的異常, 處理之。
            接上面的, 如果不能得到一個獨一無二的code, 就無法知道究竟是出了什么毛病。
            EINVAL? 哪一個參數(shù)有問題? 什么問題? 信息早就丟了。
            無法有針對性的進行處理。


            更多的, 請看:
            http://blog.csdn.net/pongba/archive/2007/10/08/1815742.aspx


            而google coding style中所謂的不使用exception的理由, 在知道什么是異常處理的人的眼中, 只有最后2點是站得住腳的:
            最后一點, 也就是上一個回復(fù)說的"與其規(guī)定什么時候可以用, 應(yīng)該如何用", 不如直接"全面禁止" —— 因噎廢食。

            倒數(shù)第2點, 就是效率問題。 在"效率攸關(guān)"的地方, 確實不能用。
            但這種地方并不是想象中的那么多。

            其他都是扯談。 要么寫這個規(guī)范的人不懂exception, 要么就是他懂, 但故意牽強附會, 或者危言聳聽。


            另外, 這種高壓政策下的google的代碼我沒看過, 所以無法評論其質(zhì)量高低。
            但肯定是"原始且不美觀"的。
            而這種在高壓政策下產(chǎn)生出的"原始且不美觀"的其他代碼我倒是看過, 例如OpenCV和apr中的內(nèi)存管理部分 —— 在這種"泯滅人類的思維與創(chuàng)造性, 僅僅將人作為制造code的工具"的高壓政策下壓榨出的代碼, 質(zhì)量怎么可能高?
            2010-05-30 20:11 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @OwnWaterloo
            我反對你以偏概全將使用異常的態(tài)度推及到指針使用,這不是具體問題具體分析的態(tài)度.
            其次,你的語氣有些過于狂妄了.就結(jié)果而言,google出品的這些軟件,雖然大部分都看不到代碼,從使用的角度看,質(zhì)量是有目共睹的,反之看它們的一些規(guī)定做法,有可取之處,而不是像你所言的"質(zhì)量怎么可能高".
            我還是堅持我的看法,異常的使用導(dǎo)致了程序的走向難以從代碼中一目了然的看出來,給問題定位帶來困難.
            2010-05-30 20:33 | 那誰

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @那誰
            我說的是OpenCV和apr的內(nèi)存管理部分的質(zhì)量, 請仔細看。

            還是那句話: 不學(xué), 什么都困難。
            這種所謂的"C++應(yīng)該避免使用異常"和java程序員所謂的"應(yīng)該避免使用指針, 所以我們使用java"有什么區(qū)別?


            "異常的使用導(dǎo)致了程序的走向難以從代碼中一目了然的看出來,給問題定位帶來困難." —— 而這才是你的偏見。
            就你這句話就能推斷你沒什么使用異常的經(jīng)驗, 而是出于對異常的不理解與恐懼。
            請問我說錯沒有?
            2010-05-30 20:42 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @OwnWaterloo
            異常少量使用過,已經(jīng)基本不用,觀點已經(jīng)在前面闡述過.如果一個特性,我認為會給我?guī)砝_,同時目前所掌握的,已經(jīng)可以滿足我的需求,為什么我還要花時間去多學(xué)呢.有時候選擇過多,反而會帶來困擾吧.這個是我的觀點,無意強加于誰身上.同時,他人也無需強加于我身上.

            "另外, 這種高壓政策下的google的代碼我沒看過, 所以無法評論其質(zhì)量高低。
            但肯定是"原始且不美觀"的。"

            這句話里面的語調(diào),我個人認為過于狂妄了,呵呵.

            如果你不能心平氣和的討論問題,而使用一些自己臆斷的詞匯去描述,比如"原始切不美觀","質(zhì)量怎么可能高",我個人認為繼續(xù)下去的意義不大.
            2010-05-30 20:50 | 那誰

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @那誰
            java程序員也可以說自己"基本用不著指針", "手工內(nèi)存管理給我?guī)砹撕芏嗬_"。

            是否美觀并不是我臆斷, 這可以使用完成同樣功能(當然, 除了效率、以及二進制兼容行上不同)的代碼進行對比。 只是cppblog對貼代碼并不友好。
            所以, 我給出了劉未鵬一篇文章的鏈接。
            里面有完成同樣事情, 錯誤代碼如何做 vs 異常如何做 的代碼片段。

            如果你對異常處理沒經(jīng)驗, 錯誤代碼肯定很有經(jīng)驗吧?
            1. 即使不能處理, 也必須檢測 —— 因為需要向上層報告
            2. 這些檢測, 重復(fù)出現(xiàn)在每個層次, 每個調(diào)用點
            3. 檢測代碼與邏輯代碼混雜
            4. 即使錯誤最終報告到一個可以處理的層次, 信息早就丟得7788了, 只剩下EINVAL這種含義模糊, 不知道應(yīng)該如何應(yīng)對的錯誤代碼。

            這些是否是實情?難道你不覺得這些手工的機械重復(fù)是不美觀的?
            而異常處理就是為了解決這些問題。


            原始也不是臆斷。 理由上面也有: 越來越多的語言開始加入異常機制。
            C++很早就加入了, 卻被程序員不分青紅皂白的拒之門外, 是否原始?
            2010-05-30 21:05 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            其實我覺得google禁止異常可能是處于與C代碼互操作困難的考慮,而不僅僅是新特性帶來的問題。如果是最終程序那怎么都好說,但作為一個庫,跟其他代碼如何進行跨編譯單元的異常傳遞和處理恐怕不是那么簡單。這是C++保留C連接能力必須付出的代價。而java顯然沒有這種問題。
            2010-05-31 16:45 | ptptt5

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            額。。。最后一個。。。
            2010-05-31 17:33 | 欣萌

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @那誰
            @OwnWaterloo
            1.在我的眼里,throw就如同if,如同for,如同while,如同break,如同continue,如同return,僅僅是一種跳轉(zhuǎn)機制。

            2.市面上所說的throw的危險程度,排除了因為程序員的畏懼而不學(xué)習之外,唯一說的過去的無非就是throw很難在ABI上得到兼容。不過google在服務(wù)器端編譯,因此不存在這種問題。存在的話是google的代碼版本管理(這其中也包含編工具版本管理)的缺陷而不是throw的缺陷

            3.throw帶來類型系統(tǒng)的美,帶來錯誤與處理的解耦。就如同linus所說,因為C++太難學(xué)(對于他本人可能不一定),因此禁止在linux里面使用C++。google的意思可能也是如此。我說的僅僅是可能,因為C++高手不多,反正招進去的都不太信任,所以干脆就禁掉算了。Microsoft相反,不會就學(xué)。

            4.throw在學(xué)術(shù)上也是一個優(yōu)美的類型系統(tǒng)的范例。當然這跟我們開發(fā)項目可能沒什么大的關(guān)系,但這卻是必然會出現(xiàn)的。原因我就不多說了,因為也是非工程的。不過隨著越來越多的語言出現(xiàn),我們看可以看到基本上所有東西都支持異常,而且也用得很好,為啥就唯獨C++不行呢?因為他們心里沒譜,沒有catch(Exception e)這種萬能東西可以用,而且團隊也不肯花成本去研究所使用的框架的異常規(guī)則并制定他們自己的異常守則(沒時間估計是一個原因,像google和baidu和bing這類公司底下員工加班已成慣例),所以最賺錢的辦法就是——禁止

            結(jié)論:google禁止異常比較省錢。
            2010-05-31 19:22 | 陳梓瀚(vczh)

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @陳梓瀚(vczh)

            >>1.在我的眼里,throw就如同if,如同for,如同while,如同break,如同continue,如同return,僅僅是一種跳轉(zhuǎn)機制。
            而且, 這種跳轉(zhuǎn)機制我認為比goto/longjmp要好理解, 因為它是結(jié)構(gòu)化的。

            >>2.市面上所說的throw的危險程度,排除了因為程序員的畏懼而不學(xué)習之外,唯一說的過去的無非就是throw很難在ABI上得到兼容。
            嗯, exception真正從技術(shù)上不能被使用的原因就只有效率和二進制兼容性。
            其他都是"人文原因", "市場原因","成本原因", "金錢原因"。

            btw: 你發(fā)覺C++的二進制兼容性會闖禍了~?


            >>4. ... 因為他們心里沒譜,沒有catch(Exception e)這種萬能東西可以用 ...
            這倒不難, 敢用exception肯定要人為規(guī)定一個最終基類。
            即使沒有這樣的基類, 還可以catch( ... )
            2010-05-31 21:48 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @OwnWaterloo
            我一直都知道兼容性有問題,但是一個團隊使用相同的編譯器是應(yīng)該的,而且如果他們使用開源的庫的話,自己編譯更加安全。

            其他語言的Exception都有Message,這個可是好東西啊……而且catch(...)不能處理基本錯誤,譬如說access violation,還有divided by zero等等。
            2010-05-31 23:17 | 陳梓瀚(vczh)

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @陳梓瀚(vczh)
            >>但是一個團隊使用相同的編譯器是應(yīng)該的
            這也就暗示了C++庫最方便的復(fù)用形式是源代碼, 而不是二進制。


            >>其他語言的Exception都有Message,這個可是好東西啊……而且catch(...)不能處理基本錯誤,譬如說access violation,還有divided by zero等等。
            其他語言可以 throw 1212么? 1212怎么message?
            SEH可以處理那2種, 還可以轉(zhuǎn)化為C++ exception。 但是, 非Windows下?

            其他語言是通過"限制能夠被throw的對象的類型" —— 比如必須繼承自Exception;
            來達到使用catch (Exception e)就可以處理所有異常的目的。

            C++沒有這一限制, 需要自我限制。


            其他語言是通過某些平臺相關(guān)的機制: 比如SEH來處理access violation;
            或者是通過損失基礎(chǔ)運算的效率: 比如
            T& dereference(T* p) { if (p) return *p; throw nullptr_exception(); }
            unsigned plus(unsigned x, unsigned y)
            {
            if (UINT_MAX-x>y) return x+y;
            throw overflow_exception();
            }
            來得到這些錯誤的異常。

            C++不會添加這些保姆工作。


            所以, 其實也不算C++ exception相對于其他語言的劣勢, 只能算一種權(quán)衡。
            默認情況下, 不限制可拋出類型, 可以通過catch (...)來處理所有。
            如果需要, 可以自我規(guī)定一個基類。

            默認情況下, 不檢測基本運算的錯誤。
            如果需要, 自己檢測并拋出。
            2010-06-01 01:30 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            引用:“當程序員沒有為類編寫一個默認構(gòu)造函數(shù)的時候, 編譯器會自動生成一個默認構(gòu)造函數(shù),而這個編譯器生成的函數(shù)如何實現(xiàn)(比如如何初始化類成員對象)是不確定的”

            老兄能詳細解釋一下否?我不明白你這話里要說的意思,能否具體說說你擔心的“不確定”?
            2010-06-01 09:54 | Kenny Yuan

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @Kenny Yuan
            我的意思是編譯器生成的構(gòu)造函數(shù)不知道會給類成員對象賦什么初值.如果自己寫的話,給它們賦一個明確的初值,這樣在出問題的時候一看,知道這些都是沒有被初始化過的.
            2010-06-01 10:29 | 那誰

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @樓主

            明白你說的意思了,看來我們是在“類成員對象”中的“對象”一詞上的理解不一致了,呵呵

            2010-06-01 11:02 | Kenny Yuan

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @Kenny Yuan
            哦,怎么說?談?wù)勀愕睦斫?
            2010-06-01 11:03 | 那誰

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @那誰
            默認構(gòu)造函數(shù)的行為是"可預(yù)測"的。
            就在你文章第1段中提到的書"inside C++ object model"中就有。
            最關(guān)鍵的一句話: "編譯器合成的構(gòu)造函數(shù), 只為滿足C++的需要, 而不是程序員的需要。"


            所以, 默認構(gòu)造函數(shù)的行為是"可預(yù)測的", "確定的", 即 —— 具有trivial construct語意的member, 不會被初始化, 而是包含隨機值。


            關(guān)于隨機值的兩種處理:
            FILE* f;
            ...
            f = fopen( ... );

            還是
            FILE* f = 0;
            ...
            f = fopen( ... );


            后一種所謂的"規(guī)范寫法", 在我看來完全是多此一舉。
            當然, 如果你真的需要這種多余的動作:
            struct T {
            ... no constructor
            };

            T v = T(); // 不再是隨機值。 v中的每個值都是確定的。
            2010-06-01 17:48 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            boost::value_intialized<T>(x)
            2010-06-02 12:29 | 空明流轉(zhuǎn)

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @樓主

            C++標準關(guān)于ctor中成員的初始化順序/值/copy ctor/assign operator等都有詳細規(guī)定。你說的對象二字,在原句中,無論從狹義還是廣義上都不成立。但當你解釋完之后,我就知道你想要說的是哪種情形了(從寫法上看是調(diào)用者需要使用trivial ctor)。有什么疑問大家都回家看標準吧,我不多寫了(樓上有人寫了不少了)
            2010-06-02 19:06 | Kenny Yuan

            # re: 解讀google C++ code style談對C++的理解[未登錄]  回復(fù)  更多評論   

            @OwnWaterloo
            又一個技術(shù)流的家伙。c++中難學(xué)難用是出了名的。
            有幾個人啃過c++標準,幾個人的代碼量超過幾萬行的?
            軟件開發(fā)是一個工程,一個大家公認的簡單清晰的代碼規(guī)范,比使用所謂的高級特性給開發(fā)效率帶來的提升更多。
            2010-06-12 08:39 | dudu

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @dudu
            >> 一個大家公認的簡單清晰的代碼規(guī)范

            異常對于你們不清晰? 怪誰? 怪你沒入"技術(shù)流"?

            并不是大家公認, 使用異常的語言是越來越多, 只是你們不求進步而已。
            要說公認, 也就是固步自封流公認罷了。
            2010-06-12 08:51 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            路過,學(xué)習了
            2010-06-12 10:28 | 溪流

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            就想linus說的,C++是門讓人恐慌的語言,而更讓人恐慌的的是一些不專業(yè)的程序員正在使用它,google或許是從大局上考慮,畢竟這么大的一個公司能完全協(xié)調(diào)的都使用好異常等特性是比較難的,而現(xiàn)在這種激烈競爭的環(huán)境下,他們選擇保守,出半點差錯不起的啊。。。
            2010-06-26 10:42 | buffer

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            的確,有些c++程序員固步自封,自以為是得太厲害了,抗拒很多現(xiàn)代語言的東西。
            2010-06-29 10:08 | donglongchao

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            看到各位反對google的理由,感到十分親切,跟我當年想得一模一樣。
            成長總需要過程,沒見過哪個程序員夸耀自己的當年的遠見卓識,都是在反省自己的很傻很天真。
            2011-03-15 14:04 | dayn9

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @dayn9
            不要裝,好嗎?有什么話說出來,大家都可以受教~
            2011-03-15 21:32 | 溪流

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            中文社區(qū)果然全是噴子。。。
            2011-08-25 13:09 | lord

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            我覺得異常也好,rtti,既然用了c++就應(yīng)該是要使用的。既然stl的錯誤處理都是用異常實現(xiàn)的,難道連stl都不用了么?
            確實c++中有一些語言特性被公認標記為無用,例如異常規(guī)范與導(dǎo)出模板,但是異常絕不是其中之一。
            合情合理的使用語言特性才是一個真正的程序員應(yīng)該做的事情。
            2011-08-28 22:03 | watsonsong

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            mark...
            2011-08-30 13:06 | captivated

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @OwnWaterloo
            編碼規(guī)范是一種控制質(zhì)量的手段,制定者希望通過微調(diào)規(guī)范的每個細節(jié)讓整個產(chǎn)品的損益值達到最優(yōu)化,所以雖然有很多高手能把exception玩的滴水不漏,但作為整個產(chǎn)品系編碼規(guī)范的制定者,必須考慮到還有其他水平并不那么出色的開發(fā)者,另外,不知道你有沒有仔細讀過google列出的這些反對使用exception的觀點,很明顯的是,有些問題并不是技術(shù)牛逼就能解決的,很顯然excepion的完美使用過于繁瑣,而人又是容易犯錯的,所以在編譯器或者說語言本身沒辦法提供更智能化更安全糾錯機制的前提下,禁止使用exception也是非常值得理解的。最后,我又仔細看了你的回復(fù)內(nèi)容,發(fā)現(xiàn)你并沒有真正理解google的觀點,關(guān)于編寫異常安全代碼,可以看一下exceptional C++的第二章,然后再來這里發(fā)言吧。
            2011-09-26 23:24 | stepinto

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @stepinto
            上面有條回復(fù)正中要害:
            >> 結(jié)論:google禁止異常比較省錢。

            那么,你們禁止使用(了解)異常(以及其他各種技術(shù))是為了什么呢?
            為了當你所說的那種
            >> 水平并不那么出色的開發(fā)者
            對嗎? 你就甘愿當這種拖后腿的人,是嗎?

            >> 可以看一下exceptional C++的第二章,然后再來這里發(fā)言吧。
            不好意思,整個exceptional系列我都看過好多年了。
            你想得到的與想不到的C++書籍我都看過。
            你想得到的與想不到的C++技術(shù)我都玩過。
            所以我才看不起你們這種 *為自己的無能找借口* 的人。
            2011-09-26 23:51 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @OwnWaterloo
            暈,感覺是被那本“拒絕借口”給洗腦了。。。。
            2011-09-27 10:57 | stepinto

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            Google并沒有說異常就是不好。使用異常有好處,也有壞處。Google不推薦使用的最大原因是現(xiàn)有代碼使用異常的很少,也就是兼容性的原因。Style Guide里面也承認如果重頭開始一個項目,使用異常是利大于弊的。
            2011-10-14 10:06 | Zor X.L.

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            想請問一件事
            若果使用異常處理,通常隱含著代碼樹中會有非常多的異常類的檔案出現(xiàn)
            那么有什么比較有系統(tǒng)的方式維護這些眾多的異常類呢?
            2011-10-23 23:56 | UGP

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @UGP
            另外補充一篇
            http://chinesetrad.joelonsoftware.com/Articles/Wrong.html
            2011-10-24 14:21 | UGP

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            @UGP
            joel這篇文章足以暴露他思維層次太低。


            即使是在C語言中,對i+j,同樣不能確定它究竟做了什么。
            完全被優(yōu)化掉了?
            還是上下文中有重復(fù)計算,此處直接取的結(jié)果?
            但有多少人是真正關(guān)心i+j具體被如何處理,實現(xiàn)的么?
            絕大多數(shù)情況都不需要。

            那為什么對C++,就要求了解i+j是具體在干什么呢?
            做出這樣批評的人,都是 *只懂得C級別的抽象方式,不懂得C++級別的抽象方式* 而已。


            對異常也是如此。
            對自己熟悉的方式根深蒂固,以至于根本就無法恰當分析其他方式。
            他的批評,比如讓代碼難以理解,熟悉異常的人的眼中完全不可理解。


            而匈牙利更是扇自己嘴巴。
            他要的就是將safe與unsafe字符串通過某種方式告訴編譯器。
            比如用不同類型,限制它們之間的自由轉(zhuǎn)換,轉(zhuǎn)換只能通過可控制的有限方式。
            然后,讓 *編譯器自動地完成這樣的檢測* ,而不是什么手工肉眼去比。
            2011-10-25 00:51 | OwnWaterloo

            # re: 解讀google C++ code style談對C++的理解  回復(fù)  更多評論   

            關(guān)于異常這塊,你沒有看完http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Exceptions 的說明

            On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications on all dependent code. If exceptions can be propagated beyond a new project, it also becomes problematic to integrate the new project into existing exception-free code. Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions.

            2013-05-07 17:00 | baibaichen
            jizzjizz国产精品久久| 97视频久久久| 久久精品国产亚洲av瑜伽| 热综合一本伊人久久精品 | 久久久精品无码专区不卡| 亚洲精品国产自在久久| 久久精品国产亚洲AV大全| 久久精品成人免费观看97| 亚洲中文久久精品无码ww16| 伊人久久大香线蕉影院95| 2019久久久高清456| 狠狠色伊人久久精品综合网| 亚洲日本va中文字幕久久| 久久高潮一级毛片免费| 久久偷看各类wc女厕嘘嘘| 亚洲精品无码久久久久AV麻豆| 色综合久久无码五十路人妻 | 精品熟女少妇AV免费久久| 国产精品伦理久久久久久| 亚洲国产精品无码久久一区二区| 94久久国产乱子伦精品免费| 色偷偷久久一区二区三区| 色老头网站久久网| 久久亚洲天堂| 久久一区二区免费播放| 激情五月综合综合久久69| 国产精品久久一区二区三区| 久久99久久99精品免视看动漫| 亚洲国产精品无码久久久久久曰 | 97久久超碰国产精品2021| 777午夜精品久久av蜜臀| 亚洲国产成人乱码精品女人久久久不卡 | 一本一道久久精品综合| 精品精品国产自在久久高清| 久久亚洲国产成人精品性色| 婷婷久久久亚洲欧洲日产国码AV | 久久99热只有频精品8| 久久超乳爆乳中文字幕| 国产精品美女久久久久| 97r久久精品国产99国产精| 久久777国产线看观看精品|