当前位置:网站首页>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 .
边栏推荐
- R语言ggplot2可视化:使用ggpubr包的ggdotplot函数可视化点阵图(dot plot)、设置add参数添加均值和标准差竖线、设置error.plot参数实际显示箱体
- The IPO of shengtaier technology was terminated: it was planned to raise 560million yuan, and Qiming and Jifeng capital were shareholders
- Deep packet inspection using cuckoo filter paper summary
- 03 common set security classes under JUC
- NAT/NAPT地址转换(内外网通信)技术详解【华为eNSP】
- Chapter 08_ Principles of index creation and design
- MYSQL 命令大全
- 【C】 Flexible array
- Glyphicons V3 字体图标查询
- 软测(七)性能测试(1)简要介绍
猜你喜欢

信用卡数字识别(opencv,代码分析)
![[leetcode daily question] - 121. The best time to buy and sell stocks](/img/51/ae7c4d903a51d97b70d5e69c6fffaa.png)
[leetcode daily question] - 121. The best time to buy and sell stocks

Credit card number recognition (openCV, code analysis)

How to query foreign literature?

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

Practical task scheduling platform (scheduled task)
![Detailed explanation of nat/napt address translation (internal and external network communication) technology [Huawei ENSP]](/img/84/3f5092bc2da6dfe657d7c27c6492cc.png)
Detailed explanation of nat/napt address translation (internal and external network communication) technology [Huawei ENSP]

# 工欲善其事必先利其器-C语言拓展--嵌入式C语言(十一)
![[five minute paper] reinforcement learning based on parameterized action space](/img/86/9deb43958b6bf7401f41f31f737cc9.png)
[five minute paper] reinforcement learning based on parameterized action space
![[leave some code] Apply transformer to target detection, and understand the model operation process of the model through debug](/img/71/068de34da9d1e6041237d936314e14.png)
[leave some code] Apply transformer to target detection, and understand the model operation process of the model through debug
随机推荐
【基础】动态链接库/静态链接库的区别
拒绝噪声,耳机小白的入门之旅
Vs add settings for author information and time information
如何将规划图转成带经纬度的矢量数据geojson
R语言ggplot2可视化:可视化折线图、使用aes函数中的group参数为不同分组可视化折线图
二叉树的创建以及遍历
R language ggplot2 visualization: use the ggballoonplot function of ggpubr package to visualize the balloon graph (visualize the contingency table composed of two classification variables), and config
Complete MySQL commands
Tool skill learning (I): pre skills -makfile, make,.Mk
Write a summary, want to use a reliable software to sort out documents, is there any recommendation?
03 common set security classes under JUC
anaconda No module named ‘cv2‘
Zhaoqi science and technology innovation high-end talent project was introduced and implemented, mass entrepreneurship and innovation competition was organized, and online live roadshow was broadcast
【留点代码】将transformer运用到目标检测上来,通过debug了解模型的模型运算流程
Detailed explanation of nat/napt address translation (internal and external network communication) technology [Huawei ENSP]
Devsecops, speed and security
Continuous integration (II) introduction to the basic use of Jenkins
Yifang biological fell 16% on the first day of listing: the company's market value was 8.8 billion, and Hillhouse and Lilly were shareholders
Tool skill learning (II): pre skills shell
R language uses LM function to build multiple linear regression model, writes regression equation according to model coefficient, and uses fitted function to calculate y value (response value) vector