StudyLover
  • Home
  • Study Zone
  • Profiles
  • Typing Tutor
  • B Tree
  • Contact us
  • Sign in
StudyLover Advanced Logical Errors (Bugs that Evade Compilation) 馃悶
Download
  1. C Programming
  2. Unit 1: Foundations of Problem Solving & C Language Basics
Understanding Logical Errors (Bugs) in C 馃悰 : Understanding Object Code in C 馃敩
Unit 1: Foundations of Problem Solving & C Language Basics

Advanced logical errors in C often arise from a misunderstanding of the C standard itself, leading to Undefined Behavior (UB). Undefined Behavior means the C standard places no requirements on the program's output; it might crash, produce strange results, or appear to work correctly, only to fail with a different compiler or optimization level.

1. Signed Integer Overflow

While unsigned integer overflow is well-defined (it wraps around, like a car's odometer), signed integer overflow is undefined behavior.

路聽聽聽聽聽聽聽聽 The Flaw: A programmer might assume that a large positive signed int, when incremented, will wrap around to a negative number. The C standard makes no such guarantee.

路聽聽聽聽聽聽聽聽 The Consequence: Because signed overflow is UB, the compiler is allowed to assume it never happens. This allows for aggressive optimizations that can lead to paradoxical code and security vulnerabilities.

Example

An optimizer might look at the if condition below and reason that x + 100 can never be less than x for any valid signed integer, so it might remove the check entirely.

C

#include <stdio.h>

#include <limits.h>

聽
int main() {

聽聽聽 int x = INT_MAX - 50; // A very large positive number

聽聽聽 

聽聽聽聽// This check is intended to detect potential overflow

聽聽聽 if (x + 100 < x) {

聽聽聽聽聽聽聽 printf("Overflow detected!\n");

聽聽聽 } else {

聽聽聽聽聽聽聽 x = x + 100;

聽聽聽聽聽聽聽 printf("No overflow, result is: %d\n", x);

聽聽聽 }

聽聽聽 // With optimizations, the 'if' block might be removed, and the program

聽聽聽 // might crash or print a wrong value due to the UB in the 'else' block.

聽聽聽 return 0;

}


size=2 width="100%" align=center>

2. Sequence Point Violations

The C standard defines sequence points (such as at a semicolon ; or a comma ,) where all side effects of previous evaluations are complete. Modifying a variable more than once between two sequence points is undefined behavior.

路聽聽聽聽聽聽聽聽 The Flaw: Writing expressions like i = i++; or x = i++ * i++; where the order of operations is ambiguous.

路聽聽聽聽聽聽聽聽 The Consequence: The compiler is free to evaluate the expression in any order. The result can be different on different compilers, or even with different optimization flags on the same compiler.

Example

C

#include <stdio.h>

聽
int main() {

聽聽聽 int i = 5;

聽聽聽 

聽聽聽聽// UNDEFINED BEHAVIOR: 'i' is modified twice without a sequence point.

聽聽聽 // The result is unpredictable. It could be 5, 6, or something else.

聽聽聽 i = i++; 

聽聽聽聽

聽聽聽聽printf("The value of i is: %d\n", i);

聽聽聽 

聽聽聽聽int j = 3;

聽聽聽 // UNDEFINED BEHAVIOR: The order in which the arguments are evaluated

聽聽聽 // is not specified by the C standard.

聽聽聽 printf("j values: %d %d\n", ++j, j); // Could print "4 4", "5 4", etc.

聽
聽聽聽 return 0;

}


size=2 width="100%" align=center>

3. Modifying String Literals

A string literal like "hello" is of type const char[]. While for historical reasons C allows a pointer-to-char (char *) to point to it, attempting to modify the literal's contents is undefined behavior.

路聽聽聽聽聽聽聽聽 The Flaw: A programmer assumes a string literal is a regular, mutable character array.

路聽聽聽聽聽聽聽聽 The Consequence: Most modern compilers place string literals in a read-only segment of memory. Attempting to write to this memory will cause a segmentation fault, crashing the program at runtime.

Example

C

#include <stdio.h>

聽
int main() {

聽聽聽 // This is valid but dangerous. 'str' points to read-only memory.

聽聽聽 char *str = "Hello, World!"; 

聽聽聽聽

聽聽聽聽printf("Original string: %s\n", str);

聽聽聽 

聽聽聽聽// UNDEFINED BEHAVIOR: Attempting to modify read-only memory.

聽聽聽 // This will likely cause a crash.

聽聽聽 str[0] = 'h'; 

聽聽聽聽

聽聽聽聽printf("Modified string: %s\n", str);

聽
聽聽聽 return 0;

}


size=2 width="100%" align=center>

4. Floating-Point Precision and Comparison Errors

Floating-point numbers (float, double) are stored in a binary format (IEEE 754) and cannot precisely represent all decimal fractions. For example, 0.1 is a repeating fraction in binary, similar to how 1/3 is 0.333... in decimal.

路聽聽聽聽聽聽聽聽 The Flaw: Assuming that floating-point math is exact and directly comparing floats for equality using ==.

路聽聽聽聽聽聽聽聽 The Consequence: Small, cumulative rounding errors can cause comparisons to fail unexpectedly.

Example

C

#include <stdio.h>

#include <math.h> // For fabs()

聽
int main() {

聽聽聽 float sum = 0.0f;

聽聽聽 for (int i = 0; i < 10; i++) {

聽聽聽聽聽聽聽 sum += 0.1f;

聽聽聽 }

聽聽聽 

聽聽聽聽// This comparison will likely fail due to precision errors.

聽聽聽 if (sum == 1.0f) {

聽聽聽聽聽聽聽 printf("The sum is exactly 1.0\n");

聽聽聽 } else {

聽聽聽聽聽聽聽 printf("The sum is not exactly 1.0, it is %.10f\n", sum);

聽聽聽 }

聽聽聽 

聽聽聽聽// CORRECT WAY: Check if the difference is within a small tolerance (epsilon).

聽聽聽 const float EPSILON = 0.00001f;

聽聽聽 if (fabs(sum - 1.0f) < EPSILON) {

聽聽聽聽聽聽聽 printf("The sum is close enough to 1.0\n");

聽聽聽 }

聽聽聽 

聽聽聽聽return 0;

}

聽

聽

Object code is the low-level machine code generated by a compiler from your source code. It's an intermediate file that is not yet a complete, runnable program.


Understanding Logical Errors (Bugs) in C 馃悰 Understanding Object Code in C 馃敩
Our Products & Services
  • Home
Connect with us
  • Contact us
  • +91 82955 87844
  • Rk6yadav@gmail.com

StudyLover - About us

The Best knowledge for Best people.

Copyright © StudyLover
Powered by Odoo - Create a free website