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

网站美工如何做免费的网站推广方法

网站美工如何做,免费的网站推广方法,购物网站二级店铺mvc,做英剧网站的目的Chrome-base源码分析(2)之Macros模块 Author:Once Day Date:2024年6月29日 漫漫长路,才刚刚开始… 全系列文章请查看专栏: 源码分析_Once-Day的博客-CSDN博客 参考文档: macros - Chromium Code SearchChrome base 库详解:工…

Chrome-base源码分析(2)之Macros模块

Author:Once Day Date:2024年6月29日

漫漫长路,才刚刚开始…

全系列文章请查看专栏: 源码分析_Once-Day的博客-CSDN博客

参考文档:

  • macros - Chromium Code Search
  • Chrome base 库详解:工具类和常用类库_base::repeatingcallback-CSDN博客
  • For Developers (chromium.org)
  • 手动代码中包含C++20 __VA_OPT__错误的类函数宏-腾讯云开发者社区-腾讯云 (tencent.com)

文章目录

      • Chrome-base源码分析(2)之Macros模块
        • 1. 概述
        • 2. concat.h
        • 3. if.h
        • 4. is_empty.h
        • 5. remove_parens.h

1. 概述

chrome-base源码中macros模块是一个比较简单的模块,定义了一些简单的宏,有五个源文件,下面一一介绍。

2. concat.h

源码如下:

// A macro that expands to the concatenation of its arguments. If the arguments
// are themselves macros, they are first expanded (due to the indirection
// through a second macro). This can be used to construct tokens.
#define BASE_CONCAT(a, b) BASE_INTERNAL_CONCAT(a, b)// Implementation details: do not use directly.
#define BASE_INTERNAL_CONCAT(a, b) a##b

这个非常基础的关键字拼接宏,例如下面所示:

TEST(MacrosTest, Concat) {auto a = BASE_CONCAT(10, 20);std::cout << "a: " << a << std::endl;EXPECT_EQ(a, 1020);auto b = BASE_CONCAT(5000, 6000);std::cout << "b: " << b << std::endl;EXPECT_EQ(b, 50006000);
}
>>> a: 1020
>>> b: 50006000

BASE_CONCAT(10, 20)会输出1020,这是可以作为源码字面量的值,并不是"10" + "20" = "1020"这种字符串拼接。

3. if.h

源码如下:

// Given a `_Cond` that evaluates to exactly 0 or 1, this macro evaluates to
// either the `_Then` or `_Else` args. Unlike a real conditional expression,
// this does not support conditions other than `0` and `1`.
#define BASE_IF(_Cond, _Then, _Else) \BASE_CONCAT(BASE_INTERNAL_IF_, _Cond)(_Then, _Else)// Implementation details: do not use directly.
#define BASE_INTERNAL_IF_1(_Then, _Else) _Then
#define BASE_INTERNAL_IF_0(_Then, _Else) _Else

这段代码定义了一个名为BASE_IF的宏,用于实现编译期的条件选择功能。

宏接受三个参数:_Cond_Then_Else_Cond必须是一个计算结果为0或1的表达式。

根据_Cond的值,宏会将其展开为_Then_Else参数的内容。

宏的实现依赖于两个内部宏BASE_INTERNAL_IF_1BASE_INTERNAL_IF_0,它们分别选择_Then_Else参数。

通过巧妙的宏拼接,BASE_IF能够在编译期根据条件选择代码,而不会产生运行时开销。

例如下面所示:

TEST(MacrosTest, If) {auto a = BASE_IF(1, 10, 20);std::cout << "a: " << a << std::endl;EXPECT_EQ(a, 10);auto b = BASE_IF(0, 100, 200);std::cout << "b: " << b << std::endl;EXPECT_EQ(b, 200);
}
>>> a: 10
>>> b: 200
4. is_empty.h

源码如下:

// A macro that substitutes with 1 if called without arguments, otherwise 0.
#define BASE_IS_EMPTY(...) BASE_INTERNAL_IS_EMPTY_EXPANDED(__VA_ARGS__)
#define BASE_INTERNAL_IS_EMPTY_EXPANDED(...) \BASE_INTERNAL_IS_EMPTY_INNER(_, ##__VA_ARGS__)
#define BASE_INTERNAL_IS_EMPTY_INNER(...) \BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED(__VA_ARGS__, 0, 1)
#define BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED(e0, e1, is_empty, ...) is_empty

这段代码定义了一个名为BASE_IS_EMPTY的宏,用于检查宏是否被传递了参数。如果宏调用时没有传递任何参数,则展开为1,否则展开为0。

