Deep C.

In this thread I will post interesting features and usages (of mostly the C programming language), that might not be known to a novice programmer. I might figure out how to display code nicely, at some other time. 


typedef (declare) a struct name before defining said struct:

typedef struct myStruct myStruct;

struct myStruct {
    myStruct* next
    ...
}; 


You can also typedef (declare) a pointer to a struct without defining the struct to achieve type safety (the pointer cannot point to a struct with a different type), and encapsulation (because it doesn't have access to the definition of said struct).


Constant on the left!

 if(NULL == x){...} is better than if(x == NULL){...} because then you don't get if(x = NULL){...} by mistake



Declare type once:

struct T *p;
p = malloc(sizeof *p);


instead of:

struct T *p;
p = malloc(sizeof (struct T));

Similarly sizeof array = (sizeof (ary) / sizeof (ary[0]))



Single item in list or not in any list?

If element is not in a list, element.next == NULL
If element is only element in list, element.next == element 

But how do we know which list the element is in? Use a pointer?
How can we iterate over a list if the apply function calls a destructor? 

Elements will have null previous and next if not in any list. Lists are circular ie last element points to first element. 

You need to wrap macros in do{…}while(0) or they might behave unexpectedly:

See here

 

It would be nice if I could do the following:

int main (void){
    int i = 0;
    do {
        printf ("A\n");
        i++;
    } while (i < 8){
        printf ("B\n");
    };

}


Round up to the nearest multiple of 16:

int stacksize = (16*1024+sizeof (*t)+nbytes+15)&~15;



void foo();

void foo(void); // Not the same!

Leaving void out of the prototype indicates to the compiler that there is no additional information about the

parameters to the function. It effectively turns off all that type checking.

With a prototype definitely use void when you have an empty parameter list.



My assert function could do with a cleanup:

#define ASSERT(c, m) \

do { \

if (!(c)) { \

fprintf(stderr, __FILE__ ":%d: assertion %s failed: %s\n", \

__LINE__, #c, m); \

exit(1); \

} \

} while(0)



BbPool_handle should be a bit field, the following is an example of a bit field:

struct foo {

4 unsigned int a:5;

5 unsigned int b:5;

6 unsigned int c:3;

7 unsigned int d:3;

8 };

 

SIGABRT Abnormal termination—what happens when abort() is called.

SIGFPE Floating point exception.

SIGILL Illegal instruction.

SIGINT Interrupt—usually the result of CTRL-C being hit.

SIGSEGV “Segmentation Violation”: invalid memory access.

SIGTERM Termination requested.q


Here's a funny thing you can do in Python:

aList = [function(number) for number in numbers if condition(number)]


Functions return flags of enum bbFlag. Flags have names like Success, None, Full.

It might be wise to rename them bbSuccess, bbNone, bbFull.

Comments

Popular posts from this blog

Maths Game.

Diablo II Hell Bovine Figurines

Artificial Sweeteners.