宏定义天坑记录

宏定义天坑记录

事件原委与推理过程

在编译一个使用了Protobuf的项目时出现了如下报错

[yb@VM-8-7-centos boost_searcher]$ make
g++ -o http_server http_server.cc data/raw_html.pb.cc -std=c++11 -lboost_system -lboost_filesystem -lpthread -ljsoncpp -lprotobuf 
In file included from /usr/local/protobuf/include/google/protobuf/io/coded_stream.h:132,from data/raw_html.pb.h:23,from index.hpp:11,from searcher.hpp:10,from http_server.cc:43:
/usr/local/protobuf/include/google/protobuf/io/coded_stream.h: In member function 'std::ptrdiff_t google::protobuf::io::EpsCopyOutputStream::GetSize(uint8_t*) const':
/usr/local/protobuf/include/google/protobuf/io/coded_stream.h:835:5: error: 'LOGLEVEL_4' is not a member of 'google::protobuf'; did you mean 'LOGLEVEL_INFO'?835 |     GOOGLE_DCHECK(ptr <= end_ + kSlopBytes);  // NOLINT|     ^~~~~~~~~~~~~

大致意思就是LOGLEVEL_3这玩意没被定义过,非常莫名奇妙的错误

当发现是google/protobuf下的头文件的问题,直接就头大了

编译过程中的语法错误就是两个极端,

  • 要么是自己的代码有语法错误,改一下就行
  • 但这是官方头文件文件报的语法错误啊,错误肯定不可能出现在人家,又不能调试,那没点时间和运气,这问题怕是搞不定

但我多少是有点运气在的,无意间交换了源代码中的两个头文件,居然编译过了!!!!

发现只要"searcher.hpp"定义在"HttpServer.hpp"前面,就能编过

啊,这就有点玄幻了啊

思考一下,这两个头文件内,应该是有某些依赖关系,或者跟编译的顺序有关

试了一下

这样也能过

也就是说,searcher.hpp中一定有某些东西要出现在HttpServer.hpp前面

又瞅了一眼报错

既然报错从你来,就拎着你测吧(整个头文件包含树中,这个文件处于末梢,再向末梢就是官方文件了)

放这里,诶果然又能编过了

接下来,就拿它沿着整条头文件包含树,一直向下试,看哪里出现了问题

直到到达一个log.hpp的头文件,不能再向下时

发现,当raw_html.pb.hFATAL上时能编译过,在其下面则无法编过

啊,小东西,终于找到你了啊

如果你观察仔细,发现这个3,在前面的报错里也有点端倪

当把这个宏定义为4时,果然变成了LOGLEVEL_4

原因分析

从上面推理中可以看出,显然是这个宏定义的问题

google/protobuf的头文件中一定也有一个FATAL宏的定义,或者出现了FATAL关键词

由于C语言对宏的处理发生在预处理阶段,只进行简单无脑的文本替换

在所有的头文件中,我们都写了#pragma once,也就意味着在整个头文件包含体系中,只要出现第一次FATAL的宏定义,那以后的所有FATAL宏定义都将被忽视,一些不该被进行宏替换的地方也会被替换

自然,当我们把google/protobuf的头文件放在我们的FATAL之前,也就不会受我们的宏定义影响

总结

虽然某些时候,对宏的使用能让我们的代码简单玄妙不少,但坑也是真的坑啊

有了上面的经验教训,宏这种东西以后还是尽量少用了,毕竟不是每次都这么好运气

如果替换宏的话,大家可以尝试使用conststatic const或者枚举的语法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/125591.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

etcd选举源码分析和例子

本文主要介绍etcd在分布式多节点服务中如何实现选主。 1、基础知识 在开始之前&#xff0c;先介绍etcd中 Version, Revision, ModRevision, CreateRevision 几个基本概念。 1、version 作用域为key&#xff0c;表示某个key的版本&#xff0c;每个key刚创建的version为1&#…

【猿灰灰赠书活动 - 05期】- 【速学Linux:系统应用从入门到精通】

&#x1f468;‍&#x1f4bb;本文专栏&#xff1a;赠书活动专栏&#xff08;为大家争取的福利&#xff0c;免费送书&#xff09; &#x1f468;‍&#x1f4bb;本文简述&#xff1a;博文为大家争取福利&#xff0c;与机械工业出版社合作进行送书活动 &#x1f468;‍&#x1f…

【虚拟机】

虚拟机 简介VMware Workstation简介下载安装许可证密钥 CentOS简介下载 创建新的虚拟机 简介 虚拟机&#xff08;Virtual Machine&#xff0c;简称VM&#xff09;是一种软件模拟的计算机&#xff0c;它在一台物理计算机上创建了一个独立的虚拟计算环境。这个虚拟环境可以运行操…

在线实时监测离子风机的功能

离子风机是一种能够通过释放大量负离子来净化空气并提供清新环境的设备。要实现联网实时在线监测离子风机&#xff0c;可以考虑以下几个步骤&#xff1a; 1. 设备接入互联网&#xff1a;离子风机需要具备网络连接功能&#xff0c;可以通过无线网络或者以太网接入路由器&#x…

[uni-app] 海报图片分享方案 -canvas绘制

文章目录 canvas使用记录先看下实际效果图绘制流程及思路1. 绘制头像, 通过drawImage来绘制2.绘制文字部分 具体代码 分享海报图片的方式,以前再RN端采用的是截图方案, 我记得组件好像是 react-native-view-shot 现在要处理uni-app的海报图片分享, 一般也有 html2canvas的相关插…

索尼 toio™应用创意开发征文|联盟国战

✨ 能用众力&#xff0c;则无敌于天下矣&#xff1b;能用众智&#xff0c;则无畏于圣人矣。 —— 孙权 前言&#xff1a; 从火爆全网的ChatGPT&#xff0c;到人人都是开发者。AI无疑贯彻了整个2023年的主题&#xff0c;从刚上幼儿园的小朋友到耄耋之年的老顽童&#xff0c;都对…

0基础学习VR全景平台篇 第96篇:VR电子楼书

大家好&#xff0c;欢迎观看蛙色VR官方系列课程——VR电子楼书&#xff01; 作为2021年底全新上线的行业解决方案&#xff0c;是专门针对地产、园区数字化营销的一站式VR解决方案&#xff0c;为行业潜在客户提供优质的7x24小时线上看房体验。 本期教程将通过功能介绍后台操作&…

SpringBoot项目集成Druid

文章目录 一、前言二、Druid相关内容1、Druid简介1.1数据库连接池 2、项目集成Druid2.1、环境准备2.2、依赖准备2.3、编写配置文件2.4、测试访问 3、功能介绍3.1、查看数据源3.2、SQL监控3.3、URI监控 三、总结提升 一、前言 本文将介绍Druid的相关内容以及项目如何集成Druid&…

C#,《小白学程序》第十二课:日历的编制,时间DateTime的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十二课&#xff1a;日历的编制&#xff0c;时间DateTime的计算方法与代码 /// 本课学习时间类型的数据 DateTime 的简单方法&#xff0c;并编制一个月的日历。 /// </summary> /// <param name"sender"…

OpenWrt系统开发笔记

openWrt英文官网&#xff1a; https://openwrt.org/ 中文官网&#xff1a; http://www.openwrt.org.cn/ 一、开发环境及编译 在github上有两个源码使用的比较多   一个是lede,地址为&#xff1a;https://github.com/coolsnowwolf/lede   另一个为OpenWrt的官方源码&#…

笔记 | 排序算法实现(Python)

排序算法 一、选择排序二、合并/归并排序三、快速排序四、计数排序 排序类型时间复杂度选择排序(Selection Sort) O ( n 2 ) O(n^{2} ) O(n2)合并/归并排序&#xff08;Merge Sort&#xff09; O ( n log ⁡ n ) O(n\log n ) O(nlogn)快速排序(Quick Sort)平均情况 O ( n log ⁡…

STM32F4X RTC

STM32F4X RTC 什么是RTCSTM32F4X RTCSTM32F4X RTC框图STM32F4X RTC计数频率STM32F4X RTC日历STM32F4X RTC闹钟 STM32F4X RTC例程 什么是RTC RTC全程叫Real-Time Clock实时时钟&#xff0c;是MCU中一个用来计时的模块。RTC的一个主要作用是用来显示实时时间&#xff0c;就像日常…

利用less实现多主题切换(配合天气现象)

1. 先看效果&#xff1a; 2. 话不多说直接撸吧&#xff1a; 原理&#xff1a;先给body元素添加style&#xff0c;再根据天气现象动态更改style 开撸&#xff1a; 创建src/assets/style/variables.less 使用 XXX:var(–XXX,‘style’) 声明系列变量&#xff0c;之后添加其他变…

单臂路由实验:通过Trunk和子接口实现VLAN互通

文章目录 一、实验背景与目的二、实验拓扑三、实验需求四、实验解法1. PC 配置 IP 地址2. PC3 属于 Vlan10&#xff0c;PC4 属于 Vlan20&#xff0c;配置单臂路由实现 Vlan10 和 Vlan20 三层互通3. 测试在 PC3 上 Ping PC4 &#xff0c;可以 Ping 通 PC4 摘要&#xff1a; 本文…

任意文件读取及漏洞复现

文章目录 渗透测试漏洞原理任意文件读取1. 任意文件读取概述1.1 漏洞成因1.2 漏洞危害1.3 漏洞分类1.4 任意文件读取1.4.1 文件读取1.4.2 任意文件读取1.4.3 权限问题 1.5 任意文件下载1.5.1 一般情况1.5.2 PHP实现1.5.3 任意文件下载 2. 任意文件读取攻防2.1 路径过滤2.1.1 过…

引爆用户参与:消息重弹,让您的推送不再被忽略

在当前各大APP拉新促活成本居高不下的大背景下&#xff0c;如何稳定存量用户、提升用户粘性就显得尤为关键。从促销活动到个性化推荐&#xff0c;从互动通知到功能提醒&#xff0c;消息推送已成为各大APP连接存量用户和目标市场之间的桥梁&#xff0c;通过点击推送&#xff0c;…

springboot初试elasticsearch

引入依赖 elasticsearch的依赖版本与你elasticsearch要一致 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency> 索引库的操作 创建索引库 impo…

Visual Studio 2019下使用C++与Python进行混合编程——环境配置与C++调用Python API接口

前言 在vs2019下使用C与Python进行混合编程,在根源上讲&#xff0c;Python 本身就是一个C库&#xff0c;那么这里使用其中最简单的一种方法是把Python的C API来嵌入C项目中&#xff0c;来实现混合编程。当前的环境是&#xff0c;win10,IDE是vs2019,python版本是3.9&#xff0c…

LeetCode 刷题记录——从零开始记录自己一些不会的

1. 最多可以摧毁的敌人城堡数目 题意 思路 两层循环&#xff0c;太low了 用一个变量记录前一个位置 代码 class Solution { public:int captureForts(vector<int>& forts) {int ans 0, pre -1;for (int i 0; i < forts.size(); i) {if (forts[i] 1 || forts…

04、javascript 修改对象中原有的属性值、修改对象中原有属性的名字(两种方式)、添加对象中新属性等的操作

1、修改对象中原有的属性值 其一、代码为&#xff1a; // 想将 obj 中的 flag 值&#xff0c;根据不同的值来变化(即&#xff1a;修改对象中原有的属性值)&#xff1b; let obj {"port": "port_0","desc": "desc_0","flag&quo…