#pragma GCC poison 的一個有趣特性
今天做程式設計的作業時又看見一題,讓使用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 string int main() { std::youknow str; return 0; }
#include<iostream>
#define youknow string
#pragma GCC poison string
int main() {
std::youknow str;
return 0;
}
差別僅僅在於互換了#pragma GCC poison與#define,真是奇怪……一搜索,發現原來這是#pragma GCC poison的一個特性
If a poisoned identifier appears as part of the expansion of a macrowhich was defined before the identifier was poisoned, it willnot
如果被“染毒”的識別符號在被“染毒”之前作為巨集定義出現,那麼它就不會造成error。後面的解釋能看懂但不能理解……(標頭檔案會用巨集來定義識別符號嗎?)先放著
於是我又改了一下,變成這樣
#pragma GCC poison string #include<iostream> #define youknow string int main() { std::youknow str; return 0; }
一編譯馬上就撲街了,首當其衝的是stringfwd.h
// GCC pragma test
std::string test;
#include<iostream>
#define youknow string
#include"test.h"
#pragma GCC poison string
int main() {
std::youknow str;
return 0;
}
本來想著標頭檔案裡面要加#pragma GCC system_header才不會報錯,結果順利編譯,看來這個特性所要保護的system header不是指#pragma GCC system_header所宣告的那種,感覺有點誤導。
而且連這也能成功編譯
#include<iostream>
#define youknow string
std::string test;
#pragma GCC poison string
int 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 的一個有趣特性
今天做程式設計的作業時又看見一題,讓使用char*實現一個"String"類(與std::string相似),但是要求上傳的String類的.cpp實現程式碼卻沒有禁用string,導致一些函式直接可以先轉換為string物件,用string提供的函式實現以後再轉換回cha
pragma GCC poison GCC編譯遮蔽不安全函式
收集不安全的c函式,使用預編譯屬性禁止這些函式在專案原始碼中使用1.poison.h#ifndef __POISON_H_ #define __POISON_H_ #ifdef __cplusplus extern "C"{ #endif /* __cplusplus */
三大關系數據庫字段值超長的一個有趣對比
ins works 關系 created mys 數據源 rec alt mapping 三大關系數據庫字段值超長的一個有趣對比 在開發中,我們可能會遇到插入字段值超長的情況,前陣子遇到這樣一個案例,結果一對比後發現一個有趣的現象,如果插入字段值超長,ORACLE、SQ
一個有趣的邏輯漏洞
情況 任務 有趣 提供商 很多 減少 一個 有趣的 做的 漏洞存在於一個外包服務提供商做的遊戲形式的內網系統。 其中,有一項功能為發布懸賞任務,金幣從自己現有金幣中扣。 這一處存在競爭條件,並發漏洞。 在短時間內發布 無數個 懸賞任務,因為競爭條件的存在,在金幣只有5個的情
#pragma GCC system_header用法
osi 手冊 mat clu because lin however director ebr 在看公司公共庫的頭文件中發現了:#pragma GCC system_header一行,以前沒有見過這種用法,在網上查了一下,解釋如下: 從#pragma GCC system
VID 與 PVID 的簡單概述,附上一個有趣案例
vlan PVID VID 重要前提,交換機內部的幀都是會打tag的 PVID:port-based vlan id pvid是交換機上的概念,說的是進入該端口的報文如果沒有打vlan id就按pvid的值打上 PVID是基於端口的VLAN ID,一個端口可以屬於多個vlan(trunk 口),
關於JAVA多線程的一個有趣的現象
有趣的 決定 sleep zed sync end AR 但是 執行 模擬一個售票系統,或者銀行取錢。 class 銀行{ synchronized getmoney(){ //這裏要sleep,為了延緩速度。 } } class 顧客 extend
HDU6438 Buy and Resell 解題報告(一個有趣的貪心問題的嚴格證明)
include 目前 users 更新 完全 計算 解題報告 tput 有一個 寫在前面 此題是一個很容易想到的貪心題目,但是正確性的證明是非常復雜的。然而,目前網上所有題解並未給出本題貪心算法的任何正確性證明,全部僅停留在描述出一個貪心算法。本著對算法與計算機科學的熱愛
一個有趣的小知識-church計數
style 小知識 知識 code lam pre pan bsp spa (define zero (lambda(f) (lambda(x)x))) (define (add-1 n) (lambda(f)(lambda(x)(f((n f)x))))
給18小萌新的一個有趣的小問題,取石子問題
題目描述: 現在地上橫著一排放了N堆石頭(N是偶數),每一堆石頭的個數不確定(但是總數和為奇數)。 然後兩個人輪流取石頭,規則是一次只能取一堆,而且只能取首位,最後誰拿到的石頭多誰取勝,請問如果你先手的話,你是否有一個必勝的策略? 題解: 答案當然是有的,那麼這個思路是怎麼樣的呢
Oracle DB 12.2(12cR2)的一個新特性:硬解析失敗的SQL語句(需要符合一定條件)列印到alert_sid.log中.
How to Identify Hard Parse Failures (Doc ID 1353015.1)Bug 16945190 - Diagnostic enhancement to dump parse failure information automatically (Doc ID 1694519
Oracle DB 12.2(12cR2)的一個新特性:硬解析失敗的SQL語句(需要符合一定條件)打印到alert_sid.log中.
erro p s doc oracl 12c ica oracle fail err How to Identify Hard Parse Failures (Doc ID 1353015.1)Bug 16945190 - Diagnostic enhancement to
一個有趣的足球賽推理題及本人的推理
以下是一場足球賽成績表: 場數:該隊總共比過的場數 勝 :該隊勝利的場數 敗 :該隊失敗的場數 平手:該隊平手的場數 進球:該隊在所有比賽中進球數總合 失球:該隊在所有比賽中讓對方進球數總合 積分:勝加2分,平手加1分,敗加0分 已知,下面這張成績表沒有一個數字是正確的
一個有趣的非同步時序邏輯電路設計例項 ——MFM調製模組設計筆記
本文從本人的163部落格搬遷至此。 MFM是改進型頻率調製的縮寫,其本質是一種非歸零碼,是用於磁介質硬碟儲存的一種調製方式。調製規則有兩句話,即兩個翻轉條件: 1、為1的碼元在每個碼元的正中進行一次翻轉;為0的碼元不翻轉。 2、對連續兩個為0的碼元,則在第一個為0的碼元結束時翻轉一次;單個的0碼元不翻轉
移動開發----biu,biu,一個有趣的EditText
BiuEditText biu,biu,一個有趣的EditText 直接看效果 and Usage Step 1 三個類: ONE(主VIEW): package me.james.biuedittext;
對於prim的一個有趣但有點奇怪的想法
prim演算法找最小生成樹適用於無向圖,對於有向加權圖會產生錯誤。 比如 1->2,8 1->3,8 2->3,4 3->2,3 最小生成樹1->2->3 而不是3->2; 這是因為2,3之間相互的邊在prim演算法中無法判斷,或者根本意識不到3-&g
bootstrap應用+一個有趣的css
前端學習網站:https://www.freecodecamp.org Bootstrap的使用 匯入boortstrap css檔案 eg: <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/boo
遇到一個有趣的邏輯漏洞
遇到個有趣的邏輯漏洞,和大家分享一下。 某系統資料庫是mysql。user表有個code欄位,型別是int(11),這個欄位是儲存一個隨機數,用來找回密碼的時候做驗證,預設值是0。 找回密碼時候的步驟是,首先填寫自己郵箱,接收重置密碼的郵件,點選連結,訪問如下程式
一個有趣的C程式碼
之前寫的一個小程式碼,但只在Windows下有效果: #include <stdio.h> #include <stdlib.h> #define decode(p,r,i,n,t,f) r##f##r##i##t##p #define puts d
一個有趣的小例子,帶你入門協程模組-asyncio
一個有趣的小例子,帶你入門協程模組-asyncio 上篇文章寫了關於yield from的用法,簡單的瞭解非同步模式,【https://www.cnblogs.com/c-x-a/p/10106031.html】這次讓我們通過一個有趣例子帶大家瞭解asyncio基本使用。 目標效果圖 基本