宏的实现依赖于几个内部宏:

  • BASE_INTERNAL_IS_EMPTY_EXPANDED: 对传入的参数进行展开,并在前面添加一个下划线。
  • BASE_INTERNAL_IS_EMPTY_INNER: 在展开后的参数列表前添加固定的参数。
  • BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED: 根据参数个数选择结果,如果只有固定参数则说明原宏调用时没传参数,返回1,否则返回0。

通过这种巧妙的宏展开和参数匹配,BASE_IS_EMPTY能够在编译期判断宏调用时是否传递了参数。下面是一些示例:

BASE_IS_EMPTY()      // 展开为 1
BASE_IS_EMPTY(a)     // 展开为 0 
BASE_IS_EMPTY(a, b)  // 展开为 0

这个宏常用于其他宏定义中,用于根据传参情况生成不同的代码,或者进行静态断言检查宏参数等。比如可以写一个字符串连接的宏:

#define CONCAT(a, ...) \BASE_IF(BASE_IS_EMPTY(__VA_ARGS__), a, CONCAT_INNER(a, __VA_ARGS__))// 当只传一个参数时直接返回,多个参数时递归拼接  

在windows上编译时,需要传入/Zc:preprocessor参数,以确保C++预编译器的行为和GCC一致。

windows上默认行为比较特殊,如下:

// windows行为
BASE_IS_EMPTY(a, b, c, d)
>>> BASE_INTERNAL_IS_EMPTY_EXPANDED(a, b, c, d)
>>> BASE_INTERNAL_IS_EMPTY_INNER(_, a, b, c, d)
>>> BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED(_, a, b, c, d, 0, 1)
e0 =  _, a, b, c, d  //因为windows默认把__VA_ARGS__当成整体了,这与GCC行为存在差异
e1 =  0
e2 =  1

GCC的默认行为如下:

// GCC行为
BASE_IS_EMPTY(a, b, c, d)
>>> BASE_INTERNAL_IS_EMPTY_EXPANDED(a, b, c, d)
>>> BASE_INTERNAL_IS_EMPTY_INNER(_, a, b, c, d)
>>> BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED(_, a, b, c, d, 0, 1)
e0 =  _
e1 =  a # GCC上, 默认是按照展开位置来抉择
e2 =  b
......

虽然GCC的行为是正常展开了变量,参数和位置能一一对应,但是依旧不满足逻辑,如下:

// BASE_IS_EMPTY() 应该返回 1
BASE_IS_EMPTY() => BASE_INTERNAL_IS_EMPTY_INNER(_) => BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED(_, 0, 1)
>>> 所以is_empty == 1
// BASE_IS_EMPTY(a, b, c, d) 应该返回0
BASE_IS_EMPTY(a, b, c, d) => BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED(_, a, b, c, d, 0, 1)
>>> 所以is_empty == b, 这并不符合预期

所以需要对命令稍加改造:

// 在Windows上使用msvc时, 需要/Zc:preprocessor参数, 否则宏处理会有问题
// reference: https://stackoverflow.com/questions/77700691/getting-va-opt-to-be-recognized-by-visual-studio
// 对于多个参数的情况, __VA_OPT__会将逗号和参数一起处理, 然后通过#__VA_ARGS__转换成一个字符串// A macro that substitutes with 1 if called without arguments, otherwise 0.
#define BASE_IS_EMPTY(...) BASE_INTERNAL_IS_EMPTY_EXPANDED(__VA_ARGS__)
#define BASE_INTERNAL_IS_EMPTY_EXPANDED(...) \BASE_INTERNAL_IS_EMPTY_INNER("_" __VA_OPT__(,) #__VA_ARGS__)
#define BASE_INTERNAL_IS_EMPTY_INNER(...) \BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED(__VA_ARGS__, 0, 1)
#define BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED(e0, e1, is_empty, ...) is_empty

这里通过"_" __VA_OPT__(,) #__VA_ARGS__来操作,将__VA_ARGS__当成整体变成字符串,那么就有:

BASE_IS_EMPTY(a, b, c, d) => BASE_INTERNAL_IS_EMPTY_INNER_EXPANDED("_", "a, b, c, d", 0, 1)
>>> is_empty == 0, 符合预期
5. remove_parens.h

源码如下:

