From 82ba818ff456bcd6d56a06226e3f27e98fbb55c3 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Thu, 14 Aug 2025 22:58:58 -0500 Subject: removing all downloaded devdocs files --- devdocs/c/language%2Fbehavior.html | 166 ------------------------------------- 1 file changed, 166 deletions(-) delete mode 100644 devdocs/c/language%2Fbehavior.html (limited to 'devdocs/c/language%2Fbehavior.html') diff --git a/devdocs/c/language%2Fbehavior.html b/devdocs/c/language%2Fbehavior.html deleted file mode 100644 index 0a883ffc..00000000 --- a/devdocs/c/language%2Fbehavior.html +++ /dev/null @@ -1,166 +0,0 @@ -

Undefined behavior

The C language standard precisely specifies the observable behavior of C language programs, except for the ones in the following categories:

-

(Note: Strictly conforming programs do not depend on any unspecified, undefined, or implementation-defined behavior)

-

The compilers are required to issue diagnostic messages (either errors or warnings) for any programs that violates any C syntax rule or semantic constraint, even if its behavior is specified as undefined or implementation-defined or if the compiler provides a language extension that allows it to accept such program. Diagnostics for undefined behavior are not otherwise required.

-

UB and optimization

Because correct C programs are free of undefined behavior, compilers may produce unexpected results when a program that actually has UB is compiled with optimization enabled:

-

For example,

-

Signed overflow

int foo(int x)
-{
-    return x + 1 > x; // either true or UB due to signed overflow
-}

may be compiled as (demo)

-
foo:
-        mov     eax, 1
-        ret

Access out of bounds

int table[4] = {0};
-int exists_in_table(int v)
-{
-    // return 1 in one of the first 4 iterations or UB due to out-of-bounds access
-    for (int i = 0; i <= 4; i++)
-        if (table[i] == v)
-            return 1;
-    return 0;
-}

May be compiled as (demo)

-
exists_in_table:
-        mov     eax, 1
-        ret

Uninitialized scalar

_Bool p; // uninitialized local variable
-if (p) // UB access to uninitialized scalar
-    puts("p is true");
-if (!p) // UB access to uninitialized scalar
-    puts("p is false");

May produce the following output (observed with an older version of gcc):

-
p is true
-p is false
size_t f(int x)
-{
-    size_t a;
-    if (x) // either x nonzero or UB
-        a = 42;
-    return a;
-}

May be compiled as (demo)

-
f:
-        mov     eax, 42
-        ret

Invalid scalar

int f(void)
-{
-    _Bool b = 0;
-    unsigned char* p = (unsigned char*)&b;
-    *p = 10;
-    // reading from b is now UB
-    return b == 0;
-}

May be compiled as (demo)

-
f:
-        mov     eax, 11
-        ret

Null pointer dereference

int foo(int* p)
-{
-    int x = *p;
-    if (!p)
-        return x; // Either UB above or this branch is never taken
-    else
-        return 0;
-}
- 
-int bar()
-{
-    int* p = NULL;
-    return *p;    // Unconditional UB
-}

may be compiled as (demo)

-
foo:
-        xor     eax, eax
-        ret
-bar:
-        ret

Access to pointer passed to realloc -

-

Choose clang to observe the output shown

-
#include <stdio.h>
-#include <stdlib.h>
- 
-int main(void)
-{
-    int *p = (int*)malloc(sizeof(int));
-    int *q = (int*)realloc(p, sizeof(int));
-    *p = 1; // UB access to a pointer that was passed to realloc
-    *q = 2;
-    if (p == q) // UB access to a pointer that was passed to realloc
-        printf("%d%d\n", *p, *q);
-}

Possible output:

-
12

Infinite loop without side-effects

-

Choose clang to observe the output shown

-
#include <stdio.h>
- 
-int fermat()
-{
-    const int MAX = 1000;
-    // Endless loop with no side effects is UB
-    for (int a = 1, b = 1, c = 1; 1;)
-    {
-        if (((a * a * a) == ((b * b * b) + (c * c * c))))
-            return 1;
-        ++a;
-        if (a > MAX)
-        {
-            a = 1;
-            ++b;
-        }
-        if (b > MAX)
-        {
-            b = 1;
-            ++c;
-        }
-        if (c > MAX)
-            c = 1;
-    }
-    return 0;
-}
- 
-int main(void)
-{
-    if (fermat())
-        puts("Fermat's Last Theorem has been disproved.");
-    else
-        puts("Fermat's Last Theorem has not been disproved.");
-}

Possible output:

-
Fermat's Last Theorem has been disproved.

References

- - - - - - - -
1. -What Every C Programmer Should Know About Undefined Behavior #1/3
2. -What Every C Programmer Should Know About Undefined Behavior #2/3
3. -What Every C Programmer Should Know About Undefined Behavior #3/3
4. -Undefined behavior can result in time travel (among other things, but time travel is the funkiest)
5. -Understanding Integer Overflow in C/C++
6. -Undefined Behavior and Fermat’s Last Theorem
7. -Fun with NULL pointers, part 1 (local exploit in Linux 2.6.30 caused by UB due to null pointer dereference)

See also

-
C++ documentation for Undefined behavior
-

- © cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
- https://en.cppreference.com/w/c/language/behavior -

-
-- cgit v1.2.3