2012-03-29 3 views
3

Я студент, и я пытаюсь написать и запустить некоторый тестовый код для задания, чтобы проверить его, прежде чем включать его. То, что я пытаюсь сделать сейчас, это проверить, что мой код предотвращает правильность семантики. В моем задании я объявил для каждого из моих классов свой собственный частный конструктор копирования и оператор присваивания, которые не имеют определения, и поэтому ничего не делают. Когда они вызываются в моей тестовой программе, я получаю ошибки компиляции, как я ожидал. Что-то вроде этого:C++ тестирование ошибок компиляции

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

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

Есть ли способ использовать TRY/поймать, так что мой тестовый код будет скомпилировать и запустить, но показать мне, что эти ошибки имели место? Я пробовал:

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

но компилятор по-прежнему дает мне выше ошибки. Разве это не «исключения»? Неужели они не вызовут броска?

Если я правильно понимаю/правильно разбираюсь, он обрабатывает ошибки времени выполнения, а не ошибки, которые я получал выше, правильно?

После проведения еще нескольких исследований кажется, что нет (простого) способа тестирования определенных ошибок компиляции изнутри C++ (это, возможно, верно для большинства языков, теперь я думаю об этом). Я прочитал post, который предлагает написать некоторый тестовый код на языке сценариев, который пытается скомпилировать фрагменты кода на C++ и проверяет наличие ошибок, а другой - post, который рекомендует использовать Boost.Build.

Что является самым простым/лучшим способом сделать то, что я пытаюсь сделать?

Я просмотрел документацию для Boost.Build, и это немного над моей головой. Если бы я использовал его, как бы проверить, что файл, скажем, «test.cpp» компилируется и, возможно, обрабатывать определенные ошибки компиляции, которые встречаются с «test.cpp»?

Благодарим за помощь!

P.S. Это одна из моих первых должностей, надеюсь, я сделал «достаточно» исследований и сделал все остальное должным образом. Извините, если я этого не сделал.

+0

Как только вы компилируете программу, вы получите список ошибок. Этого было недостаточно ?! Если вы добавите тестовый класс, который не сможет извлечь больше «компиляции ошибок» из вашего кода. Тестовые классы записываются в (после компиляции), запускают ваш код и извлекают семантические ошибки. – Shahbaz

+0

В этом случае, когда у меня было только несколько операций, которые я хотел протестировать, чтение ошибок компиляции не было действительно большим делом. Но что происходит, когда вы работаете над большим проектом, и есть много операций/действий, которые вы хотите предотвратить, операции/поведение, которые вы хотите произвести с ошибками компиляции? Ручное чтение и проверка на каждый из них кажется более чем утомительным. –

+0

Подождите, вы не можете «произвести ошибку компиляции» для работы/поведения во время выполнения. Компилятор читает ваш код, следит за тем, чтобы он соответствовал языку C++, лексически, грамматически и семантически, и генерировал для него код. Он проверяет только то, что указано языком C++. Если сгенерированный код не работает, это не имеет ничего общего с компилятором (поэтому он не может дать вам ошибки компиляции) – Shahbaz

ответ

3

Это ошибки компилятора, а не исключения. Исключения - это механизм для программистов, которые бросают ошибки во время выполнения и ловят/обрабатывают их. Компилятор не может даже выполнить исполняемый файл для запуска, потому что он распознает, что код неверен и является недопустимым кодом C++.

Если вы хотите сделать это ошибкой во время выполнения, сделайте этот метод общедоступным/используйте друзей/что бы вы ни делали, чтобы обеспечить доступ к чему-либо и выдать исключение в определении метода, уловить и обработать исключение в вызывающий код.

Я не вижу цели в этом. Всегда предпочитайте ошибку времени компиляции во время выполнения. Всегда.

Стандарт C++ определяет, что является допустимым или недействительным кодом, а некоторые оставлены как неопределенные и другие вещи, оставшиеся до тех, кто реализует компилятор. Любой стандартный компилятор C++ даст ошибку, потому что что-то не соответствует стандарту/определению и, следовательно, недействительно. Ошибки обычно говорят, что что-то неоднозначно или прямо бессмысленно, и вам нужно пересмотреть то, что вы написали.

Ошибки во время выполнения - это либо сбои, либо непредвиденные или нежелательные с точки зрения пользователя ошибки. Ошибки компилятора - это компилятор, говорящий: «Я не понимаю, что вы говорите. Это не имеет смысла». Предупреждения компилятора - это компилятор, говорящий: «Я позволю вам сделать это, но я, вероятно, не должен. Вы действительно уверены, что это то, что вы имели в виду?».

+2

+1: 'Всегда предпочитайте ошибку времени компиляции во время выполнения ошибки –

3

try-catch происходит во время выполнения, тогда как компилятор статически пытается связать функции, которые вы вызываете во время компиляции, поэтому компиляция всегда будет терпеть неудачу.

В качестве альтернативы, если вы хотите использовать исключения C++, вы можете просто реализовать методы копирования и присваивания, сделать их общедоступными и просто выбросить исключение в теле этих функций. Обратите внимание, что в каждой ситуации вы должны предпочитать статические/компиляционные проверки по проверкам времени выполнения, если у вас есть выбор.

+0

Спасибо, Preet, я сделал это, и это помогло мне понять исключения немного больше. Теперь я понимаю, что проверки времени компиляции намного предпочтительнее. –

0

Этот тип ошибок компиляции не может быть подавлен. Это ошибки с точки зрения стандартов C++.

Несомненно, вы можете подавить некоторые из них в своем собственном (или исправленном) компиляторе.

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