繁体   English   中英

Objective-C类作为C指针类型

[英]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指针”。 这是有道理的,因为CFStringNSString是免费桥接的。

但它没有意义,因为错误消息特别提到了NSConstantString 所以git grep -w NSConstantString来看看它来自哪里。 您最终在lib/ast/ASTContext.cpp找到方法ASTContext::getCFConstantStringType lib/ast/ASTContext.cpp 此方法使用标识符NSConstantString创建结构类型声明,但它从不将声明添加到任何范围(它不调用PushOnScopeChainsAddDecl )。 因此, NSConstantString标识符可以出现在诊断中,但您无法在源代码中按名称访问该类型。 就编译器而言,在NSString.h声明的NSConstantString类型与此合成类型无关。

无论如何,重要的问题是为什么要覆盖__builtin___NSStringMakeConstantString ,你没有说。 如果是因为你想使用自己的常量字符串类,那么你就是错误的方式。

我不认为你可以覆盖该函数,因为它内置于编译器中。 如果要更改其含义,则需要修改编译器源代码。

另外,我认为编译器实际上并不使用该函数来创建Objective-C字符串文字。 运行git grep __builtin___NSStringMakeConstantString不会打开编译器生成调用的任何位置。 编译器处理@"string"在语法上lib/Parse/ParseObjc.cpplib/Sema/SemaExprObjC.cpp (寻找名为方法ParseObjCStringLiteral在这两个文件)。 编译器按名称查找NSConstantString类型(这意味着它应该从NSString.h头文件中获取一个)并创建一个具有该类型的ObjCStringLiteral实例。

您应该能够使用-fconstant-string-class命令行标志使其为常量字符串类型(而不是NSConstantString )查找不同的类,但我不知道它的效果如何。 这个问题暗示它可能不起作用。 即使它确实有效,我认为你被限制使用与NSConstantString相同的内存布局,在这种情况下,为什么还要使用不同的类呢?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM