0 / 0 / 1 Регистрация: 04.12.2012 Сообщений: 18 |
|
1 |
|
Игнорирование ошибок при компилировании10.09.2014, 04:18. Показов 9141. Ответов 16
Всем привет. Проблема такая: Есть код с ошибками. Необходимо его так и скомпилировать.
0 |
1449 / 1121 / 346 Регистрация: 11.04.2011 Сообщений: 2,621 |
|
10.09.2014, 05:30 |
2 |
Есть код с ошибками. Необходимо его так и скомпилировать.
0 |
4608 / 2029 / 359 Регистрация: 17.03.2012 Сообщений: 10,086 Записей в блоге: 6 |
|
10.09.2014, 10:44 |
3 |
Может, ему (компилятору) денег дать? Чтобы не кочевряжился.
6 |
Почетный модератор 16842 / 6720 / 880 Регистрация: 12.06.2012 Сообщений: 19,967 |
|
10.09.2014, 11:52 |
4 |
вы попробуйте системнику пистолетом погрозить.. Только надо уверенно, чтобы он поверил и испугался. Тогда он компилятору скажет, что там серьезно все и надо собрать несмотря на ошибки….
2 |
41 / 33 / 24 Регистрация: 09.06.2012 Сообщений: 144 |
|
10.09.2014, 13:11 |
5 |
populois, ну ответ такой — никак.
0 |
kolorotur 17227 / 12679 / 3323 Регистрация: 17.09.2011 Сообщений: 20,950 |
||||
10.09.2014, 13:48 |
6 |
|||
Есть код с ошибками. Необходимо его так и скомпилировать. Встречный вопрос: что должна выполнять программа, скомпилированная из нижеприведенного кода?
1 |
65 / 65 / 16 Регистрация: 07.04.2014 Сообщений: 332 |
|
10.09.2014, 16:02 |
7 |
Спасибо, поржал
0 |
484 / 439 / 123 Регистрация: 05.01.2010 Сообщений: 1,848 |
|
10.09.2014, 16:59 |
8 |
kolorotur, а что тут непонятно-то? написано же — хочу мир захватить. сделай
1 |
307 / 284 / 102 Регистрация: 06.05.2014 Сообщений: 861 |
|
10.09.2014, 17:02 |
9 |
Позвольте, в качестве нездорового любопытства, поинтересоваться — а с каких побуждений энто потребовалось?
0 |
1 / 1 / 1 Регистрация: 22.08.2014 Сообщений: 9 |
|
10.09.2014, 17:23 |
10 |
1. Заходишь в диск с виндой. По теме: каким образом должен комплиятор скомплириовать код с ошибкой?
0 |
65 / 65 / 16 Регистрация: 07.04.2014 Сообщений: 332 |
|
11.09.2014, 09:59 |
11 |
Позвольте, в качестве нездорового любопытства, поинтересоваться — а с каких побуждений энто потребовалось? А что тут непонятного? У человека есть код, но он вот не компилится. Пишет что-то вроде «NullReferenceException». Ну так пусть компилится и работает хоть как то.
0 |
4608 / 2029 / 359 Регистрация: 17.03.2012 Сообщений: 10,086 Записей в блоге: 6 |
|
11.09.2014, 10:13 |
12 |
Пишет что-то вроде «NullReferenceException». Ну так пусть компилится и работает хоть как то. NullReferenceException — это run-time ошибка.
0 |
65 / 65 / 16 Регистрация: 07.04.2014 Сообщений: 332 |
|
11.09.2014, 10:29 |
13 |
NullReferenceException — это run-time ошибка. И не при каких условиях во время компиляции вылететь не может? Даже если и так, то сразу после может.
0 |
4608 / 2029 / 359 Регистрация: 17.03.2012 Сообщений: 10,086 Записей в блоге: 6 |
|
11.09.2014, 10:39 |
14 |
И не при каких условиях во время компиляции вылететь не может? Даже если и так, то сразу после может. Не может. Разве что это будет ошибка в самом компиляторе, но я очень сильно в этом сомневаюсь
0 |
1220 / 1008 / 259 Регистрация: 15.06.2012 Сообщений: 3,904 |
|
11.09.2014, 13:09 |
15 |
Есть код с ошибками. Не проще исправить эти ошибки? Например можно привести этот код сюда, люди скажут, чего не собирается.
0 |
0 / 0 / 1 Регистрация: 04.12.2012 Сообщений: 18 |
|
05.08.2017, 16:16 [ТС] |
16 |
Эту тему действительно я создавал?)
0 |
17227 / 12679 / 3323 Регистрация: 17.09.2011 Сообщений: 20,950 |
|
05.08.2017, 16:29 |
17 |
Эту тему действительно я создавал? Самый простой способ проверить прирост своих знаний и опыта — это открыть старую тему или код и обратить внимание на свою реакцию. Так что мои поздравления!
3 |
- 1. Применение
Исключения выбрасываются во время выполнения программы, если же ошибка может быть найдена во время компиляции программы, то можно использовать
static_assert
, который сообщит о необходимости поправить программный код в ключевых местах.
Использование
static_assert
будет выглядеть следующим образом.
static_assert(4<=sizeof(int), "integers are too small"); // проверка размера integerСинтаксис будет следующим
static_assert(A, B);
где
A
— это условие, при котором будет выбрасываться ошибка в том случае, если
A
равно
false
B
— это текст сообщения об ошибке
Применение
static_assert
может быть полезен при использовании констант и константных выражений, которые вычисляются на этапе компиляции.
В данном коде делается проверка локальной константной скорости, которая не может быть быстрее скорости света.
constexpr double C = 299792.458; // km/s, скорость света void f(double speed) { const double local_max = 160.0/(60∗60); // 160 km/h == 160.0/(60*60) km/s static_assert(speed<C,"can't go that fast"); // error: speed должна быть константой static_assert(local_max<C,"не может двигаться быстрее"); // OK }Также ещё можно использовать данную проверку в ключевых местах для перечислений. Например, дано такое перечисление.
enum Types { E_BEGIN_TYPES, E_A = E_BEGIN_TYPES, E_B, E_C, E_D, E_END_TYPES = E_D };И есть следующий метод или функция в каком-то месте кода
QString getStandardMessage(Types type) { static_assert(E_END_TYPES == 3, "Need to implement method for new type"); switch (type) { case E_A: return "Type A"; case E_B: return "Type B"; case E_C: return "Type C"; case E_D: return "Type D"; default: return "Type is not implemented"; } }В данном случае мы знаем, что самые последние перечисления, то есть E_D или E_END_TYPES будут равны 3. И исключение во время компиляции выброшено не будет. Но как только будет добавлен новый участник данного перечисления.
enum Types { E_BEGIN_TYPES, E_A = E_BEGIN_TYPES, E_B, E_C, E_D, E_E, // Новый участник перечисления E_END_TYPES = E_E };То static_assert выбросит ошибку, которая будет означать, что мы забыли поправить данный метод. Исправление будет выглядеть следующим образом.
QString getStandardMessage(Types type) { static_assert(E_END_TYPES == 4, "Need to implement method for new type"); switch (type) { case E_A: return "Type A"; case E_B: return "Type B"; case E_C: return "Type C"; case E_D: return "Type D"; case E_E: return "Type E"; default: return "Type is not implemented"; } }В данном методе мы добавим реализацию кода для типа E_E, а также поправим сам static_assert, чтобы он учитывал количество участников перечисления с новым участником.
Отладка, или debugging, — это поиск (локализация), анализ и устранение ошибок в программном обеспечении, которые были найдены во время тестирования.
Виды ошибок
Ошибки компиляции
Это простые ошибки, которые в компилируемых языках программирования выявляет компилятор (программа, которая преобразует текст на языке программирования в набор машинных кодов). Если компилятор показывает несколько ошибок, отладку кода начинают с исправления самой первой, так как она может быть причиной других.
В интерпретируемых языках (например Python) текст программы команда за командой переводится в машинный код и сразу исполняется. К моменту обнаружения ошибки часть программы уже может исполниться.
Ошибки компоновки
Ошибки связаны с разрешением внешних ссылок. Выявляет компоновщик (редактор связей) при объединении модулей программы. Простой пример — ситуация, когда требуется обращение к подпрограмме другого модуля, но при компоновке она не найдена. Ошибки также просто найти и устранить.
Ошибки выполнения (RUNTIME Error)
Ошибки, которые обнаруживают операционная система, аппаратные средства или пользователи при выполнении программы. Они считаются непредсказуемыми и проявляются после успешной компиляции и компоновки. Можно выделить четыре вида проявления таких ошибок:
- сообщение об ошибке, которую зафиксировали схемы контроля машинных команд. Это может быть переполнение разрядной сетки (когда старшие разряды результата операции не помещаются в выделенной области памяти), «деление на ноль», нарушение адресации и другие;
- сообщение об ошибке, которую зафиксировала операционная система. Она же, как правило, и документирует ошибку. Это нарушение защиты памяти, отсутствие файла с заданным именем, попытка записи на устройство, защищенное от записи;
- прекращение работы компьютера или зависание. Это и простые ошибки, которые не требуют перезагрузки компьютера, и более сложные, когда нужно выключать ПК;
- получение результатов, которые отличаются от ожидаемых. Программа работает стабильно, но выдает некорректный результат, который пользователь воспринимает за истину.
Ошибки выполнения можно разделить на три большие группы.
Ошибки определения данных или неверное определение исходных данных. Они могут появиться во время выполнения операций ввода-вывода.
К ним относятся:
- ошибки преобразования;
- ошибки данных;
- ошибки перезаписи.
Как правило, использование специальных технических средств для отладки (API-логгеров, логов операционной системы, профилировщиков и пр.) и программирование с защитой от ошибок помогает обнаружить и решить лишь часть из них.
Логические ошибки. Они могут возникать из ошибок, которые были допущены при выборе методов, разработке алгоритмов, определении структуры данных, кодировании модуля.
В эту группу входят:
- ошибки некорректного использования переменных. Сюда относятся неправильный выбор типов данных, использование индексов, выходящих за пределы определения массивов, использование переменных до присвоения переменной начального значения, нарушения соответствия типов данных;
- ошибки вычислений. Это некорректная работа с переменными, неправильное преобразование типов данных в процессе вычислений;
- ошибки взаимодействия модулей или межмодульного интерфейса. Это нарушение типов и последовательности при передаче параметров, области действия локальных и глобальных переменных, несоблюдение единства единиц измерения формальных и фактических параметров;
- неправильная реализация логики при программировании.
Ошибки накопления погрешностей. Могут возникать при неправильном округлении, игнорировании ограничений разрядной сетки, использовании приближенных методов вычислений и т.д.
Методы отладки программного обеспечения
Метод ручного тестирования
Отладка программы заключается в тестировании вручную с помощью тестового набора, при работе с которым была допущена ошибка. Несмотря на эффективность, метод не получится использовать для больших программ или программ со сложными вычислениями. Ручное тестирование применяется как составная часть других методов отладки.
Метод индукции
В основе отладки системы — тщательный анализ проявлений ошибки. Это могут быть сообщения об ошибке или неверные результаты вычислений. Например, если во время выполнения программы завис компьютер, то, чтобы найти фрагмент проявления ошибки, нужно проанализировать последние действия пользователя. На этапе отладки программы строятся гипотезы, каждая из них проверяется. Если гипотеза подтвердилась, информация об ошибке детализируется, если нет — выдвигаются новые.
Вот как выглядит процесс:
Важно, чтобы выдвинутая гипотеза объясняла все проявления ошибки. Если объясняется только их часть, то либо гипотеза неверна, либо ошибок несколько.
Метод дедукции
Сначала специалисты предлагают множество причин, по которым могла возникнуть ошибка. Затем анализируют их, исключают противоречащие имеющимся данным. Если все причины были исключены, проводят дополнительное тестирование. В обратном случае наиболее вероятную причину пытаются доказать.
Метод обратного прослеживания
Эффективен для небольших программ. Начинается с точки вывода неправильного результата. Для точки выдвигается гипотеза о значениях основных переменных, которые могли привести к ошибке. Далее на основании этой гипотезы строятся предположения о значениях переменных в предыдущей точке. Процесс продолжается до момента, пока не найдут ошибку.
Как выполняется отладка в современных IDE
Ранние отладчики, например gdb, представляли собой отдельные программы с интерфейсами командной строки. Более поздние, например первые версии Turbo Debugger, были автономными, но имели собственный графический интерфейс для облегчения работы. Сейчас большинство IDE имеют встроенный отладчик. Он использует такой же интерфейс, как и редактор кода, поэтому можно выполнять отладку в той же среде, которая используется для написания кода.
Отладчик позволяет разработчику контролировать выполнение и проверять (или изменять) состояние программ. Например, можно использовать отладчик для построчного выполнения программы, проверяя по ходу значения переменных. Сравнение фактических и ожидаемых значений переменных или наблюдение за ходом выполнения кода может помочь в отслеживании логических (семантических) ошибок.
Пошаговое выполнение — это набор связанных функций отладчика, позволяющих поэтапно выполнять код.
Шаг с заходом (step into)
Команда выполняет очередную инструкцию, а потом приостанавливает процесс, чтобы с помощью отладчика было можно проверить состояние программы. Если в выполняемом операторе есть вызов функции, step into заставляет программу переходить в начало вызываемой функции, где она приостанавливается.
Шаг с обходом (step over)
Команда также выполняет очередную инструкцию. Однако когда step into будет входить в вызовы функций и выполнять их строка за строкой, step over выполнит всю функцию, не останавливаясь, и вернет управление после ее выполнения. Команда step over позволяет пропустить функции, если разработчик уверен, что они уже исправлены, или не заинтересован в их отладке в данный момент.
Шаг с выходом (step out)
В отличие от step into и step over, step out выполняет не следующую строку кода, а весь оставшийся код функции, исполняемой в настоящее время. После возврата из функции он возвращает управление разработчику. Эта команда полезна, когда специалист случайно вошел в функцию, которую не нужно отлаживать.
Как правило, при пошаговом выполнении можно идти только вперед. Поэтому легко перешагнуть место, которое нужно проверить. Если это произошло, необходимо перезапустить отладку.
У некоторых отладчиков (таких как GDB 7.0, Visual Studio Enterprise Edition 15.5 и более поздних версий) есть возможность вернуться на шаг назад. Это полезно, если пропущена цель либо нужно повторно проверить выполненную инструкцию.
Is this legal in Groovy?
class RequestContext {
def static requestContext
def static setRequestContext(rc) {
requestContext = rc
}
}
Given the above I expect the following to fail at compile time using the groovy-eclipse-compiler:
RequestContext.setRequestContext()
Yet this passes and I’m trying to get this to fail at mvn compile
time.
asked Mar 26, 2020 at 22:28
It can’t fail at compile time, because you might add that method dynamically at runtime via the metaclass, ie:
class Test {
}
Test.metaClass.static.woo = { -> println "yay" }
Test.woo() // prints 'yay'
To fail at compile time, you’d need to annotate the calling class with @CompileStatic
or @TypeChecked
answered Mar 26, 2020 at 22:36
tim_yatestim_yates
166k26 gold badges341 silver badges338 bronze badges
Вопрос:
Извините, если это такой простой вопрос, должно быть что-то, что я не понимаю о наследовании, virtual
и override
в c++. В следующем примере я получаю ошибку времени компиляции относительно виртуального метода, который я специально переопределяю, чтобы избежать такой ошибки в дочернем классе. Я делаю что-то неправильно?
#include <array>
#include <deque>
template <class T, class C>
struct foo
{
virtual const C& data() const =0;
inline virtual T& operator[] ( unsigned n ) const
{ return const_cast<T&>( data()[n] ); }
};
/**
* The implementation of foo::operator[] is useful for classes inheriting
* with simple sequence containers like:
* foo<T,std::deque<T>>, foo<T,std::vector<T>>, ..
*
* But the following requires operator[] to be redefined:
*/
template <class T, unsigned N>
struct baz
: public foo<T, std::deque<std::array<T,N>> >
{
typedef std::deque<std::array<T,N>> data_type;
data_type m_data;
inline const data_type& data() const
{ return m_data; }
inline virtual T& operator[] ( unsigned n ) const override
{ return const_cast<T&>( data()[n/N][n%N] ); }
};
int main()
{
baz<double,3> b; // throws an error relative to foo::operator[] depsite override
}
EDIT 1 Ошибка:
clang++ -std=c++0x -Wall virtual_operator.cpp -o virtual_operator.o
virtual_operator.cpp:11:12: error: const_cast from 'const value_type' (aka 'const std::__1::array<double, 3>') to 'double &' is not allowed
{ return const_cast<T&>( data()[n] ); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~
virtual_operator.cpp:26:8: note: in instantiation of member function 'foo<double, std::__1::deque<std::__1::array<double, 3>, std::__1::allocator<std::__1::array<double, 3> > > >::operator[]'
requested here
struct baz
^
1 error generated.
EDIT 2 Я считаю это частью вопроса; если компиляция завершается с ошибкой, потому что foo::operator[]
по-прежнему может быть вызвана в baz
, то почему она компилируется отлично, если я не объявляю foo::operator[]
как виртуальную (т.е. скрываясь вместо переопределения)?
Лучший ответ:
Проблема в том, что, хотя вы только намереваетесь вызвать функцию производного operator[]
на экземплярах baz
, компилятору все равно необходимо сгенерировать код для базового класса, потому что эта функция по-прежнему может быть вызвана в случаях baz
. В этом случае генерация этого кода приводит к ошибке типа, потому что вы пытаетесь использовать const std::array<double,3>
в double&
.
Чтобы исправить это, вы должны иметь разные части иерархии, которые определяют оператора, который будет работать для всех его детей, например (с удалением непереносимого материала):
template <class T, class C>
struct foo
{
inline virtual T& operator[] ( unsigned n ) const = 0;
};
template <class T>
struct bar
: public foo<T,std::deque<T>>
{
inline virtual T& operator[] ( unsigned n ) const override
{ return const_cast<T&>( data()[n] ); }
};
template <class T, unsigned N>
struct baz
: public foo<T, std::deque<std::array<T,N>> >
{
inline virtual T& operator[] ( unsigned n ) const override
{ return const_cast<T&>( data()[n/N][n%N] ); }
};
Таким образом, если у вас есть какие-либо другие версии, которые вы хотите добавить позже, вы можете получить из бара или база и не обязательно определять оператора для каждого ребенка.