#pragma GCC poison 的一个有趣特性
来源:互联网 发布:p2p网络借贷入罪 编辑:程序博客网 时间:2024/06/10 05:21
今天做程序设计的作业时又看见一题,让使用char*实现一个"String"类(与std::string相似),但是要求上传的String类的.cpp实现代码却没有禁用string,导致一些函数直接可以先转换为string对象,用string提供的函数实现以后再转换回char*……然后就想应该可以用#pragma GCC poison来实现禁用string,但是同时也想到,因为#define和#pragma GCC poison都是预处理器来处理的,会不会使用#define能实现绕过#pragma GCC poison呢?实验表明在一些情况下是可以的,如下面两段代码
#include<iostream>#pragma GCC poison string#define youknow stringint main() { std::youknow str; return 0;}
#include<iostream>#define youknow string#pragma GCC poison stringint main() { std::youknow str; return 0;}
差别仅仅在于互换了#pragma GCC poison与#define,真是奇怪……一搜索,发现原来这是#pragma GCC poison的一个特性
在http://gcc.gnu.org/onlinedocs/gcc-3.2/cpp/Pragmas.html里是这么说的
If a poisoned identifier appears as part of the expansion of a macrowhich was defined before the identifier was poisoned, it willnotcause an error. This lets you poison an identifier without worryingabout system headers defining macros that use it.
如果被“染毒”的标识符在被“染毒”之前作为宏定义出现,那么它就不会造成error。后面的解释能看懂但不能理解……(头文件会用宏来定义标识符吗?)先放着
于是我又改了一下,变成这样
#pragma GCC poison string#include<iostream>#define youknow stringint main() { std::youknow str; return 0;}
一编译马上就扑街了,首当其冲的是stringfwd.h
又看了下stringfwd.h,发现有一行(37行)#pragma GCC system_header,感觉这应该就是之前所说的system header了,于是去看了http://gcc.gnu.org/onlinedocs/gcc-3.2/cpp/System-Headers.html#System%20Headers,又试了一下自己写的头文件
// GCC pragma teststd::string test;
#include<iostream>#define youknow string#include"test.h"#pragma GCC poison stringint main() { std::youknow str; return 0;}本来想着头文件里面要加#pragma GCC system_header才不会报错,结果顺利编译,看来这个特性所要保护的system header不是指#pragma GCC system_header所声明的那种,感觉有点误导。
而且连这也能成功编译
#include<iostream>#define youknow stringstd::string test;#pragma GCC poison stringint main() { std::youknow str; return 0;}这根本不是macro expansion,只是一段很裸的语句好吗!……
说不定实际上只是出现在#pragma GCC poison以后的标识符才会报错
结论:#pragma GCC poison应该加在所include的系统头文件后面,且尽量靠前
预处理器好强大
我好菜
感觉不补一下C和C++的各种reference都不行啊
pragma的reference后面的内容都是一边写博文一边测试的,不信拉倒
话说写文章的这个过程好像对于探究有点促进作用
本著作係採用創用 CC 姓名標示-非商業性 3.0 美國 授權條款授權.
- #pragma GCC poison 的一个有趣特性
- Glusterfs的编译选项 #pragma GCC poison system popen
- 有趣的Swift特性
- gcc pragma
- GCC 4.0 的特性
- 一个有趣的项目,可以把TC2.0的代码移到gcc上
- 一个有趣的游戏
- 一个有趣的故事
- 看到一个有趣的
- 一个有趣的故事
- 一个有趣的现象
- 一个有趣的数学公式
- 一个有趣的javascript
- 一个有趣的程序
- 一个有趣的学习方法
- 一个有趣的框架
- 一个有趣的问题
- 一个有趣的查找
- Android 进程生命周期 Process Lifecycle
- 第二次上机赛解题报告及标程
- 集合中线程安全
- Android内存管理、监测剖析
- 新浪微博的 【微博登陆按钮】部署在页面上后,登陆后,按钮始终未变
- #pragma GCC poison 的一个有趣特性
- 1. Struts2的工作机制
- 打包c#程序(续)
- poj 1753-Flip Game
- mysql-5.6.16-win32免安装配置方法
- UVa 10566 Crossed Ladders 平面几何结论,二分答案
- 关于UrlHttpConnection.setRequestProperty()的调用顺序问题的验证
- Makefile(1) --- .PHONY
- java的工具类collections例子