C
Memory, pointers, compilation and portable C programs.
45 troubleshooting guides · Page 2 / 2
Why does my MIN macro increment an argument more than once?
A macro substitutes tokens wherever the parameter appears. A conditional minimum macro can evaluate the selected argument again, so passing an increment or function call introduces extra effects.
Why does a scaling macro produce a different result for x+1?
Macro substitution does not automatically group the argument as one expression. Multiplication or bitwise operators can bind to only part of a substituted expression.
Why does including a header indirectly twice redefine its struct?
A header can be reached through several include paths within one translation unit. Without a guard, its declarations and definitions are processed repeatedly.
Why does a global variable defined in a header fail at link time?
Each source file including the header can contribute its own definition, while the program intends one shared object. Header guards operate per translation unit and cannot enforce one program-wide definition.
Why is a function declared successfully but undefined at link time?
A declaration tells the compiler how a function is called; it does not provide executable code. The object file or library containing the definition may be absent from the link.
Why is suppressing an implicit-function-declaration warning unsafe?
Calling a function without the correct visible declaration can produce an incompatible call contract. A cast on its result does not repair the arguments or return convention used by the compiler.
Why does printing size_t with %d produce incorrect output?
Variadic formatting depends on the format specifying the actual argument type. A mismatch is not a safe numeric conversion and can misread the argument.
Why does scanf with %f corrupt a double variable?
Input formatting writes through a pointer, so the pointed-to type must match the conversion. For scanf, `%f` expects float storage while `%lf` expects double storage.
Why does modifying a char pointer initialized from a string literal crash?
A pointer to a string literal does not make that literal writable. Attempting to alter its storage has undefined behavior even when the pointer type was accepted by the compiler.
Why can strlen read past a buffer received from a binary source?
strlen searches for a null terminator, not a supplied buffer boundary. A block of received bytes is not necessarily a C string.
Why can memcmp report unequal C structs with equal fields?
A structure’s object representation can contain padding that is not part of the logical field values. Comparing every byte therefore need not express value equality.
Why is fwrite(struct) not a portable file format?
Writing a structure’s raw bytes captures compiler layout, padding and native representations. Another build can interpret those bytes differently even if its source fields look identical.
Why does casting packet bytes to an integer pointer fail on another CPU?
A byte buffer may lack the alignment and object-access guarantees required by an integer pointer. Even a seemingly aligned address does not establish the packet’s byte order.
Why can an export fail after fwrite appeared to succeed?
Buffered output can defer errors until flushing or closing. Successful writes into the library buffer do not prove that the final file was committed successfully.
Why does assigning malloc to a function parameter leave the caller pointer unchanged?
A pointer parameter is itself passed by value. Assigning a new address to that local parameter changes the callee’s copy, not the caller’s variable.
What is the practical difference between const char * and char * const?
The first form restricts modification through the pointed-to character view; the second makes the pointer variable itself non-reassignable. Confusing them can leave an API’s mutability promise backwards.
Why is a two-dimensional C array incompatible with int **?
A contiguous two-dimensional array is not an array of independently stored row pointers. Treating its first element as an int** imposes a different memory layout.
Why does assigning integer division to double still lose the fraction?
The division is evaluated using its operand types before assignment. Storing the already truncated integer result in double cannot restore the discarded fraction.
Why does a clean AddressSanitizer run not prove my C program is memory-safe?
A sanitizer observes instrumented execution, not every possible input and path. An untested branch or uninstrumented dependency can retain defects after one clean run.
Why can UBSan detect integer errors while missing a memory leak?
UndefinedBehaviorSanitizer checks selected undefined operations; it is not a universal detector for all correctness or resource problems. Expecting one tool to cover unrelated failure classes leaves gaps.
Why should C bit fields not directly model a network header?
Bit-field allocation and ordering depend on implementation rules. A structure that matches a packet on one compiler is not automatically a portable wire-layout declaration.
Ask your own question · Sign in to post questions and answers.