[英]Objective-C class as C pointer type
clang builtin function "__builtin_NSStringMakeConstantString"
返回const NSConstantString*
,
這不是Objective-C可保留對象。
我想用我自己的函數替換這個函數,但似乎沒有辦法NSConstantString* as non-Objective-C pointer in Objective-C++
聲明NSConstantString* as non-Objective-C pointer in Objective-C++
(你可以使用struct NSConstnatString*
在Objective-C中struct NSConstnatString*
)。 我確定,這個函數返回NSConstantString
,因為以下兩行輸出PK16NSConstantString
:
printf("%s\n", typeid(__builtin___NSStringMakeConstantString("foo")).name());
printf("%s\n", typeid(const NSConstantString*).name());
每當我嘗試執行以下代碼時,我都會收到錯誤“無法初始化'const NSConstantString *'類型的變量,其值為'const NSConstantString *'的rvalue:
const NSConstantString* a = __builtin___NSStringMakeConstantString("foo");
如果我添加橋接強制轉換,一切正常,所以這意味着NSConstantString *作為“原始”Objective-C指針返回,但我必須創建一個返回與“__builtin _NSStringMakeConstantString” 完全相同的結果的函數 ,所以我沒有選項使用__bridge。
每當我嘗試從函數返回const NSConstantString *時,它總是作為Objective-C可保留指針返回,似乎沒有辦法將它聲明為C指針,除了這個:
typedef typeof __builtin___NSStringMakeConstantString("") rawNSConstnatStringPtr;
所以問題是:有沒有辦法聲明一個不可獲得的NSConstantString *指針(不使用typeof)?
你認為_builtin__NSStringMakeConstant
返回NSConstantString
,因為編譯器會欺騙你。
我建議你查看clang源代碼: http : //llvm.org/docs/GettingStarted.html#git-mirror
然后搜索源代碼: git grep __builtin___NSStringMakeConstantString
。 您發現它在include/clang/Basic/Builtins.def
如下:
BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
第二個參數是函數簽名,文件頂部的注釋解釋了它的含義。 FC*
部分是返回類型,表示“常量CFString const指針”。 這是有道理的,因為CFString
和NSString
是免費橋接的。
但它沒有意義,因為錯誤消息特別提到了NSConstantString
。 所以git grep -w NSConstantString
來看看它來自哪里。 您最終在lib/ast/ASTContext.cpp
找到方法ASTContext::getCFConstantStringType
lib/ast/ASTContext.cpp
。 此方法使用標識符NSConstantString
創建結構類型聲明,但它從不將聲明添加到任何范圍(它不調用PushOnScopeChains
或AddDecl
)。 因此, NSConstantString
標識符可以出現在診斷中,但您無法在源代碼中按名稱訪問該類型。 就編譯器而言,在NSString.h
聲明的NSConstantString
類型與此合成類型無關。
無論如何,重要的問題是為什么要覆蓋__builtin___NSStringMakeConstantString
,你沒有說。 如果是因為你想使用自己的常量字符串類,那么你就是錯誤的方式。
我不認為你可以覆蓋該函數,因為它內置於編譯器中。 如果要更改其含義,則需要修改編譯器源代碼。
另外,我認為編譯器實際上並不使用該函數來創建Objective-C字符串文字。 運行git grep __builtin___NSStringMakeConstantString
不會打開編譯器生成調用的任何位置。 編譯器處理@"string"
在語法上lib/Parse/ParseObjc.cpp
和lib/Sema/SemaExprObjC.cpp
(尋找名為方法ParseObjCStringLiteral
在這兩個文件)。 編譯器按名稱查找NSConstantString
類型(這意味着它應該從NSString.h
頭文件中獲取一個)並創建一個具有該類型的ObjCStringLiteral
實例。
您應該能夠使用-fconstant-string-class
命令行標志使其為常量字符串類型(而不是NSConstantString
)查找不同的類,但我不知道它的效果如何。 這個問題暗示它可能不起作用。 即使它確實有效,我認為你被限制使用與NSConstantString
相同的內存布局,在這種情況下,為什么還要使用不同的類呢?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.