// A macro that removes at most one outer set of parentheses from its arguments.
// If the arguments are not surrounded by parentheses, this expands to the
// arguments unchanged. For example:
// `BASE_REMOVE_PARENS()` -> ``
// `BASE_REMOVE_PARENS(foo)` -> `foo`
// `BASE_REMOVE_PARENS(foo(1))` -> `foo(1)`
// `BASE_REMOVE_PARENS((foo))` -> `foo`
// `BASE_REMOVE_PARENS((foo(1)))` -> `foo(1)`
// `BASE_REMOVE_PARENS((foo)[1])` -> `(foo)[1]`
// `BASE_REMOVE_PARENS(((foo)))` -> `(foo)`
// `BASE_REMOVE_PARENS(foo, bar, baz)` -> `foo, bar, baz`
// `BASE_REMOVE_PARENS(foo, (bar), baz)` -> `foo, (bar), baz`
#define BASE_REMOVE_PARENS(...)                                            \BASE_IF(BASE_INTERNAL_IS_PARENTHESIZED(__VA_ARGS__), BASE_INTERNAL_ECHO, \BASE_INTERNAL_EMPTY())                                           \__VA_ARGS__#define BASE_INTERNAL_IS_PARENTHESIZED(...) \BASE_IS_EMPTY(BASE_INTERNAL_EAT __VA_ARGS__)
#define BASE_INTERNAL_EAT(...)
#define BASE_INTERNAL_ECHO(...) __VA_ARGS__
#define BASE_INTERNAL_EMPTY()

这段代码定义了一个名为BASE_REMOVE_PARENS的宏,用于移除宏参数最外层的一对括号(如果有的话)。如果参数没有被括号包围,则宏展开后的结果与原参数相同。

宏的实现利用了之前提到的BASE_IS_EMPTY和BASE_IF宏,以及一些辅助的内部宏:

  • BASE_INTERNAL_IS_PARENTHESIZED: 判断参数是否被括号包围。它将参数传递给BASE_INTERNAL_EAT宏,如果参数有括号,那么括号内的内容会被BASE_INTERNAL_EAT"吃掉",导致BASE_IS_EMPTY的结果为1,否则为0。
  • BASE_INTERNAL_EAT: 接受任意参数,但不做任何事情。
  • BASE_INTERNAL_ECHO: 原样返回传入的参数。
  • BASE_INTERNAL_EMPTY: 不接受任何参数,也不返回任何内容。

BASE_REMOVE_PARENS的实现可以分为两步:

  • 使用BASE_INTERNAL_IS_PARENTHESIZED判断参数是否有括号。
  • 根据第一步的结果,使用BASE_IF选择BASE_INTERNAL_ECHO(有括号)或BASE_INTERNAL_EMPTY(无括号),并将其展开。

最后,将原始的__VA_ARGS__附加在展开的结果之后。如果参数有括号,那么展开的空宏会移除最外层括号,否则原始参数不变。

下面是一个示例演示:

BASE_REMOVE_PARENS((foo))
>>> BASE_IF(BASE_INTERNAL_IS_PARENTHESIZED((foo))), BASE_INTERNAL_ECHO, BASE_INTERNAL_EMPTY()) (foo)
>>> BASE_IF(BASE_IS_EMPTY(BASE_INTERNAL_EAT ((foo))), BASE_INTERNAL_ECHO, BASE_INTERNAL_EMPTY()) (foo)
//这里__VA_ARGS__外面存在括号,则会执行BASE_INTERNAL_EAT宏,从而变成空,条件选择BASE_INTERNAL_ECHO
>>> BASE_INTERNAL_ECHO (foo)
>>> foo // 去掉了外面一层括号

文章转载自:
http://wanjiaprosperous.kjrp.cn
http://wanjiasaccharine.kjrp.cn
http://wanjiasybarite.kjrp.cn
http://wanjiasnubbingly.kjrp.cn
http://wanjiasunfish.kjrp.cn
http://wanjiaskullduggery.kjrp.cn
http://wanjiacravenhearted.kjrp.cn
http://wanjiaracket.kjrp.cn
http://wanjiaskua.kjrp.cn
http://wanjiafilelist.kjrp.cn
http://wanjiaapologetical.kjrp.cn
http://wanjiarecalcitrant.kjrp.cn
http://wanjiapermeably.kjrp.cn
http://wanjiaisostemony.kjrp.cn
http://wanjiafenestration.kjrp.cn
http://wanjiahisself.kjrp.cn
http://wanjiawarner.kjrp.cn
http://wanjiaentocranial.kjrp.cn
http://wanjiabisulphide.kjrp.cn
http://wanjianbg.kjrp.cn
http://wanjianarco.kjrp.cn
http://wanjiastridence.kjrp.cn
http://wanjiapolysyllabic.kjrp.cn
http://wanjiametempirical.kjrp.cn
http://wanjiamedfly.kjrp.cn
http://wanjiaredbird.kjrp.cn
http://wanjiareluctant.kjrp.cn
http://wanjiasubgroup.kjrp.cn
http://wanjiagayal.kjrp.cn
http://wanjiapilus.kjrp.cn
http://wanjiapergameneous.kjrp.cn
http://wanjiapectoral.kjrp.cn
http://wanjiaflowage.kjrp.cn
http://wanjiaeroticism.kjrp.cn
http://wanjiaensanguined.kjrp.cn
http://wanjiarufous.kjrp.cn
http://wanjiapreclinical.kjrp.cn
http://wanjialoudspeaker.kjrp.cn
http://wanjiaintegrallty.kjrp.cn
http://wanjiagymnosperm.kjrp.cn
http://wanjiadisplume.kjrp.cn
http://wanjiaacetylcholinesterase.kjrp.cn
http://wanjiadefeasible.kjrp.cn
http://wanjialovesickness.kjrp.cn
http://wanjiaequipe.kjrp.cn
http://wanjiascroop.kjrp.cn
http://wanjiaferity.kjrp.cn
http://wanjiaorthodonture.kjrp.cn
http://wanjiamohawk.kjrp.cn
http://wanjiadebunk.kjrp.cn
http://wanjiacosmine.kjrp.cn
http://wanjiaorthoepist.kjrp.cn
http://wanjiametacompilation.kjrp.cn
http://wanjialockless.kjrp.cn
http://wanjiapronatalist.kjrp.cn
http://wanjiaunsocial.kjrp.cn
http://wanjiafaint.kjrp.cn
http://wanjiasillabub.kjrp.cn
http://wanjiadragnet.kjrp.cn
http://wanjiaplatyrhynchous.kjrp.cn
http://wanjiaalpenglow.kjrp.cn
http://wanjiarollerdrome.kjrp.cn
http://wanjiasemifinalist.kjrp.cn
http://wanjialanolin.kjrp.cn
http://wanjiahypodermal.kjrp.cn
http://wanjiadrumlin.kjrp.cn
http://wanjiaurushiol.kjrp.cn
http://wanjiavoetsek.kjrp.cn
http://wanjiaundervest.kjrp.cn
http://wanjiainsularity.kjrp.cn
http://wanjiapointy.kjrp.cn
http://wanjiaapiarist.kjrp.cn
http://wanjiaunsight.kjrp.cn
http://wanjiabattery.kjrp.cn
http://wanjiaquestionably.kjrp.cn
http://wanjiaareola.kjrp.cn
http://wanjiaecocatastrophe.kjrp.cn
http://wanjiabondsman.kjrp.cn
http://wanjiaregularise.kjrp.cn
http://wanjiacommissarial.kjrp.cn
http://www.15wanjia.com/news/128592.html

相关文章:

  • python网站开发源码建站宝盒
  • 什么是网络设计冗余设计泰州seo网站推广
  • 手机网站做跳转好吗青岛seo计费
  • 多个网站备案吗百度seo分析工具
  • 力洋深圳做网站公司长沙网站优化推广
  • 中国建设银行龙卡信用卡网站百度竞价调价软件
  • 网站测试域名301怎么做网络推广专员岗位职责
  • wordpress导航站模板百度关键词排名突然消失了
  • 南京网站制作哪家专业推广公司是做什么的
  • 网站建设的目标是什么 提供了哪些栏目百度搜索推广的定义
  • 网站怎么做qq登录界面上海网站制作开发
  • 内容营销公司企业网站seo方案
  • 下载好了网站模板怎么开始做网站企业网页
  • 南宁做网站开发的公司有哪些竞价外包推广
  • 毕设代做网站招聘怎么做网站赚钱
  • 天津 网站开发seo优化总结
  • 东鹏拼奖网站怎么做网页优化怎么做
  • wordpress v4.9.5seocms
  • 香港空间做的网站接受大陆监管么上海百度推广官网
  • wordpress是不是一定要买服务器泉州百度seo公司
  • php如何搭建网站后台全渠道营销案例
  • 西安网站设计试听北京疫情最新数据
  • 网站建设学校网站深圳seo优化排名公司
  • 碑林网站制作seo网站首页推广
  • 宝山做网站公司培训机构学校
  • wordpress 加cdn搜索引擎优化是指什么
  • 杭州的服装网站建设有什么功能
  • 长春商城网站建设技成培训网
  • 做网站分辨率一般多少怎么出售友情链接
  • 北京哪家做网站好网站关键词搜索排名优化