当前位置: 首页 > wzjs >正文

太原响应式网站建设网站开发培训实训

太原响应式网站建设,网站开发培训实训,中核集团电子商城,电商平面设计是什么1.引言 在上一篇文章【征程 6】VP 简介与单算子实操中,介绍了 VP 是什么,并以单算子 rotate 为例,介绍了 VP API 使用方法,其中有一些日志打印的代码显得特别高大上 LOGE_AND_RETURN_IF(src_mat.empty(), HB_UCP_INVALID_ARGUMEN…

1.引言

在上一篇文章【征程 6】VP 简介与单算子实操中,介绍了 VP 是什么,并以单算子 rotate 为例,介绍了 VP API 使用方法,其中有一些日志打印的代码显得特别高大上

    LOGE_AND_RETURN_IF(src_mat.empty(), HB_UCP_INVALID_ARGUMENT,"Read image {} failed", src_img.c_str());

作为对 C++不那么熟悉的伙伴,可能会好奇:LOGE_AND_RETURN_IF 到底是怎么写的呢?有没有什么门道可以介绍一下?

由于本人是属于对 C++不那么熟悉的同学,下面会从我的视角来介绍这个问题,如果其中有错误或表述不当的地方,欢迎评论指正。

其实本文是为了服务于另外一篇文章:【征程 6】工具链 VP 示例为什么能运行

2.log_util.h 代码解读

LOGE_AND_RETURN_IF 是在 log_util.h 定义的一个宏,下面来具体看下 log_util.h 中的代码:

#ifndef VP_CODE_07_ROTATE_INCLUDE_UTIL_LOG_UTIL_H_
#define VP_CODE_07_ROTATE_INCLUDE_UTIL_LOG_UTIL_H_#include <sstream>    //C++中标准头文件,不做解释
#include <utility>    //C++中标准头文件,不做解释#include "hlog/logging.h"    // 地平线提供的头文件,并不在当前目录下,为什么能包含?#define LOGI(err_msg, ...) HFLOGM_I("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)
#define LOGD(err_msg, ...) HFLOGM_D("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)
#define LOGE(err_msg, ...) HFLOGM_E("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)
#define LOGW(err_msg, ...) HFLOGM_W("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)#define LOGE_AND_RETURN_IF(condition, code, err_msg, ...) \do {                                                    \if (condition) {                                      \LOGE(err_msg, ##__VA_ARGS__);                       \return code;                                        \}                                                     \} while (0)#define LOGE_AND_RETURN_IF_NULL(ptr, code) \LOGE_AND_RETURN_IF(ptr == nullptr, code, NULLPTR_ERR(ptr))#endif  // VP_CODE_07_ROTATE_INCLUDE_UTIL_LOG_UTIL_H_

2.1 LOGx

来看一下日志宏定义

#define LOGI(err_msg, ...) HFLOGM_I("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)
#define LOGD(err_msg, ...) HFLOGM_D("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)
#define LOGE(err_msg, ...) HFLOGM_E("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)
#define LOGW(err_msg, ...) HFLOGM_W("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)

这些宏封装了 日志打印函数:

  • LOGI(Info):信息日志
  • LOGD(Debug):调试日志
  • LOGE(Error):错误日志
  • LOGW(Warning):警告日志

具体解释下其中一行:

#define LOGI(err_msg, ...) HFLOGM_I("VP_TRANSFORMATION", err_msg, ##__VA_ARGS__)

LOGI(err_msg, …) 定义了一个宏:

  • err_msg 是第一个参数
  • … 表示可以接受变长参数。但… 仅是一个 占位符,它不能直接用于宏的展开。(在下面介绍个展开的例子)

HFLOGM_I(“VP_TRANSFORMATION”, err_msg, ##VA_ARGS):

  • HFLOGM_I 是 hlog/logging.h 中提供的 具体日志实现
  • “VP_TRANSFORMATION” 是 日志模块名称,用于分类日志来源。
  • err_msg 就是前面的 LOGI 中的 err_msg
  • VA_ARGS 是一个 占位符的替代符,用于 填充 … 传递的实际参数。
  • ##VA_ARGS 的作用是 在 VA_ARGS 为空时去掉前面的逗号,防止编译错误。

当调用:LOGI(“Error code: %d”, 404);

它会展开为:HFLOGM_I(“VP_TRANSFORMATION”, “Error code: %d”, 404);

如果调用:LOGI(“Simple message”);

它会展开为:HFLOGM_I(“VP_TRANSFORMATION”, “Simple message”);

其中 ##VA_ARGS 确保了 VA_ARGS 为空时不会出现额外的 ,。(在下面介绍个展开的例子)

2.2 LOGE_AND_RETURN_IF 宏

下面来解读 LOGE_AND_RETURN_IF 宏的写法:

#define LOGE_AND_RETURN_IF(condition, code, err_msg, ...) \do {                                                    \if (condition) {                                      \LOGE(err_msg, ##__VA_ARGS__);                       \return code;                                        \}                                                     \} while (0)

这个宏 LOGE_AND_RETURN_IF 是一个常见的 防御式编程(Defensive Programming) 宏,如果 condition 为真,则:

  1. 记录错误日志 LOGE(err_msg, ##VA_ARGS)
  2. 返回 code

定义一个 LOGE_AND_RETURN_IF 宏时,do { … } while (0)起到什么作用?

do { … } while (0) 的作用是让整个宏块结构化,使它在语法上表现得像一个普通的语句,这样:确保 if 语句和 return 被视为一个整体,不会因为 if-else 结构导致错误。

  • 条件满足,触发错误日志并返回;当 … 为空时,去掉前面的 ,,防止编译错误,示例(无可变参数)
LOGE_AND_RETURN_IF(error, -1, "An error occurred");

展开后

do {if (error) {LOGE("An error occurred");return -1;}
} while (0);

##VA_ARGS 确保了 没有多余的 , 影响 LOGE 语法。

  • (带可变参数)
LOGE_AND_RETURN_IF(value < 0, -1, "Invalid value: %d", value);

展开后

do {if (value < 0) {LOGE("Invalid value: %d", value);return -1;}
} while (0);

2.3 do { … } while (0)作用

在前面有说 do { … } while (0) 可以:确保 if 语句和 return 被视为一个整体,不会因为 if-else 结构导致错误。

为什么 do { … } while (0) 能避免 if-else 结构导致的错误?if-else 结构有什么问题?下面来看一下

do { … } while (0) 的核心作用是让整个宏块在语法上表现得像一个单一语句,从而避免 if-else 结构中的 悬空 else(dangling else) 和 单行 if 语句的 bug。

2.3.1 if-else 结构的问题

如果 没有 do { … } while (0),在 if-else 语句中 直接用 if 语句包裹宏时,可能导致 else 结构错误。错误示例如下:

未使用 do { … } while (0) 定义宏

#define LOGE_AND_RETURN_IF(condition, code, err_msg, ...) \if (condition) {                                      \LOGE(err_msg, ##__VA_ARGS__);                     \return code;                                      \}

代码中调用宏

if (x < 0)LOGE_AND_RETURN_IF(x < -10, -1, "x is too small");
elseprintf("x is positive\n");

错误展开:

if (x < 0)if (x < -10) {  LOGE("x is too small");  return -1;  }  // 这里的 `if` 结束
else  // 这个 else 可能会匹配到错误的 if!printf("x is positive\n");

此时就会引入悬空 else 的问题。

2.3.2 悬空 else 问题

错误现象:

x = -5:
x is positive   // 这个输出是不应该出现的!

C/C++ 规定:else 总是匹配最近的 if。

上一节中 else 错误地匹配了 if (x < -10),而不是 if (x < 0),导致:

  • x = -5 时,if (x < 0) 为真,但 if (x < -10) 为假,所以 LOGE_AND_RETURN_IF 不执行。
  • 然而 else 仍然执行,最终 printf(“x is positive\n”); 被错误地执行!

解决方案:使用 do { … } while (0)结构。

2.4 NULLPTR_ERR(ptr) 宏

#define NULLPTR_ERR(ptr) #ptr " is null pointer"

#ptr 是 字符串化(stringizing)运算符,它会把 ptr 变成字符串。

示例:

printf("%s\n", NULLPTR_ERR(my_ptr));

展开后:

printf("%s\n", "my_ptr is null pointer");

输出:my_ptr is null pointer

2.5 LOGE_AND_RETURN_IF_NULL(ptr, code) 宏

#define LOGE_AND_RETURN_IF_NULL(ptr, code) \LOGE_AND_RETURN_IF(ptr == nullptr, code, NULLPTR_ERR(ptr))

这个宏会:

  • 检查 ptr 是否为 nullptr。
  • 如果 ptr == nullptr:
    • 记录日志,日志信息由 NULLPTR_ERR(ptr) 生成,例如 “ptr is null pointer”。
    • 返回 code 作为错误码。

3.总结

本文主要介绍在 VP 单算子示例中用到的日志打印的头文件应该怎么写,主要适用于和我一样 C++基础学习用户~

http://www.dtcms.com/wzjs/573130.html

相关文章:

  • 深圳网站建设定制平台怎么在网站上打广告
  • 有那些网站可以做担保交易的梅州建设公司网站
  • 程序员 做 个人网站长春网站业务哪个公司好
  • 网站打开速度多少时间网站建设维护工作
  • 网站建设w亿码酷1流量订制高端集团响应式企业网站模板
  • 网站建设的基础资料合肥哪家做网站不错
  • 网站建设与管理维护做产品封面的网站
  • 网站开发后台一般用什么智能建站软件哪个好
  • 做网站有兼职吗最便宜的网站叫什么名字
  • 如何让百度收录网站优购物官方网站手机
  • 大型 视频网站开发大同市住房与城乡建设厅网站
  • 做字幕网站有哪些做音乐网站怎么放音乐
  • 无锡便宜做网站深圳外贸集团
  • 英德建设网站施工员证书查询网站
  • 网站建设手机建设工程其它费计算网站
  • 建网站需要多少钱和什么条件免费百度广告怎么投放
  • 知名营销网站开发dede如何制作网站地图
  • 建设网站教程网络推广培训要多少钱
  • 商城网站建设的注意事项wordpress 调用近期文章
  • 淄博网站建设招聘餐饮店设计哪家好
  • 本地企业网站建设建设网站的
  • mstsc做网站江苏网络科技有限公司
  • 高端品牌网站建设九五网络网站建设续费是什么费用
  • 怎么看一个网站用什么程序做的wordpress漫画采集
  • 网站备案 几年网络优化是做啥的
  • 自己做采集电影网站19手机网站
  • 有趣的网站网址之家中国人在线观看免费高清
  • 浙江省住房和建设厅网站哪个网站的系统
  • 网站产品的详情页怎么做福清哪有做网站的地方
  • 服务好的微网站建设杭州seo外包服务