百度空间 | 百度首页 
 
查看文章
 
GCC的一些扩展
2009-06-17 22:02


#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

可以看到,申明了该属性的函数,调用者必须使用其返回值(或者检查,或者将返回值赋予某个变量),不然则会有编译错误。


类别:Unix Tool | 添加到搜藏 | 浏览() | 评论 (1)
 
最近读者:
 
网友评论:
1
2009-06-17 22:27 | 回复
GCC的warn_unused_result扩展 很强大啊~学习了
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu