Code logic error

From Wikipedia, the free encyclopedia

From Wikipedia, the free encyclopedia

In computer programming, a logic error is a bug in a program that causes it to operate incorrectly, but not to terminate abnormally (or crash). A logic error produces unintended or undesired output or other behaviour, although it may not immediately be recognized as such.

Logic errors occur in both compiled and interpreted languages. Unlike a program with a syntax error, a program with a logic error is a valid program in the language, though it does not behave as intended. Often the only clue to the existence of logic errors is the production of wrong solutions, though static analysis may sometimes spot them.

Debugging logic errors[edit]

One of the ways to find this type of error is to put out the program’s variables to a file or on the screen in order to determine the error’s location in code. Although this will not work in all cases, for example when calling the wrong subroutine, it is the easiest way to find the problem if the program uses the incorrect results of a bad mathematical calculation.

Examples[edit]

This example function in C to calculate the average of two numbers contains a logic error. It is missing parentheses in the calculation, so it compiles and runs but does not give the expected answer due to operator precedence (division is evaluated before addition).

float average(float a, float b)
{
    return a + b / 2;  // should be (a + b) / 2
}

See also[edit]

  • Syntax error
  • Off-by-one error
Bug Types

The logic error is the most dangerous and insidious of all software errors.

  • Mike Wolfe

Aug 19, 2021
1 min read

Logic Errors

This is part 7 of a 7-part series comparing different kinds of software bugs.

What is a Logic Error?

A logic error is a piece of code that executes properly but does not behave the way you intended.

Causes of Logic Errors

  • Inexperience
  • Sleep deprivation
  • Distracted programming
  • Texting and coding
  • Developing Under the Influence (of Alcohol, Drugs, or Tryptophan)
  • Ned from Accounting (stop calling me about my expense report, I’m trying to concentrate over here)

Consequences of Logic Errors

Logic errors are the worst kind of errors because they can go unnoticed for so long.

Some logic errors are obvious.  The electrician wires up the lights in your new house.  Everything is to code.  Everything is perfectly safe.  But when you flip the switch in the kitchen, the lights go on in the living room.  That’s a logic error, but it’s one that’s hard to miss.

Some logic errors are not obvious.  They’re like the black mold growing behind the walls of your finished basement because the vapor barrier got installed backwards.  You don’t even know it’s a problem.  Heck, it might not even [cough] be a problem.  I mean [cough], how would you even [cough] know if you have [cough] black mold in your base–[cough]…[hack]…[hack]…[cough]–basement?


Referenced articles

Some Bugs are Better than Others

Not all bugs are created equal. Avoid the expensive ones by making more of the ones that are easy to find and fix.

No Longer SetMike Wolfe

Image by InspiredImages from Pixabay

What Does Logic Error Mean?

A logic error is an error in a program’s source code that
gives way to unanticipated and erroneous behavior. A logic error is classified as a type of runtime
error that can result in a program producing an incorrect output. It can also cause
the program to crash when running.

Logic errors are
not always easy to recognize immediately. This is due to the fact that such
errors, unlike that of syntax errors, are valid when considered in the language,
but do not produce the intended behavior. These can occur in both interpreted
and compiled languages.

A logic error is also known as a logical error.

Techopedia Explains Logic Error

Logic errors cause a program to work
incorrectly. For example, in PHP, when «if ($i=1) {…}» is incorrectly entered instead of «if ($i==1) {….},» the former means
«becomes» while the latter means «is equal to.» The incorrect if statement would always return TRUE as assigning 1 to the variable $i. In the correct version, though, the statement only returns TRUE when
the value of variable $i is equal to 1. The syntax in the incorrect
case is perfectly correct as per the language. So, the code would compile
successfully without producing any syntax errors. However, during runtime of
the code, the resultant output may be wrong, thus showing that a certain logic
error has occurred. Logic errors tend to be hidden in the source code and can
typically be harder to determine and debug, unlike syntax errors that are
recognized at compile time.

  1. 1. Инварианты
  2. 2. Виды исключений
  3. 3. std::logic_error
  4. 4. std::invalid_argument
  5. 5. std::domain_error
  6. 6. std::length_error
  7. 7. std::out_of_range
  8. 8. std::future_error
  9. 9. std::runtime_error
  10. 10. std::range_error
  11. 11. std::overflow_error
  12. 12. std::underflow_error
  13. 13. std::system_error
  14. 14. std::ios_base::failure
  15. 15. std::bad_typeid
  16. 16. std::bad_cast
  17. 17. std::bad_weak_ptr
  18. 18. std::bad_function_call
  19. 19. std::bad_alloc
  20. 20. std::bad_array_new_length
  21. 21. std::bad_exception

Что такое исключение? Это ситуация, которая не предусмотрена стандартным поведением программы. Например, попытка доступа к элементу в классе Vector (который мы разбирали в статье про

классы

), который не существует. То есть происходит выход за пределы вектора. В данном случае можно воспользоваться исключениями, чтобы прервать выполнение программы. Это необходимо потому, что

  • Как правило в таких случаях, автор класса

    Vector

    не знает, как пользователь захочет использовать его класс, а также не знает в какой программе этот класс будет использоваться.
  • Пользователь класса

    Vector

    не может всегда контролировать правильность работы этого класса, поэтому ему нужно сообщить о том, что что-то пошло не так.

Для разрешения таких ситуация в C++ можно использовать технику исключений.


Рассмотрим, как написать вызов исключения в случае попытки доступа к элементу по индексу, который не существует в классе Vector.

double& Vector::operator[](int i)
{
    if (i<0 || size()<=i) throw out_of_range{"Vector::operator[]"};
    return elem[i];
}

Здесь применяется исключение

out_of_range.

Данное исключение определено в заголовочном файле

.

Оператор

throw

передаёт контроль обработчику для исключений типа

out_of_range

в некоторой функции, которая прямо или косвенно вызывает

Vector::operator

. Для того, чтобы обработать исключения необходимо воспользоваться блоком операторов

try catch.

void f(Vector& v)
{
    // ...
    try { // блок обработки функции с исключением
        v[v.size()] = 7; // попытка доступа к элементу за пределами вектора
    }
    catch (out_of_range) { // ловим ошибку out_of_range 
        // ... обработки ошибки out_of_range ...
    }
    // ...
}

Инварианты

Также блоки

try catch

позволяют производить обработку нескольких различных исключений, что вносит инвариантность в работу механизма исключений C++.

Например, класс вектор при создании может получить неправильный размер вектора или не найти свободную память для элементов, которые он будет содержать.

Vector::Vector(int s)
{
    if (s < 0) throw length_error{};
    elem = new double[s];
    sz = s;
}

Данный конструктор может выбросить исключение в двух случаях:

  • Если в качестве аргумента

    size

    будет передано отрицательное значение
  • Если оператор

    new

    не сможет выделить память


length_error

— это стандартный оператор исключений, поскольку библиотека std часто использует данные исключения при своей работе.

Обработка исключений будет выглядеть следующим образом:

void test()
{
    try {
        Vector v(−27);
    }
    catch (std::length_error) {
        // обработка отрицательного размера вектора
    }
    catch (std::bad_alloc) {
        // обработка ошибки выделения памяти
    }
}

Также можно выделить свои собственные исключения.

Виды исключений

Все исключения стандартной библиотеки наследуются от

std::exception.

На данный момент существуют следующие виды исключений:

  • logic_error
  • invalid_argument
  • domain_error
  • length_error
  • out_of_range
  • future_error (C++11)
  • runtime_error
  • range_error
  • overflow_error
  • underflow_error
  • system_error (C++11)
  • ios_base::failure (начиная с C++11)
  • bad_typeid
  • bad_cast
  • bad_weak_ptr (C++11)
  • bad_function_call (C++11)
  • bad_alloc
  • bad_array_new_length (C++11)
  • bad_exception
  • ios_base::failure (до C++11)

std::logic_error

Исключение определено в заголовочном файле

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

Этот класс используется как основа для ошибок, которые могут быть определены только во время выполнения программы.

std::invalid_argument

Исключение определено в заголовочном файле

Наследован от std::logic_error. Определяет исключение, которое должно быть брошено в случае неправильного аргумента.

Например, на MSDN приведён пример, когда в объект класса bitset из стандартной библиотеки

// invalid_arg.cpp  
// compile with: /EHsc /GR  
#include <bitset>  
#include <iostream>  

using namespace std;  

int main( )  
{  
   try   
   {  
      bitset< 32 > bitset( string( "11001010101100001b100101010110000") );  
   }  
   catch ( exception &e )   
   {  
      cerr << "Caught " << e.what( ) << endl;  
      cerr << "Type " << typeid( e ).name( ) << endl;  
   };  
}  
* Output:   
Caught invalid bitset<N> char  
Type class std::invalid_argument  
* 

В данном примере передаётся неправильная строка, внутри которой имеется символ ‘b’, который будет ошибочным.

std::domain_error

Исключение определено в заголовочном файле

Наследован от std::logic_error. Определяет исключение, которое должно быть брошено в случае если математическая функция не определена для того аргумента, который ей передаётся, например:

std::sqrt(-1)

std::length_error

Исключение определено в заголовочном файле

Наследован от std::logic_error. Определяет исключение, которое должно быть броше в том случае, когда осуществляется попытка реализации превышения допустим пределов для объекта. Как это было показано для размера вектора в начале статьи.

std::out_of_range

Исключение определено в заголовочном файле

Наследован от std::logic_error. Определяет исключение, которое должно быть брошено в том случае, когда происходит выход за пределы допустимого диапазона значений объекта. Как это было показано для диапазона значений ветора в начале статьи.

std::future_error

Исключение определено в заголовочном файле

Наследован от std::logic_error. Данное исключение может быть выброшено в том случае, если не удалось выполнить функцию, которая работает в асинхронном режиме и зависит от библиотеки потоков. Это исключение несет код ошибки совместимый с

std::error_code

.

std::runtime_error

Исключение определено в заголовочном файле

Является базовым исключением для исключений, которые не могут быть легко предсказаны и должны быть брошены во время выполнения программы.

std::range_error

Исключение определено в заголовочном файле

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

underflow_error

или

overflow_error

.

std::overflow_error

Исключение определено в заголовочном файле

Исключение используется при ошибках при вычислении значений с плавающей запятой интегрального типа, когда число имеет слишком большое положительное значение, положительную бесконечность, при которой происходит потеря точности, т.е. результат настолько большой, что не может быть представлен числом в формате IEEE754.

std::underflow_error

Исключение определено в заголовочном файле

Исключение используется при ошибках при вычислении значений с плавающей запятой интегрального типа, при которой происходит потеря точности, т.е. результат настолько мал, что не может быть представлен числом в формате IEEE754.

std::system_error

Исключение определено в заголовочном файле


std::system_error

— это тип исключения, которое вызывается различными функциями стандартной библиотеки (как правило, функции, которые взаимодействуют с операционной системой, например, конструктор

std::thread

), при этом исключение имеет соответствующий

std::error_code

.

std::ios_base::failure

Исключение определено в заголовочном файле

Отвечает за исключения, которые выбрасываются при ошибках функций ввода вывода.

std::bad_typeid

Исключение определено в заголовочном файле

Исключение этого типа возникает, когда оператор

typeid

применяется к нулевому указателю полиморфного типа.

#include <iostream>
#include <typeinfo>

struct S { // Тип должен быть полиморфным
    virtual void f();
}; 

int main()
{
    S* p = nullptr;
    try {
        std::cout << typeid(*p).name() << 'n';
    } catch(const std::bad_typeid& e) {
        std::cout << e.what() << 'n';
    }
}

std::bad_cast

Исключение определено в заголовочном файле

Данное исключение возникает в том случае, когда производится попытка каста объекта в тот тип объекта, который не входит с ним отношения наследования.

#include <iostream>
#include <typeinfo>

struct Foo { virtual ~Foo() {} };
struct Bar { virtual ~Bar() {} };

int main()
{
    Bar b;
    try {
        Foo& f = dynamic_cast<Foo&>(b);
    } catch(const std::bad_cast& e)
    {
        std::cout << e.what() << 'n';
    }
}

std::bad_weak_ptr

Исключение определено в заголовочном файле


std::bad_weak_ptr

– тип объекта, генерируемый в качестве исключения конструкторами

std::shared_ptr

, которые принимают

std::weak_ptr

в качестве аргумента, когда

std::weak_ptr

ссылается на уже удаленный объект.

#include <memory>
#include <iostream>
int main()
{
    std::shared_ptr<int> p1(new int(42));
    std::weak_ptr<int> wp(p1);
    p1.reset();
    try {
        std::shared_ptr<int> p2(wp);
    } catch(const std::bad_weak_ptr& e) {
        std::cout << e.what() << 'n';
    }
}

std::bad_function_call

Исключение определено в заголовочном файле

Данное исключение генерируется в том случае, если был вызван метод

std::function::operator()

объекта

std::function

, который не получил объекта функции, то есть ему был передан в качестве инициализатора nullptr, например, а объект функции так и не был передан.

#include <iostream>
#include <functional>

int main()
{
    std::function<int()> f = nullptr;
    try {
        f();
    } catch(const std::bad_function_call& e) {
        std::cout << e.what() << 'n';
    }
}

std::bad_alloc

Исключение определено в заголовочном файле

Вызывается в том случае, когда не удаётся выделить память.

std::bad_array_new_length

Исключение определено в заголовочном файле

Исключение вызывается в следующих случаях:

  1. Массив имеет отрицательный размер
  2. Общий размер нового массива превысил максимальное значение, определяемое реализацией
  3. Количество элементов инициализации превышает предлагаемое количество инициализирующих элементов
#include <iostream>
#include <new>
#include <climits>

int main()
{
    int negative = -1;
    int small = 1;
    int large = INT_MAX;
    try {
        new int[negative];           // negative size
        new int[small]{1,2,3};       // too many initializers
        new int[large][1000000];     // too large
    } catch(const std::bad_array_new_length &e) {
        std::cout << e.what() << 'n';
    }
}

std::bad_exception

Исключение определено в заголовочном файле


std::bad_exception

— это тип исключения в C++, которое выполняется в следующих ситуациях:

  1. Если нарушается динамическая спецификация исключений
  2. Если

    std::exception_ptr

    хранит копию пойманного исключения, и если конструктор копирования объекта исключения поймал current_exception, тогда генерируется исключение захваченных исключений.
#include <iostream>
#include <exception>
#include <stdexcept>

void my_unexp() { throw; }

void test() throw(std::bad_exception)
{
    throw std::runtime_error("test");
}

int main()
{
    std::set_unexpected(my_unexp);
    try {
         test();
    } catch(const std::bad_exception& e)
    {
        std::cerr << "Caught " << e.what() << 'n';
    }
}

A logic error always does the following

  1. It allows the program to run (or at least to start).
  2. It leads to unexpected results . The program might seem to work fine 99% of the time, but during that other 1% of the time, something weird occurs.

Example of a Logic Error in Penjee:

Example of a Logic Error

Example of a Logic Error

As you can see from the above animation, we wrote code, and

  1. the program did actually start up
  2. our code lead to unexpected results (because our code’s logic was wrong. We turned the  wrong way!)

Now, in many ways, the above example is not representative of many logic errors in production code. This example is so easy to identify .  This, of course, is because Penjee is a visual tool for teaching kids Python , so let’s continue exploring logic errors in the larger world of programming.

Typical Traits of Logic Errors

Below is a list of other stuff that’s usually true about logic errors.

  • They’re harder to detect than syntax errors . If  you make a syntax error  in Python by forgetting a colon or messing up an indent, you’ll learn that real quick!
  • They arise from special cases in a program, a specific case that you didn’t think about.
  • They might crash the program, or might not.    A program with a logic error will always ,at least, start correctly, and the logic error might or might not cause the program to crash.

Second Example of a Penjee Logic Error

The following example is more representative of the trickiness frequently involved in identifying a logic error.

Our penguin, Pam, wants to collect all of the fish. By all appearances, seems to do exactly that!  Here’s a still shot of the final state of this program:

final-state-logic-error

Looks pretty good, right ! Our goal has been achieved right? Pam grab() ‘ed all of the fish, none are visible, right? So, what’s the problem?

Well, the thing is, she actually did not grab() the final fish, the one that she is sitting on in that still shot. One thing all programmers must get used to is–examining the logger to get used to identify logic errors:

If you still can’t find the logic error in this particular case, that’s ok, because we always let you check your answers if you’re stumped .

A Logic error is just one of the two types of errors in computer programming, and here at Penjee, we want to teach kids more than just Python, we want to teach you how to think like a programmer so, read up on these other types of errors or, even better, start learning to program now .

No matter your skill level or experience, anyone that writes and deals with computer code will experience coding errors, from time to time.

Coding errors could take the form of typos, flawed logic, or an accidental oversight. And how they manifest and impact the program determines which type of error they are.

So, here’s a refresher course of the main types of coding errors.


Syntax error

A syntax error is akin to a spelling error, grammar error or basic typo. It’s where the code has been typed incorrectly.

Humans can (and do) communicate without perfect grammar, punctuation and spelling. We can work out what the other person meant and ignore these niggly little mistakes. Computers (for the most part) cannot ignore mistakes as we can. They can’t tell what is or isn’t supposed to be there. As such, syntax errors trip them up. 

Missing semicolons, extra brackets, misspelt instructions, and misplaced capitals are all examples of a syntax coding error.

Syntax errors are among the easiest to find and fix. This is because your compiler will often give you the location of the error.


Runtime error

Runtime errors (also known as execution errors) are coding errors that show themselves when you or a user tries to run your program. Essentially, a runtime coding error is when something has confused the computer and caused it to crash.

For example, your instructions could be in the wrong order, relying on a step that hasn’t happened yet. Or, you might have asked the computer to do something impossible. (A common example here is asking a computer to divide by zero.) Another reason a runtime error could happen is if the user has interacted with a program in an unforeseen way.

Run-time errors are a type of error that can impact your users, preventing them from achieving what they want from your software. You find them by encountering them, so making sure you test thoroughly. A good technical support/bug report system always helps, too.


Logic error

The hardest type of coding error to locate and fix is the logic error. With logic errors, there are no crashes or helpful highlighting to point out the problem. Instead, the program runs successfully. But it doesn’t do what you wanted it to do.

Programs with a logic error don’t behave as desired because you’ve programmed it to do the wrong thing. For this reason, logic errors make everything look like it’s working, because it is. It’s written in a viable language and is an executable program.

This means that you’ll notice there’s a logic error based on the behaviour of the program, and the output it generates. Fixing a logic error can mean tweaking your code or rewriting several lines of it.


Types of coding errors

There are other categories of coding error if you look for them, but these are the main three.

Every developer, young, old, new, experienced, will encounter coding errors — and make them, too. It’s part and parcel of the job. But the more code you write, the better you get at spotting them and fixing them.

Nobody is perfect. That’s why we have debugging practices.


Useful links

The myth of the clean code base

What is technical debt and what should you do about it?

The positives of negative code

Понравилась статья? Поделить с друзьями:
  • Code fddn532 pes 2017 как исправить на русском
  • Code error хонда аккорд 8
  • Code error андертейл
  • Code error komatsu
  • Code error e honda cr v что делать