C-Faq How I program C - Eskil Steenberg
Harder,Better, Faster, Stronger code Crafting interpreters Linux Container in 500 lines Simple memory alocator Learning C projects ideas Gustedt blog
https://freecomputerbooks.com/ C in depth
You can have a scope without anything to isolate variables from their outer scope.
int main() { int i = 2; printf("%d", i); { int i = 4; printf("%d", i) } printf("%d", i); } // 242\0
C language has the concept of variable scope. Ina a nutshell, each pair of { and } introduce new scope, and variables are bound to those scopes. You can declare variables with the same name, as long they are in different scopes.
Redeclaring variables in C - Stack Oveflow
Specifier | Storage | Initial Value | Scope | Life |
---|---|---|---|---|
auto | Stack | Garbage | In block | End of block |
extern | Data Segment | Zero | Global | Program life |
static | Data segment | Zero | In block | Program life |
register | CPU Register? | Garbage | In block | End of block |
Use of extern to share variables between source files - Stack Overflow How to correctly use the extern keyword in C - Stack Overflow
Extern keyword can be used inside a function. It informs the compiler the variable is not in the same file. We usually declare extern variables in the .h so we don't need to use that keyword.
/* main.c
** gcc main.c 2.c -o extern
*/
int main() { extern int a; a = 5; f();}
// 2.c
int a; f() { printf("%d", a); }
Since functions are visible throughout the program by default, the use of extern is not needed in function declarations or definitions. Its use is implicit. When extern is used with a variable, it's only declared, not defined.
When extern is used with a variable, it’s only declared, not defined. As an exception, when an extern variable is declared with initialization, it is taken as the definition of the variable as well.
Variables in function scope are implicitly declared as automatic (auto).
static inline int pow(int n) { return n * n; }
Don't confuse static used in function scope with static used in the global scope. It means the variable can only be accessed from that file.
In all modern OSes (Windows, Linux, BSD, etc), all addresses in a userspace application are virtual addresses. The exceptions to this are certain RTOSes or other custom bare-metal applications.
Do pointers refer to physical or virtual memories
Ld is responsible for making the segments mapping and setting rwx permissions.
Segment | Description |
---|---|
Text | Executable instructions |
Data | Global and static variables with predefined values |
BSS | Undefined global and static |
Stack | LIFO. Converges to Heap. |
Heap | Dynamically alocated variables. Converges to Stack |
char *a = "ABCD"; // .rodata (modifying causes SIGSEGV)
char b[] = "ABCD"; // Data
int c; // BSS
int main() {
static int d; // BSS
char *d = "ABCD"; // .rodata (modifying causes SIGSEGV)
char e[] = "ABCD"; // Stack
char *f = strdup("ABCD"); // Heap
// <- code instructions in Text
Some compilers also use a data segment called .rodata as in read-only data to store string literals and sometimes const.
(gdb) info proc
process 8596
cmdline = '/home/guy/blog/string_elf/a.out'
cwd = '/home/guy/blog/string_elf'
exe = '/home/guy/blog/string_elf/a.out'
(gdb) shell cat /proc/8596/maps
00400000-00401000 r-xp 00000000 fd:02 134817229 ...
00600000-00601000 r--p 00000000 fd:02 134817229 ...
00601000-00602000 rw-p 00001000 fd:02 134817229 ...
[From Rodata to RwData - https://guyonbits.com/from-rodata-to-rwdata-introduction-to-memory-mapping-and-ld-scripts/]
Without adres randomization (ASLR), the variable address is exactly the same as the one found in the symbol table.
$ gcc code.c -no-pie -o executable
$ objdump --syms executable | grep variable
0804a020 g O .bss 00000004 variable
printf("%p", &variable); // 0x804a020
-z execstack marks the object as requiring executable stack.
-fstack-protector allocates a little more space on the stack and adds a stack guard (canary) to protect against buffer overflows.
#define FORTYTWO 42
int main() { int i = FORTYTWO; } // gcc -E fortytwo.c
[Can gcc output code after preprocessing? - Stack Overflow]
We need to protect macro with parenthesis otherwise we can get non-desired results such as :
#define ABS(x) x<0?-x:x // e.g. abs(2-3) translates to 2-3<0-2-3:2-3 -> -5
It is also better practice macros with* *do {...} while (0)**:
#define DEBUG(fmt, ...) do { fprintf(stderr, fmt) } while(0)
#### Offset Macro
#define offsetof(st, m) \
((size_t)&(((st *)0)->m))
#ifdef DEBUG
# define DBG(x) do { (X) } while(0);
# else
# define DBG(X)
# endif
printf("%d", sizeof('A')); // 4
What every programmer needs to know about floats - Oracle
Plain array decays to a pointer to its first element, it's equal to &array[0].
Why are arrays and array pointing to the same address?
int array[] = {1, 2, 3, 4, 5 }; // 1, 2, 3, 4, 5
int array2[5] = {1, 2}; // 1, 2, 0, 0, 0
int array3[5] = {1, }; // 1, 0, 0, 0, 0
int array4[5] = { [0 ... 1] = 1, [2 ... 3] = 2 }; // 1, 1, 2, 2, 0
int array5[] = { [0 ... 2] = 1, [2 ... 3] = 3, [ 1 ... 4 ] = 5 }; // 1, 5, 5, 5, 5
int array6[] = { [4] = 1, [1 ... 2] = 1, [2 ... 3] = 2, [1] = 8, [1] = 9 }; // 0, 9, 2, 1
int main()
{
int array[4] = {1, 2, 3, 4};
printf("%d", (array + 4)[-4]); // prints '1'
}
char *s_array[] = "ABC"; // equivalent to char s_array = {'A', 'B', 'C', '\0'}. On stack if automatic variable.
char *str = "ABC"; // .rodata if compiled with gcc (read-only memory)
String Literals. Where do they go? - StackOverflow
VAL were introduced in C99 standard.
scanf( "%d", &numElements);
if(numElements <= 0) return ;
double data[numElements];
The memory occupied by a union will be large enough to hold the largest member of the union.
typedef union {
int i;
struct {
char b1; // LSB
char b2;
char b3;
char b4; // MSB
};
} u_integer;
int main() {
u_integer integer;
integer.i = 0xFF;
printf("%d\n", integer.i); // 255 == 0xFF
integer.b2 = 0xFF;
printf("%d\n", integer.i); // 65535 == 0x0000FFFF
return (0);
}
How Variable arguments list work in C
void f(int *restrict a, int *restrict b) {
*a += *b;
*b += *a;
}
// ...
int a = 2;
f(&a, &a); // returns 6
gcc -O3 restrict.c -o restrict
[https://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html](Desmitifying the restrict keyword)
Branchless programming examples
https://stackoverflow.com/questions/2486386/why-do-i-see-throw-in-a-c-library assert.h source code from glibc
Fortify source 1 and 2 - StackOverflow
Anybody who writes #pragma pack(1)...
if (1, 2, a = b) printf("Wow?");
(The Comma Operator - Wikipedia)[https://en.wikipedia.org/wiki/Comma_operator]
When to open file in binary mode
Use 'b' mode, to read/write binary data as is without any transformations such as converting newlines to/from platform-specific values or decoding/encoding text using a character encoding.
https://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
Compression algorithms - Michael Dipperstein's Page O'Stuff
Strict aliasing rule https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
How to continue execution after a SIGSEGV https://stackoverflow.com/questions/3291382/coming-back-to-life-after-segmentation-violation
Unit testing, Unit testing macros