Skip to content
Gopal V edited this page Oct 24, 2013 · 3 revisions

Deep C Notes

Notes from Deep-C

off_t end = pos + PREFIXLEN(buf);

where PREFIXLEN(buf) does (buf[pos++] | (buf[pos++] << 8))

and the scenario for VINTPREFIX(buf) is worse since it introduces control points (i.e the value has more bytes if MSB is 1) within the section.

This bit us badly when we switched compilers and tests started to fail. We had to crawl through gcc -E to find it.

The other bit of unspecified behaviour kicked in when we had -O3 enabled and strict-aliasing, basically with allocations and I/O sections mixed with macros which cast it into structs. Something like

#define WRITE_MESSAGE(buf, pos, tag, value) do {
  Msg* msg = (Msg*)(buf[pos]);
  msg->tag = tag;
  msg->value = value;
  pos += size(msg); 
} while(0)

int8_t *buf = malloc(...);
buf[0] = 0; // always zero out buf[0]
pos = 0;
if(...) {
  WRITE_MESSAGE(buf, pos, 0, 42);
}
// now any check on buf[0] results in invalid assembly due to aliasing

This didn't warn with -Wall and we hit a problem with -O3.

Btw as an example of bad-code ideas inherited by Ruby programmers, here's my favourite fake-closure sample

typedef int (*intfun)(int i);

intfun make_adder(int i) 
{
   int add(int k) 
   {
      return (i+k);
   }
   return add;
}
int main() 
{
   intfun foo;
   foo = make_adder(2);
   printf("%d\n", foo(3));
   return 0;
}    

This is what you have to do to make real closures in C - x86-native-closures

And as for the variable shadowing problem, I dug up my old GCC bug-report (on the lack of warnings) - gcc-bug #19099

Clone this wiki locally