I wanted to investigate how Clang facilitates a kind of object-oriented 
programming style, using blocks. A first experiment was as follows:

// crash1.c
#include <stdio.h>

int (^f)();

void func() {
  __block int ext;
  f=^int {
    ext=7;
    printf("ext=%d\n",ext);
    return ext;
  };
}

int main() {
  func();
  for(int i=0;i<2;++i)
    printf("-> ext=%d\n",f());
}

I compiled with: clang -fblocks -lBlocksRuntime crash1.c. The result:

ext=7
-> ext=-1217394584
Segmentation fault (core dumped)

Thus a crash. The valgrind tool revealed that there were problems with the 
stack. Thus I tried to compile with option -fsanitize=safe-stack, and bingo!, 
the result as expected:

ext=7
-> ext=7
ext=7
-> ext=7

Then I tried a somewhat bigger program, inspired by an example for the Go 
language. It's a generator for fibonacci numbers.

// crash2.c
#include <stdio.h>
#include <stdlib.h>

typedef struct {
  int a,b;
  int (^f)();
} XX;

XX xx1,
   xx2;

void init(XX *x) {
  x->a=0; x->b=1;
  x->f= ^int {
    int out=x->a + x->b;
    x->a=x->b; x->b=out;
    return out;
  };
}

int main() {
  init(&xx1);
  init(&xx2);

  for (int i=0;i<3;++i) {
    printf("xx1: n=%d\n",xx1.f());
  };
  for (int i=0;i<3;++i) {
    printf("xx2: n=%d\n",xx2.f());
  };
}

The output was:

xx1: n=1
Segmentation fault (core dumped)

Another crash! Compiled with -fsanitize=safe-stack:

xx1: n=1
xx1: n=2
xx1: n=3
xx2: n=5
xx2: n=8
xx2: n=13

No crash, but no correct result either. There are 2 struct's, xx1 and xx2, so the output should be 1,2,3,1,2,3. It seems like only one struct was used however. Probably I don't understand how blocks exactly operate, but finally, by try and error, I found a way that seemed to work. But how was this code incorrect? The compiler version: 3.8.0-2ubuntu4.

W.Boeke

_______________________________________________
cfe-users mailing list
cfe-users@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users

Reply via email to