-
Notifications
You must be signed in to change notification settings - Fork 0
L22 [Misc Topics]
There is a goto
in C but it isn't recommended for many reasons
- Optimization
- Performance
- Clarity
Plus it will only jump within a single function. Even worse, there is a library that lets you jump anywhere
#include <setjmp.h>
jmp_buf x; //Hold location x
t = setjmp(x); //Mark a location as x, t will be 0 for normal control flow, non-zero if coming back from longjmp()
longjmp(x, 3); //Transfer back to location x, and setjmp will have return value 3
A call to setjmp()
saves various information about the calling environment (typically, the stack pointer, the program counter, possibly the values of other registers and the signal mask) in the jmp_buf and returns 0
longjmp()
must be called later in the function OR in a function that’s called by the function that did the setjmp(). In other words, the stack frame of the function that called setjmp() must still be on the stack (somewhere) when longjmp() is called.
longjmp()
restores the saved CPU state from jmp_buf while setting the return value to the value in its second argument
- This makes it appear as if setjmp() returns for a SECOND time without being called again, distinguished only by its return value!
How do we get printf()
to have all these different types of arguments and parameters?
printf("Count %d, average %f\n", ct, avg);
printf("%d %d %d %d\n", a[0], a[3], a[2], a[1]);
Welcome stdarg.h
#include <stdarg.h>
void printargs(int arg1, ...);
int main(void) {
printargs(5, 2, 14, 84, 97, 15, -1, 48, -1;(
printargs(84, 51, -1;(
printargs(-1;(
printargs(1, -1;(
return 0;
}
void printargs(int arg1(... ,
{
va_list ap;
int i;
va_start(ap, arg1 ;(
for (i = arg1; i >= 0; i = va_arg(ap, int((
printf("%d ", i;(
va_end(ap;(
putchar('\n;('
}
And the result...
$ ./a.out
5 2 14 84 97 15
84 51
1
int main(void)
{
printargs(5, 2, 14, 84, 97 ,
;(1- ,48 ,1- ,15
printargs(84, 51, -1;(
printargs(-1;(
printargs(1, -1;(
return 0;
}
- 0 means okay
- Anything else means a problem
- Any function can exit with
exit(99)
a set whatever return value - You can check this value on the command line with
echo $?
Default Streams
- stdin – Standard input
- stdout – Standard output – printf(...) defaults to stdout
- stderr – Standard error output – use fprintf(stderr, ...)
FILE *infile;
if((infile = fopen(“f.txt”,”r”)) == NULL){
// Handle error
}
For stdout the output is line-buffered if it’s written to a terminal and block-buffered if it’s written to to a disk file
- BufferOutput not flushed if your program crashes
printf(“Checkpoint 1”);
fflush(stdout);
However, for stderr, the output is not buffered, so output will always cause immediate I/O
fprintf(stderr, “Checkpoint 1”);
The reason output is buffered by default is to reduce the number of I/O traps the operating system has to process
You can have inline functions that are essentially text-substituted into where you call them from
inline int myfunc(int a, int b) {
return a + b;
}
You can use the -O
flag to control optimization
- 0 is don't move code around (default)
- 1 is quick optimizations that don't take much compile time
- 2 is all optimizations that don't involve speed/space tradeoff
- 3 is max optimization
Don't write tricky code designed to be very efficient
- Until they’ve measured it, programmers rarely know where the CPU is spending its time in their code; this is called premature optimization
Profiling is program means instrumenting and measuring a running program to discover where the CPUs spend their time in order to find the most effective places to optimize the code