《The _Pragma("once") vs include guards》

我写的issue原文:

标题:Consider changing include guards to pragma once.

We can use the _Pragma directive for header file guard.

example:

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_

change to

_Pragma("once")

There are several factors to support the lowcase file/directory name.

portability
Cross-platform problems will not occur, compiler implement standard, they will support it.
readability
Generally, if you just want to do some guard, you should not care about the name and the directory of this file. and the naming of the guard is yet another big question, nonstandard things always end up in a fight.
convenience
just copy & paste for the _Pragma("once"), here and there.

Computer industry set the standards, so does our company.

feel free to refer to
tencent cplusplus code standard, “2.2.【必须】 头文件保护”:
https://git.code.oa.com/standards/cpp#22%E5%BF%85%E9%A1%BB-%E5%A4%B4%E6%96%87%E4%BB%B6%E4%BF%9D%E6%8A%A4

image.png

More importantly, the _Pragma directive is the standard level in C++, instead of the a specific compiler extension like GCC's # pragma, which maximizes stability and compatibility.

see:


我写的wiki原文(工程标准 -> C++ Coding Guideline):

标题:The _Pragma("once") Guard

_Pragma操作符

在C/C++标准中,#pragma是一条预处理的指令(preprocessor directive)。简单地说,#pragma是用来向编译器传达语言标准以外的一些信息。举个简单的例子,如果我们在代码的头文件中定义了以下语句:

#pragma once

要达到与上例#pragma类似的效果,则只需要如下代码即可。

_Pragma("once");

而相比预处理指令#pragma,由于_Pragma是一个操作符,因此可以嵌套在宏中。我们可以看看下面这个例子:

#define CONCAT(x) PRAGMA(concat on #x)
#define PRAGMA(x) _Pragma(#x)
CONCAT( ..\concat.dir )

这里,CONCAT( ..concat.dir )最终会产生_Pragma(concat on "..concat.dir")这样的效果。而#pragma则不能在宏中展开,因此从灵活性上来讲,标准的 _Pragma具有更大的灵活性

注意,为什么强调“标准”,我指的是

_Pragma("once")

而不是

#pragma once

以上,可以看出,不管从可移植性、可读性、便利性,还是规范角度看,_Pragma("once")都有优势。使用新标准可以提高开发效率,用最自然的思维方式、最简单的代码,表达大量内容。

因为前者是语言层面的标准,而后者是编译器的扩展,可能在标准通过_Pragma操作符之前,GCC就已经实现了#pragma,这个时候,windows,macOS系统的编译器可能是不认识#pragma的,他可能是别的foo, bar。但是,标准通过之后,所有编译器都将遵循标准。

所以,使用标准,会是最通用的方式,也是我们的方式。

详见n3690.pdf:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

image.png

不过有观点认为,我们不该使用_Pragma("once"),因为编译器的实现有bug。(https://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards

我们确立一个标准,提高开发效率的同时,也要确认该标准是否稳定可用,为了防止引入未知的问题。

网上的资料不多,就直接看了下内核、编译器的实现。

早期存在的问题在于,比如foo.h -> /path/to/foo.h链接会共享相同的inode,导致编译器无法区分。(详见附录“内核实现分析”)

在问题相关的上下游,有如下若干事实:
编译器层面,gcc在3.4.0版本的时候已经修复了上述问题。(详见附录“编译器实现分析”)
开发者层面,绝大多数项目都不会存在上述问题。

这让我们相信标准,且相信标准的实现。

极端假设,即使编译器仍存在这个所谓的bug,并且我们刻意触发了,那么会不会有严重问题呢?答案是否定的。因为,它和ifndef造成的macro冲突问题是同一级别的,而且更容易在最早期的编译阶段被发现。换言之,既然你都可以接受ifndef,那么为什么不能接受_Pragma("once")呢,后者即便是在最邪恶的情况下,也不会比前者错得更多。

结论:我们可以使用标准的_Pragma操作符

大家已经将这个结论,作为我们的共识。在代码规范中已更新。

具体的编码,可以直接遵循规范:

如果存在ifndef头文件保护,那么麻烦进行如下替换:

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_

改成

_Pragma("once")

如果不存在,请直接使用

_Pragma("once")

内核实现分析(linux-5.7.0):

image.png

编译器实现分析(gcc-9.2.0):

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容