Monthly Archives: November 2013

time is too fast to catch

why time is so fast? i can’t just lay down and stare mindlessly for “a long time”, long in the sense of my mental judgement, ’cause we’ll all be dead by now. feels like a rest is too much sometimes, can’t do something like peruse, like taste. ’cause time just flies by if you do that. if you are not careful, some hours just slip by without notice.

why i can’t just die yet

why can’t i just die yet?

because i believe i’m different, i want to leave something behind, i want to change this world

but my parents didn’t believe it

but i believe in myself

and i want to prove, to prove i’m different, to prove i can succeed

and there is still someone i love, and she’s still alive

honestly living is suffering, but i can’t just die yet

当时确实很痛

后来我以为时间能淡忘这些

确没想到痛却像是陈年的老酒一样,时间越长,酒越香,感觉越清晰

现在就像梦靥一样,每每从梦魇中惊醒

我已经习惯了,接纳了它

所以感觉越来越清晰,清晰的都有点不真实了

毕竟你都那么久没见她了

很多都是记忆的碎片

some thoughts about Visual Studio 2013 C99 compiler

So here it is, Visual Studio 2013 with partial C99 support.

It’s good to see Microsoft finally picked up support for C99 because otherwise a lot of code can’t compile because they are C99 compliant.

Well, in my experience with C, the most annoying thing from C89 to C99 is mix variable declaration with code. I simply can’t live without it. I like to declare a variable just before I need to use it other than stack all variables at the start and use it later. I know this is a personal taste thing but C99 do offers more freedom.

Now let’s have a look at VS 2013’s new C99 compiler. I have thrown a not too simple project to it and compilation failed, after some digging around I found the bug is quite interesting. That project uses a lot of “variable declaration inside code” feature and some declaration is immediately after a if switch without bracket. To trigger this bug, that declaration needs to be a struct variable and have to be not inside the file you define your main(). Let’s see a example:

Say you got a file named foo.h with contents like this:

#ifndef __FOO__
#define __FOO__

typedef struct foo {
 int bar;
}foo;

int foo_do(int a, int b);

#endif

and you write your foo.c like this:

#include "foo.h"

int foo_do(int a, int b) {
 int d = 1;
 if (a > b) d = 0;
 foo *c;
 return -1;
}

Even you got your main.c right, the compilation would fail in foo.c in line 6

To fix it, just change

 if (a > b) d = 0; 

to

 if (a > b) {d = 0;} 

or if you change

 foo *c; 

to

 int c; 

It also won’t have trouble compiling.

And if you move foo.h and foo.c to main.c like this:

typedef struct foo {
 int bar;
}foo;

int foo_do(int a, int b) {
 int d = 1;
 if (a > b) d = 0;
 foo *c;
 return -1;
}

/* your code */

int _tmain(int argc, _TCHAR* argv[]) {

/* your code */

then delete foo.h and foo.c, the project would compile just fine.

I do appreciate Microsoft adopting C99, but if they can make their C99 compiler more robust, I would be more happy.

Hope someone at Visual Studio developer team can read this.

C and C++ compiler difference in action

So before Visual Studio have a C99 compiler, I use C++98 compiler for my C code. You just rename .c to .cpp and it compiles fine, at least most of the time. Since C++ is actually not a super set of C(read http://david.tribble.com/text/cdiffs.htm), sometimes C++ compiler can’t handle legit C code.

A common one is type casting. You can do this in C:

int *foo = malloc(16 * sizeof(int));

But in C++, you have to cast the pointer, like this:

int *foo = (int *)malloc(16 * sizeof(int));

Another I encountered is struct initialization. Suppose you got this struct:

struct foo {
 int gee;
 float bar;
};

in C, you can initialize a variable like this:

struct foo a = {
 .gee = 1,
 .bar = 0.1f
};

in C++, member name notation with . is not allowed, you need to use this:

struct foo a = {
 1,
 0.1f;
};

but notation in C is more intuitive, if you miss that in C++, use this:

struct foo a = {
 /* .gee = */ 1,
 /* .bar = */ 0.1f
};

Another interesting thing is C89 has no “inline” keyword but C++98 can handle that well.