Live data from Hacker News

Ask HN: Favorite pointer tricks in C?

news.ycombinator.com

61–70 of 81 posts

Re: Ask HN: Favorite pointer tricks in C?

#61

Instead of using a while loop to iterate through a linked list, consider using a for loop. Node * iter; for (iter=root; iter != NULL; iter=iter->next) { /* iter->object; */ } A concise implementation of strlen size_t strlen(char * str) { char * cur; for(cur=str; *cur; ++cur); return (cur-str); } Reverse a string in-place. void reverse(char * str) { char *i,*j, tmp; for (i=str, j=(str+strlen(str)-1); i

Shouldn't that be --j in your reverse function?

Anyhow, when asked to write those on a blackboard, I typically do this:

  size_t strlen(char* start) {
     char* end=start;
     while(*end) ++end;
     return (end-start);
  }
and

  void reverse(char* i) {
    char* j=(i+strlen(i)-1);
    for (; i 

Re: Ask HN: Favorite pointer tricks in C?

#62

Instead of using a while loop to iterate through a linked list, consider using a for loop. Node * iter; for (iter=root; iter != NULL; iter=iter->next) { /* iter->object; */ } A concise implementation of strlen size_t strlen(char * str) { char * cur; for(cur=str; *cur; ++cur); return (cur-str); } Reverse a string in-place. void reverse(char * str) { char *i,*j, tmp; for (i=str, j=(str+strlen(str)-1); i

Shouldn't that be --j in your reverse function? Anyhow, when asked to write those on a blackboard, I typically do this: size_t strlen(char* start) { char* end=start; while(*end) ++end; return (end-start); } and void reverse(char* i) { char* j=(i+strlen(i)-1); for (; i

Yup, --j.

Also, the XOR version probably isn't worth the complexity.

Re: Ask HN: Favorite pointer tricks in C?

#63
post #13

I like the trick of using the last few bits of aligned pointers to store something useful. It's tricky and has to be done correctly. A class wrapper around the pointer would be better. For e.g., a constraint in an AVL tree requires that the difference in sizes of left and right subtrees be -1, 0 or 1 (just 3 values, which requires 2 bits). A 4-byte aligned pointer would be enough. =)

this is how v8 does tagged pointers.

Re: Ask HN: Favorite pointer tricks in C?

#64

Instead of using a while loop to iterate through a linked list, consider using a for loop. Node * iter; for (iter=root; iter != NULL; iter=iter->next) { /* iter->object; */ } A concise implementation of strlen size_t strlen(char * str) { char * cur; for(cur=str; *cur; ++cur); return (cur-str); } Reverse a string in-place. void reverse(char * str) { char *i,*j, tmp; for (i=str, j=(str+strlen(str)-1); i

void strcpy(char s1, char s2) { while((s1++) = (s2++)); }

Re: Ask HN: Favorite pointer tricks in C?

#65
post #13

I like the trick of using the last few bits of aligned pointers to store something useful. It's tricky and has to be done correctly. A class wrapper around the pointer would be better. For e.g., a constraint in an AVL tree requires that the difference in sizes of left and right subtrees be -1, 0 or 1 (just 3 values, which requires 2 bits). A 4-byte aligned pointer would be enough. =)

This trick is often seen in language interpreters. Two widely used examples are Emacs Lisp and Mozilla Spidermonkey Javascript.

Re: Ask HN: Favorite pointer tricks in C?

#66
post #57
post #25

* Using pointer offsets to get to the stack frame pointer, and then walking the frame pointer backwards to get the call stack. * Using && to take the address of a jump label. * Casting a u_int32_t over a 4-byte string (like an SMTP verb) to get a value you can switch() on.

* Using && to take the address of a jump label. Had to look that one up...turns out it's a GCC trick that allows you store the address of a jump label into a pointer to void. Later on, you can do "goto *ptr" to jump back to that address. Neat. See http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html (You obviously already know this...just putting it here in case anyone else hasn't heard of it and is curious)

Being a gcc extension to the C language, I recommend this construct never be used and certainly not taught.

Re: Ask HN: Favorite pointer tricks in C?

#67
post #36
post #25

* Using pointer offsets to get to the stack frame pointer, and then walking the frame pointer backwards to get the call stack. * Using && to take the address of a jump label. * Casting a u_int32_t over a 4-byte string (like an SMTP verb) to get a value you can switch() on.

> Casting a u_int32_t over a 4-byte string (like an SMTP verb) to get a value you can switch() on. This is awesome beyond words. If I stumbled across this in the wild I would flip flop between awe and disgust until my head exploded. Let me guess, "SMTP verb" is not a hypothetical example?

There are at least three common mistakes involving tricks like this:

1. Alignment. Many CPUs will trap (or worse) if accessing a 32-bit quantity at a non-aligned address.

2. Endianness. Needless to say, the 32-bit value read for a given string depends on the machine endianness.

3. Aliasing. Casting between different pointer types can result in a violation of the C aliasing rules and, with a little bad luck, incorrect results.

Re: Ask HN: Favorite pointer tricks in C?

#68

You may want to show them how you can generate code by emitting assembly hex-codes into a block of memory and then _call_ the block of code after casting it into a function pointer.

Modern hardware and operating systems require special care when doing this. Firstly, the D-cache must be cleaned and the I-cache invalidated for the relevant memory addresses. This is because the CPU does not in general maintain coherency between these caches for performance reasons (writing instructions is rare). Secondly, memory protection must be set to allow execution of the generated code. Some systems even forbid pages being writeable and executable at the same time in order to make code injection attacks that little bit harder.

Re: Ask HN: Favorite pointer tricks in C?

#69
post #25

* Using pointer offsets to get to the stack frame pointer, and then walking the frame pointer backwards to get the call stack. * Using && to take the address of a jump label. * Casting a u_int32_t over a 4-byte string (like an SMTP verb) to get a value you can switch() on.

> Casting a u_int32_t over a 4-byte string (like an SMTP verb) to get a value you can switch() on.

How do you ensure your code is portable between the architectures with different endianness ? One trick may be using htonl on the u_int32_t to get it to a canonical format, but probably there would be better approaches ?

Re: Ask HN: Favorite pointer tricks in C?

#70
post #67
post #36

Earlier quoted context omitted.

> Casting a u_int32_t over a 4-byte string (like an SMTP verb) to get a value you can switch() on. This is awesome beyond words. If I stumbled across this in the wild I would flip flop between awe and disgust until my head exploded. Let me guess, "SMTP verb" is not a hypothetical example?

There are at least three common mistakes involving tricks like this: 1. Alignment. Many CPUs will trap (or worse) if accessing a 32-bit quantity at a non-aligned address. 2. Endianness. Needless to say, the 32-bit value read for a given string depends on the machine endianness. 3. Aliasing. Casting between different pointer types can result in a violation of the C aliasing rules and, with a little bad luck, incorrect…

Good to see you on hn.
Post reply on HN