#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
void test_type()
{
int a = 0;
typeof(a) b =5;
printf("%d\n", b);
}
void test_min()
{
int a = 2;
int b = 3;
printf("min(a,b) = %d\n", a <? b);
printf("max(a,b) = %d\n", a >? b);
}
void test_switch(int a)
{
switch (a) {
case 0:
printf("%d in 0\n", a);
break;
case 1 ... 7:
printf("%d in 1 - 7\n", a);
break;
case 8 ... 15:
printf("%d in 8 - 15\n", a);
break;
default:
printf("%d in nothing\n", a);
break;
}
}
typedef struct _sa
{
int a;
int b;
bool operator <(const _sa & src) const
{
bool ret = true;
if(b > src.b)
{
ret = false;
}
return ret;
}
}sa;
void test_init()
{
//this extension is not implemented in GNU C++
//int widths[] = {[0 ... 9] = 1, [10 ... 19] = 2, [20] = 3};
sa s = {2, 6};
sa s2 = {6, 2};
//not supported
//struct _sa s2 = { .b = 2, .a = 6 };
printf("s.a=%d, s.b=%d, s2.a=%d, s2.b=%d\n", s.a, s.b, s2.a, s2.b);
}
//not supported in c++
void test_nested()
{
// void my_print(int a)
// {
// printf("my_print: %d; ", a);
// }
// printf("\n");
//
// my_print(2);
// my_print(23);
}
int test_redirect_call(const char * fmt, ...)
{
void * param = __builtin_apply_args();
void * ret = __builtin_apply((void (*)(...))&printf, param, 1024);
__builtin_return(ret);
}
void test_typeof_compare()
{
sa s1 = {2, 8};
sa s2 = {3, 7};
sa s3 = {1, 9};
sa min = min(s1, s2);
printf("min.a=%d, min.b=%d\n", min.a, min.b);
min = min(s1, s3);
printf("min.a=%d, min.b=%d\n", min.a, min.b);
min = min(s3, s2);
printf("min.a=%d, min.b=%d\n", min.a, min.b);
}
/*
*
*/
int main(void)
{
printf("haha\n");
test_type();
test_min();
test_switch(0);
test_switch(9);
test_init();
printf("ret: %d\n", test_redirect_call("test_redirect_call: %d\n", 125));
test_typeof_compare();
//test2();
//test_sem();
//test_timeused();
//test_str_cmp();
// for(int i=0; i<20; i++)
// {
// test_binary_search(i);
// }
return 0;
}
//--result--------------------------
haha
5
min(a,b) = 2
max(a,b) = 3
0 in 0
9 in 8 - 15
s.a=2, s.b=6, s2.a=6, s2.b=2
test_redirect_call: 125
ret: 24
min.a=3, min.b=7
min.a=2, min.b=8
min.a=3, min.b=7
dt_threadpool.cpp:396 un-init
//comments
感觉typeof和__builtin_apply_args系列比较有用,__inline__ 或 __attribute__((deprecated)) 也比较有用。详细可以参见下面文章:
http://www.ibm.com/developerworks/cn/linux/l-gcc-hacks/
http://gcc.gnu.org/onlinedocs/gcc-3.0.1/gcc.html#SEC_Top (extensions章节)
----------------------------------------------------------------------------------
GCC下成员函数指针是16bytes
很变态的问题。。。
其实是32位机器上是8bytes,64位机器上是16bytes;因为成员函数的指针不是一个指针而是一个结构。测试如下:
1 #include <stdio.h>
2
3 class Test
4 {
5 public:
6 void print() {
7 }
8 };
9
10 void print2(){
11
12 }
13
14 int main()
15 {
16 printf( "%d\n", sizeof( &Test::print ) );
17 printf( "%d\n", sizeof( &print2 ) );
18 }
19
输出如下:
tandai@tc-dpf-rd /home/tandai>:./test
16
8
-------------------------------------------------------------
GCC的warn_unused_result扩展:
这个扩展可以在编译期用来检查调用者是否判断了函数的返回值,对于一些关键的基础函数申明该属性,可以减少人为错误,与大家分享之。
使用示例如下:
int __attribute__((warn_unused_result)) check()
{
return 1;
}
int main(void)
{
int ret = 0;
check();
ret = check();
if(0 != (ret = check()))
{
//bla bla...
}
ret = check();
}
编译结果如下:
tm_td_tester.cpp: In function `int main()':
tm_td_tester.cpp:365: warning: ignoring return value of `int check()', declared with attribute warn_unused_result
make: *** [tm_td_tester.o] Error 1
可以看到,申明了该属性的函数,调用者必须使用其返回值(或者检查,或者将返回值赋予某个变量),不然则会有编译错误。