首页 > 其他分享 >1835_GCC中C语言typeof的使用

1835_GCC中C语言typeof的使用

时间:2023-12-21 12:01:24浏览次数:32  
标签:GCC 一个 max 功能 C语言 typeof 指针


Grey

全部学习内容汇总:GitHub - GreyZhang/c_basic: little bits of c.

1835_GCC中C语言typeof的使用

typeof是C语言中对数据类型的一种引用方法,目前看到的信息来看,并不是标准C中提供或者要求的内容。这个功能,其实是编译器提供的一种便捷的操作模式。而我看的资料中,这个功能在gcc中是有提供的。至于其他的编译器,是否也提供了类似的功能,这个还真不好讲。因此,利用这个功能相关的一些设计,我也暂时不会纳入到我自己的C语言工具箱中。

从哪里看到的这样的用法

最近从国科础石开放的开源项目中看到了一个RTOS,我获取了他仓库的代码。简单浏览看到了一个list.h,查看后是一个以内敛方式提供的一个链表操作。看到这样的设计的时候,我觉得很吸精,其实这种设计看上去有很好的通用性。而且,从注释看,其实这个设计也是来自于linux内核的。

1835_GCC中C语言typeof的使用_#define

上面是文件开头的部分,不仅看到了我说的拷贝的说明,而且也看到了我今天探索的这个功能。

资料整理过程说明

在此之前的确是没有用过 typeof ,先去看了一下这个文档。找到了如下链接:

Typeof (Using the GNU Compiler Collection (GCC))

这本身也是 gcc 的文档,查看上层的文档结构如下:

1835_GCC中C语言typeof的使用_mfc_02

从这里可以看出来,这个是gcc对于C语言的扩展。从描述看,其实C99中是已经支持了这样的功能的,但是C99并不是标准C的来源,因此标准C来源的C90其实是不支持的。

要点细节分析

typeof (x[0](1))

x是一个函数指针数组,上面的功能实现的是获取对应函数返回值的类型。

typeof (int *)

一个指向整形的指针类型。

上面是文档中的两个例子,其实从这两个例子可以看得出来,这个typeof其实是可以快速构建出来一个新的隐藏式的数据类型的。这个构建的速度或者说便捷性是比typedef要快很多的。

更多探索以及效果分析

#define max(a,b) \
  ({ typeof (a) _a = (a); \
      typeof (b) _b = (b); \
    _a > _b ? _a : _b; })

这是另一个使用的示范,实现的是最大值求值的宏。这个设计相比不使用typeof实现的功能有点在于数据类型可以根据输入的信息进行动态的调整,达到“自适应”的效果,可以避免溢出等一系列的问题。

typeof (*x) y;

结合前面的分析,这一段代码快速定义了一个变量y,y是一个指向x类型的指针所指向的内容。也就是说,x本身是一个指针,而y相当于对这个指针类型的引用类型。

typeof (*x) y[4];

这个例子与上面功能类似,只是此时y是一个4个元素的数组。

typeof (typeof (char *)[4]) y;

这是一个双重的引用,首先里面的typeof实现了对于一个字符串指针的引用,接下来扩展为4元素数组。而这样的语义,进一步由外面的typeof来继承。最终,构建出来了y,表征一个四元素指针数组。

#define pointer(T)  typeof(T *)
#define array(T, N) typeof(T [N])

array (pointer (char), 4) y;

这样的一个语言元素的组合抽象,让整个数据对象的构建理解变得更加人性化。很容易理解最后行代码其实是定义了一个y,而y是一个4个char指针元素的数组。

小结

从上面的处理看,我觉得typeof的功能不仅仅是紧急应用,可以在typeof没有构建的情况下迅速组合出来新的数据类型引用方式,而且让语言的设计具备了更好的伸缩度。这不仅是typeof的一个变种或者替代品,有着更加灵活的方式。但是,这也不是在任何场景下都是最优秀的设计方案。如下的例子就是一个说明:

#define max(a,b) \
  ({ __auto_type _a = (a); \
      __auto_type _b = (b); \
    _a > _b ? _a : _b; })

这里有了一个新的max的实现方式,依然具有前面实现方式的优点。但是,这种使用方式会让max的组合调用有更好的处理方式。不会像typeof一样,多重组合调用会有指数型增长的调用展开消耗。什么是这种组合调用呢?大概的形式应该如下:

