Skip to content
Snippets Groups Projects
Commit 83fcdcf8 authored by Mactavish's avatar Mactavish
Browse files

update

parent df2aa1ce
No related branches found
No related tags found
No related merge requests found
......@@ -34,7 +34,7 @@ Example:
## Specific Sized Numbers
C only guarantees minimum and relative size of "int", "short" etc...
C only guarantees minimum and relative size of "int", "short" etc... The range that each type can represent depends on the implementation.
The integer data types range in size from at least 8 bits to at least 32 bits. The C99 standard extends this range to include integer sizes of at least 64 bits.
......@@ -51,3 +51,144 @@ For example:
- `int64_t` is an signed 64-bit integer
All theses types are defined in the header file `stdint.h` instead of in the language itself.
## Undefined Behaviours
The C language standard precisely specifies the observable behavior of C language programs, except for:
- Undefined behaviours
- Unspecific behaviours
- Implementation-defined behaviours
- Locale-specific behaviours
More information about these can be found [here](https://en.cppreference.com/w/c/language/behavior).
We are going to focus on **undefined behaviours** in this section.
### What are Undefined Behaviours
- The language definition says: "We don't know what will happen, nor care of that matter".
- This often means **unpredictable behaviour**.
- Often contributes to bugs that seem random and hard to reproduce.
What we have to do is to pay attention to these possible behaviours and avoid them in the source code.
We will use **UB** and **undefined behaviours** interchangeably in the later sections.
### Frequent Undefined Behaviours
#### Signed Overflow
```c
#include < limits .h >
int foo(int a)
{
int b = INT_MAX + a; // UB, b can be anything
return b;
}
```
#### Division by Zero
```c
#include <stdio.h>
int func() {
int gv;
printf("Enter a integer number: ");
scanf("%d", &gv);
return (23 / func()); // UB
}
```
#### NULL Pointer Dereference
```c
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
}
```
#### Value of a Pointer to Object with Ended Lifetime
```c
int* fun(int x) {
int y = 2;
y = x + y;
return *y; // UB
}
```
#### Use of Indeterminate Value
```c
#include <stdio.h>
int main() {
int a;
int b = a; // UB
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
```
#### String Literal Modification
```c
#include <stdio.h>
int main() {
char *p = "some text here";
p[2] = 'O'; // UB
}
```
#### Access Out Of Bounds
```c
#include <stdio.h>
int main() {
int arr[5] = { 1, 2, 3, 4, 5 };
int b = arr[7]; // UB
printf("b = %d\n", b);
}
```
#### Pointer Used After Freed
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char str[9] = "tutorial";
char ftr[9] = "aftertut";
int bufsize = strlen(str) + 1;
char *buf = (char *)malloc(bufsize);
if (!buf) {
return EXIT_FAILURE;
}
free(buf);
strcpy(buf, ftr); // UB
printf("buf = %s\n", buf);
return EXIT_SUCCESS;
}
```
This list goes on, you can find more information about undefined behaviours in this [thesis](https://solidsands.com/wp-content/uploads/Master_Thesis_Vasileios_GemistosFinal.pdf) and in the [C99 Standard](https://www.dii.uchile.cl/~daespino/files/Iso_C_1999_definition.pdf)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment