Use C variable parameters and macro definitions to implement your own log system

[Why write this article]

   In the development process of embedded applications, the log system is very important! Especially when there are occasional bugs related to the current execution environment in the production process, if there is no log system to track the problem, it is difficult to reproduce the problem.

    Therefore, it is very helpful and necessary to implement a log system of your own. In the software model, the log system is generally compiled into a library file. The application program directly calls the API interface function provided in the library to record the log information.

    Then there are 3 problems to be dealt with to implement your own log system:

(1) Design of log API function.

(2) Cache of log information.

(3) Persistence of log information, that is, it is written to the local file system.

 

This article mainly explains the first problem: the design of the log API function.

[First on the code]

【test】

[Knowledge Points]

1. Concatenation of string literals

    In C language, there are many ways to concatenate strings: memcpy, strcpy, strcat, sprintf and so on.

    In line 19 of the code, the method of string literal splicing in C language is used to splice the three strings "%s:%d(%s) \"" format "\"\n" into one string .

 

    Add:

    In the logging system code, there are some places where you need to format strings.

    Using sprintf is the most convenient, but it is also the least efficient!

    You can also use some third-party libraries to implement string formatting, such as fmtlib, facebook's folly format, and google's Abseil StrFormat.

    Of course, the best way is to format specific types of data by yourself, which can significantly improve the throughput of the logging system. I will talk about this part of the code in the next article.

 

2. Variable parameters

    Everyone knows that the printf function is implemented through a variable parameter mechanism.

    Variable parameters can be defined and used like this:

(1) Without parameter name

#define debug1(...)                printf(__VA_ARGS__)
#define debug2(format, ...)        printf(format, __VA_ARGS__)
#define debug3(format, ...)        printf(format, ##__VA_ARGS__)

(2) With parameter name

​
#define debug4(args...)            printf(args)
#define debug5(format, args...)    printf(format, args)
#define debug6(format, args...)    printf(format, ##args)

 

    The 20th line of code uses __VA_ARGS__ to represent the three points (...) in the macro definition parameters, which are variable parameters.

 

    Let’s talk about "##" again:

    If you call: debug2("code = %d", 100); There is no problem with this call.

    If you call: debug2("hello"); when you call here, if no parameters are passed in after format, then a compilation error will occur, because after the macro replacement becomes printf("hello",), after the first parameter There is an extra comma, so an error is reported.

    If you call: debug3("hello, world!"); then there is no problem, because there is "##" in front of the variable parameter __VA_ARGS__ in debug3. When the compiler finds that no parameters are passed in, it will automatically change the format The comma after it is removed, so the compilation is OK.

 

3. # and ## in the macro definition

    The function of # is to "stringify" macro parameters during preprocessing, for example:

#define LOG(exp)   printf("%s=%d\n", #exp, exe)
int code = 100;
LOG(code);                // 被替换为"code=100"

 

    The function of ## is to "glue" two macro parameters during preprocessing, for example:

#define VAR(name, no)  name##no
int VAR(err, 1);   // 被替换为 int err1;
err1 = 100;

 

[After finishing work]

I wonder if this article will bring you a little help?

In addition, comments and reposts are free~~~

I will continue to share various best practices in the embedded development process, welcome to pay attention to the public number: IOT Internet of Things Town

Guess you like

Origin blog.csdn.net/u012296253/article/details/110496534