当前位置:网站首页>If you want to be good at work, you must first use its tools -c language expansion -- embedded C language (11)
If you want to be good at work, you must first use its tools -c language expansion -- embedded C language (11)
2022-07-26 15:32:00 【Little fat man touching his stomach】
If a worker wants to do a good job, he must sharpen his tools first -C Language development – The embedded C Language ( 11、 ... and )
Here comes the last part–> Variable parameter macro
The content of the article is all from –>《 The embedded C Language self-cultivation —— From chip 、 Compiler to operating system 》 Senior Wang Litao , Super recommendation
In the previous content, we have the definition and use of variable parameter functions , If you don't know, you can have a look first , The basic routine here is to use va_list、va_start、va_end Isochromatic , To parse those variable parameter lists .
Find the storage address of these parameters , These parameters can be processed . Or do it yourself , Handle it personally ; Or continue to call other functions to handle .
The whole example :


GNU C And help : Simply macro definitions also support variable parameters !
What is a variable parameter macro
C99 Standards already support this feature , But other compilers are not very awesome , Yes C99 Standard support is not very good , Only GNU C The standard supports this function , So sometimes we think of this variable parameter macro as GNU C A syntax extension of the standard .
Implemented above LOG() Argument function , If we want to use a variable parameter macro implementation , We can define this directly .
The implementation form of variable parameter macro is actually similar to that of variable parameter function : use … Represents a variable parameter list , The variable parameter list consists of uncertain parameters , The parameters are separated by commas . Variable parameter macros use C99 A new addition to the standard __VA_ARGS__ Predefined identifier to represent the previous argument list , It's not like a variable parameter function , Use va_list、va_start、va_end These macros parse the argument list . When the preprocessor expands the macro , Will replace all... In the macro definition with a list of arguments __VA_ARGS__ identifier .
Use macro definition to realize a variable parameter macro of printing function , You'll find that , Its implementation is even simpler than variable parameter function !Linux A lot of print macros in the kernel , Variable parameter macros are often used to implement , The macro definition is usually in the following format .

In this macro definition , There's a fixed parameter , Usually a format string , The following arguments are used to print data in various formats , Match the previous format string . This definition is easy to understand , But there is a loophole : When the variable parameter is empty , When the macro is expanded, there will be a syntax error .


The above program will report an error when compiling , Produce a grammatical error . This is because , We only give LOG The macro passed an argument , And change the parameter to empty . When the macro expands , It becomes like the following .
After the grand exhibition , There is also a comma after the first string parameter , Does not conform to grammatical rules , So there is a grammatical error . We need to continue to improve this macro , Use macro connectors ##, This syntax error can be avoided .
Continue to improve our macro
Next , We use macro connectors ## To improve the macro above . Macro connectors ## The main function of is to connect two strings . We can use ## To connect two characters , When the preprocessor expands a macro in the preprocessing phase , Will ## The characters on both sides merge , And delete ## This connector .

In the above procedure , We define a macro .

The function of this macro is to connect characters a and x. In the program ,A(1) After unfolding, it is a1,A() After unfolding, it is a. We use printf() Functions can print variables directly a1、a Value , Because after grand exhibition , It's equivalent to using int The keyword defines two integer variables a1 and a. The above program can be compiled through , The operation results are as follows .

I know the macro connector ## How to use , We can be right LOG Macro makes some changes .


We're in the identifier __VA_ARGS__ The macro connector is added in front ##, The advantage of this is : When the argument list is not empty ,## The function of is to connect fmt And variable list , The parameters are separated by commas , Macro can be used normally ; When the argument list is empty ,## There's another special use , It will fix the parameters fmt Delete the comma after , So the macro can be used normally .
Another way to write variable parameter macros
When we define a variable parameter macro , In addition to using predefined identifiers __VA_ARGS__ Represents a variable parameter list , You can also use this way of writing .
Use predefined identifiers __VA_ARGS__ To define a variable parameter macro , yes C99 How to write the standard . And the format above is GNU C A new way to write extensions : May not be used __VA_ARGS__, But directly args… To represent a list of arguments , Then in the following macro definition , Use it directly args On behalf of the argument list .
Same as above , In order to avoid the syntax error when the parameter list is empty , We also need to add a connector between parameters ##.
Use this macro definition , You will find that it is better than using __VA_ARGS__ It looks more intuitive , Easier to understand .
Variable parameter macro in kernel
Variable parameter macro is mainly used for log printing in the kernel . Some driver modules or subsystems sometimes define their own print macro , Support print switch 、 Print format 、 Priority control and other functions . If in printk.h Header file , We can see pr_debug Definition of macro .


See this macro definition , It is estimated that two words have been rippling back and forth in the hearts of many people , I almost burst my throat , If you can blurt out , But at the same time, I have to admire the author of macro : A little macro , But can comprehensively use various skills and knowledge points , hold C The potential of language is brought into full play .
This macro defines three versions : If we have dynamic debugging options when compiling the kernel , So this macro is defined as dynamic_pr_debug. If the dynamic debugging option is not configured , Then we can go through DEBUG This macro , To control the opening and closing of the macro .
no_printk() As an inline function , It's defined in printk.h Header file , And through format Property declaration , Instructs the compiler to follow printf Standard to do parameter format check .
The most interesting thing is dynamic_pr_debug This macro , Macro definition uses do{…}while(0) structure . It seems a bit redundant : Have it or not , Our aces can work . It's all done once , Why use this seemingly “ Gild the lily ” What about the cyclic structure of ?
The truth is very simple , This definition is to prevent macros in conditions 、 Select the branch structure of the statement after expansion , Macro ambiguity . For example, we define a macro , It consists of two printed statements .
For example, we define a macro , It consists of two printed statements .
In theory ,else Branches can't be executed , But you can see through the print results , The program was executed else Part of the code for the branch . This is because the macro we define consists of multiple statements , After pretreatment and expansion , It's like this .

Multiple statements can be expanded directly in macro adjustment , It destroys the original program if/else Branching structure , Cause the program logic to change , That's why you see else Abnormal printing of branches . And use do{…}while(0) This structure , We can package the compound statements in our macro definition . After the grand exhibition , It's a block of code , This logic error is avoided .
A little macro , Hidden knowledge points , Use a combination of techniques , Analyze it carefully , Can learn a lot of knowledge . In the future work and study , You may be exposed to all kinds of 、 All kinds of macro . As long as there is a solid C Language foundation , be familiar with GNU C The common extension syntax of , When I encounter a macro like this again , We can all try to analyze it slowly by ourselves . Don't be afraid. , Only I have really analyzed , That's what we really know , Ability into their own knowledge and ability , To appreciate the subtleties of it .
边栏推荐
- 【5分钟Paper】Pointer Network指针网络
- VP video structured framework
- Enterprise digital transformation needs in-depth research, and it cannot be transformed for the sake of transformation
- University rankings in Beijing
- Remote desktop on Jetson nano
- 第七章 在 REST 服务中支持 CORS
- Using two stacks to implement a queue
- Strengthen the defense line of ecological security, and carry out emergency drills for environmental emergencies in Guangzhou
- 小白哪个券商开户最好 开户最安全
- Google tries to introduce password strength indicator for chromeos to improve online security
猜你喜欢

北京的大学排名

Practical purchasing skills, purchasing methods of five bottleneck materials

广州地铁十三号线二期全线土建已完成53%,预计明年开通

The IPO of shengtaier technology was terminated: it was planned to raise 560million yuan, and Qiming and Jifeng capital were shareholders

工具技能学习(二):前置技能-shell
![[static code quality analysis tool] Shanghai daoning brings you sonarource/sonarqube download, trial and tutorial](/img/fe/3baec8f6def4e569842a683fcb9fd1.png)
[static code quality analysis tool] Shanghai daoning brings you sonarource/sonarqube download, trial and tutorial

How do college students apply for utility model patents?

【C】 Flexible array

装备制造业的变革时代,SCM供应链管理系统如何赋能装备制造企业转型升级

Pytorch installation CUDA corresponding
随机推荐
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
R语言ggplot2可视化:使用ggpubr包的ggdotplot函数可视化点阵图(dot plot)、设置add参数添加均值和标准差竖线、设置error.plot参数实际显示箱体
Unity URP entry practice
The most detailed patent application tutorial, teaching you how to apply for a patent
R语言ggplot2可视化:使用ggpubr包的ggballoonplot函数可视化气球图(可视化由两个分类变量组成的列联表)、配置guides函数中的size参数指定不显示数据点大小的图例
【C】 Flexible array
采购实用技巧,5个瓶颈物料的采购方法
【5分钟Paper】Pointer Network指针网络
Tool skill learning (II): pre skills shell
Continuous integration (II) introduction to the basic use of Jenkins
Prometheus adds redis and MySQL node monitoring
Creation and traversal of binary tree
示波器的使用
OpenGL learning diary 2 - shaders
OSPF综合实验
食品制造企业想要实现智能协同的供应商管理,选择SRM供应商系统就够了
小白哪个券商开户最好 开户最安全
Xiaobai, which securities firm is the best and safest to open an account
Soft test (VII) performance test (1) brief introduction
软测(七)性能测试(1)简要介绍