GNU C 语法扩展(2)

《GNU C 语法扩展(2)》

要研究LINUX内核,C语言是基础中的基础,但是LINUX并不是完全的标准C,而是对标准C做了很多扩展,这些扩展特性对于我们分析内核有着很重要的作用,下面做些总结性的工作。

2 局部标签

  • GCC允许你在任何内嵌代码块中声明局部标签,所谓的局部标签跟普通的标签用法一样(用在goto语句或者被获取地址),只不过你只能在声明它的代码块中使用。局部标签的声明如下:
__label__  label; 

或者

__label__  label1, label1, … ;
  • 局部标签声明只是定义了标签的名字,但是并没有定义标签本身,它本身必须像普通标签那样在语句内嵌表达式内部使用局部标签。
  • 另外要注意的是,局部标签的声明必须在代码块的起始位置(即位于任何其他声明和语句之前)。
  • 在复杂的宏定义中,局部标签显得尤为有用。如果一个宏包含有内嵌循环,goto语句可以方便地跳出它们。然而,拥有整个函数作用域的普通标签在这里不能被使用,因为该宏可能会在一个函数中被展开若干次,那样的话同样的一个标签就会被重复定义。局部标签就是用来避免这种情况的。例如:
#define SEARCH(value, array, target) 
do {
      __label__ found;
      typeof (target) _SEARCH_target = (target);   
      typeof (*(array)) *_SEARCH_array = (array);int i, j; int value; 
      for (i = 0; i < max; i++)
           for (j = 0; j < max; j++) 
                if (_SEARCH_array[j] == _SEARCH_target) 
                      { (value) = i; goto found; } 
      (value) = -1;
      found:;
} while (0)

当然,也可以用语句表达式改写这个宏定义:

#define SEARCH(value, array, target) 
({    __label__ found;
      typeof (target) _SEARCH_target = (target);   
      typeof (*(array)) *_SEARCH_array = (array);int i, j; int value; 
      for (i = 0; i < max; i++)
           for (j = 0; j < max; j++) 
                if (_SEARCH_array[j] == _SEARCH_target) 
                      { (value) = i; goto found; } 
      (value) = -1;
      found:
             value;
})
  • 局部标签在内嵌函数(如果有)中也是可见的。

注意:我们用语句表达式的时候,在最后的found局部标签后面有个语句 value; 而在do … while循环中并无出现,原因是语句表达式的值取决于最后的表达式,而do … while 循环中的found局部标签仅仅用来跳出循环

===========我是华丽的分割线===========

更多知识:
点击关注专题:嵌入式Linux&ARM

或浏览器打开:https://www.jianshu.com/c/42d33cadb1c1

或扫描二维码:

《GNU C 语法扩展(2)》

    原文作者:Leon_Geo
    原文地址: https://www.jianshu.com/p/b514a85ad66e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