2012-03-29 103 views
3

我是一名學生,我正在嘗試編寫並運行一些測試代碼,以便在調用之前檢查它。我現在想要做的是測試我的代碼正確地阻止了值語義。在我的任務中,我已經爲我的每個類聲明瞭自己的專用複製構造函數和賦值運算符,它們沒有定義,因此什麼都不做。當他們在我的測試程序中被調用時,我得到了像我預期的編譯錯誤。事情是這樣的:編譯錯誤的C++測試

error: 'myClass::myClass(const &myClass)' is private'

error: 'myClass& myClass::operator=(const myClass&)' is private

是否有使用try/catch語句,這樣我的測試代碼編譯和運行,但告訴我,這些錯誤確實發生的方法嗎? 我已經試過:

myClass obj1(...); 
myClass obj2(...); 
try{ 
    obj1 = obj2; 
    throw 1; 
} 
catch(int e){ 
    assert(e==1); 
} 

但是編譯器仍然給我上述錯誤。這些不是'例外'嗎?他們會不會引發一次投擲?

如果我正確理解try/catch,它會處理運行時錯誤,而不是我上面得到的那種錯誤,對嗎?

在做了一些更多的研究之後,似乎沒有(簡單的)在C++中本地測試某些編譯錯誤的方法(對於大多數語言來說,現在我認爲它可能是這樣)。我讀了post,建議用腳本語言編寫一些測試代碼,嘗試編譯C++代碼片段並檢查是否有任何錯誤,另一個建議使用Boost.Build的post

做什麼我想要做什麼是最簡單/最好的方式?

我看了看Boost.Build的文檔,它有點凌駕於我的頭上。如果我使用它,我將如何測試一個文件,比如'test.cpp'編譯,並且可能處理'test.cpp'發生的特定編譯錯誤?

感謝您的幫助!

P.S.這是我的第一篇文章之一,希望我已經做了「足夠」的研究,並且正確地完成了一切。對不起,如果我沒有。

+0

只要您編譯程序,你會得到一個錯誤列表。這還不夠?!如果你添加一個測試類,那就不能從你的代碼中提取更多的「編譯錯誤」。測試類被寫入(編譯後)運行代碼並提取語義錯誤。 – Shahbaz 2012-03-29 09:25:27

+0

在這種情況下,我只需要進行一些我想測試的操作,但仔細閱讀編譯錯誤並不是什麼大不了的事情。但是當你在一個大項目上工作時,會發生什麼情況,並且有很多您想要防止的操作/行爲,您想要產生編譯錯誤的操作/行爲?手動閱讀並檢查每一個看起來不僅有點乏味。 – 2012-03-29 15:52:59

+0

等待,您不能爲運行時操作/行爲「產生編譯錯誤」。編譯器讀取您的代碼,確保它符合C++語言,從詞彙,語法和語義上都符合C++語言,併爲其生成代碼。它只檢查C++語言指定的內容。如果生成的代碼不起作用,那與編譯器無關(所以它不能給你編譯錯誤) – Shahbaz 2012-03-29 16:07:47

回答

3

這些是編譯器錯誤,不是例外。異常是程序員拋出運行時錯誤並捕獲/處理它們的機制。編譯器甚至無法爲您創建可執行文件,因爲它可以識別代碼格式錯誤並且是無效的C++代碼。

如果你想使這是一個運行時錯誤,使該方法公開/使用朋友/無論你需要做什麼來提供對某些東西的訪問並在方法的定義中拋出一個異常,捕獲並處理異常調用代碼。

但是我沒有看到這樣做的目的。總是比運行時錯誤更喜歡編譯時錯誤。總是。

C++標準定義了什麼是有效或無效的代碼,有些東西還沒有定義,剩下的東西留給誰來實現編譯器。任何符合標準的C++編譯器都會出錯,因爲某些內容不符合標準/定義,因此無效。這些錯誤通常是說某些東西模棱兩可或者直接無意義,你需要修改你寫的東西。

運行時錯誤是崩潰或從用戶的角度來看是不想要的和不需要的行爲。編譯器錯誤是編譯器說:「我不明白你在說什麼,這沒有意義。」編譯器的警告是編譯器說:「我會讓你這樣做,但我可能不應該,你確定這是你的意思嗎?」。

+2

+1:'總是喜歡編譯時錯誤到運行時錯誤' – 2012-03-29 01:04:38

3

try-catch在運行時發生,而編譯器會靜態地嘗試鏈接您在編譯時調用的函數,因此編譯將始終失敗。另外,如果你願意使用C++異常,那麼你可以實現複製和賦值方法,使它們公開,並在這些函數的主體中引發異常。請注意,在基本上每種情況下,如果您有選擇,您應該優先選擇運行時檢查的靜態/編譯時檢查。

+0

感謝Preet,我這樣做,它幫助我更多地理解異常。我現在明白編譯時檢查是更可取的。 – 2012-03-29 01:18:10

0

這種編譯錯誤不能被抑制。他們是來自C++ standarts'觀點的錯誤。

當然,你可以在你自己的(或修補過的)編譯器中抑制它們中的一些。

1

你真正想測試的不是編譯器失敗,而是你想測試關於你的類的某些假設。

在您的測試文件,把#include <type_traits>

然後添加

assert((std::is_assignable <myClass, myClass> ::value) == FALSE); 
assert((std::is_copy_assignable<myClass> ::value) == FALSE); 
assert((std::is_copy_constructible<myClass> ::value) == FALSE); 

您可以檢查這裏有記載的各種性狀: http://en.cppreference.com/w/cpp/types

注意,你必須編譯爲C++ 11使用這些功能的大部分。

(如Assert that code does NOT compile首次描述)

+0

更好的是使用static_assert而不是assert,以便它會觸發編譯錯誤。 – Tomis 2016-08-19 14:42:14