x = max(max(a, b), max(max(c, d), e));

这是很好的语言特性,这样的语言特性一定催进了很多信息化的发展。不过,在控制类的嵌入式领域之中,或许这种能力的展示显得过于滞后。至少目前为止,我还没有在项目应用中看到过这样的设计应用。

标签:GCC,一个,max,功能,C语言,typeof,指针
From: https://blog.51cto.com/greyzhang/8921026

相关文章

  • 深入c语言中的数组
    在C语言中,数组是一种非常重要的数据结构,它可以用来存储一系列相同类型的数据。数组在C语言中被广泛应用于各种算法和数据处理中,因此了解和掌握数组的使用是非常重要的。数组的声明和初始化在C语言中,数组的声明和初始化非常简单。我们可以通过以下语法来声明和初始化一个数组:intarr......
  • C语言中文网
    关于C语言中文网」C语言中文网,一个在线学习编程的网站。它始于C语言,但不终于C语言,除了C语言,您还可以学习C++、Java、Python、Golang、PHP、Linux等其它技能,请「猛击这里」查看所有教程。C语言中文网成立于2012年初,由站长「严长生」在大三寒假期间创办,致力于分享优质编程教程,......
  • C语言中的存储类型
    指针在内存中定义变量(申请内存空间)存储数据,但是每个存储数据变量都有地址,地址也能找到内存空间,通过地址也可以操作到内存空间的值指针:存储地址的变量,就叫做指针,也叫做指针变量指针也会占用内存空间,但是指针占用内存空间,空间中存储的是地址值指针就是操作内存地址,使用内存地址定......
  • c语言 数组与指针
    @TOC前言之前我们讲了指针数组,今天讲一下数组指针。一、数组与指针的概述:数组指针就是数组的指针,就是指向数组的指针。inta[5]={1,2,3,4,5};//定义一个数组int*p=&a[0];//定义一个指针指向数组的首地址,由于数组的首地址就是数组名,所以&a[0]==a;则可写为int*......
  • 通过反汇编理解GCC优化以及inline函数的功能
    在linux环境写下以下C代码:首先不加优化选项去编译:gcc-ginline_func_test.c-oinline_func_test之后用objdump-S反汇编可见:可见,即使f1是inline函数,还是和f2一样被调用了六次。之后加入优化选项去编译gcc-O1-ginline_func_test.c-oinline_func_test这一次,f2依然被......
  • 《初学C语言第33天》
    ////——————————————————————scanf的语法并举例说明////scanf是C语言中的一个标准输入函数,用于获取用户输入的数据,并赋值给变量。////——————基本语法:////scanf(format,variables);////其中,format是格式控制字符串,用于指定输入数据的格式,variable......
  • clang VS gcc 的command-line机制: clang 在 MacOS 上要设置 -isysroot $(xcrun --sho
    clangVSgcc的command-line机制:clang在MacOS上作为编译器时要设置-isysroot$(xcrun--show-sdk-path)注意明确指定clang/clang++在MacOS上作为编译器时,一定要设置CFLAGS/CPPFLAGS为"-isysroot$(xcrun--show-sdk-path)${CFLAGS}"CC="/usr/local/bin/clang"C......
  • C语言 不定长数组
    #include<stdio.h>#include<malloc.h>structstudent{intage;};structdata{intlen;//不占用空间structstudentstudents[0];};intmain(){structdata*d=malloc(sizeof(structdata)+2*sizeof(structstudent));......
  • 《初学C语言第32天》
    //////——————————————————10.指针笔试题//////笔试题1//#include<stdio.h>//intmain()//{//  inta[5]={1,2,3,4,5};//  int*ptr=(int*)(&a+1);//  printf("%d,%d",*(a+1),*(ptr-1));//*(a+1):指的是数组a中第二个元素2......
  • C语言实现TCP CS模型代码,客户端服务器
    服务端将接受客户端发送的数据并将其转换成大写形式,然后再发送给客户端,客户端将发送一个字符串给服务器,并显示来自服务器的响应内容。服务器点击查看代码#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/socket.h>#include<netinet/in.h>#......