是由编译器优化的字符串形成吗? [英] Is string formation optimized by the compiler?
问题描述
我试图回答另一个关于==运算符的问题,我创建了这个代码:
NSString * aString = @ 你好;
NSString * bString = aString;
NSString * cString = @Hello;
if(aString == bString)
NSLog(@CHECK 1);
if(bString == cString)
NSLog(@CHECK 2);
if([aString isEqual:bString])
NSLog(@CHECK 3);
if([aString isEqual:cString])
NSLog(@CHECK 4);
NSLog(@%i,aString);
NSLog(@%i,bString);
NSLog(@%i,cString);
但结果令人惊讶:
等于[6599:10b]检查1
等于[6599:10b]检查2
等于[6599:10b]检查3
等[6599: 10b] CHECK 4
Equal [6599:10b] 8240
Equal [6599:10b] 8240
Equal [6599:10b] 8240
解决方案有明显的字符串正在进行,至少在一个单一的编译单元。我建议您通过
man gcc
进行简短的访问,在此期间您访问所有使用字符串。你会发现几个与文字NSString
和他们的免费桥接对象直接相关的选项,CFString
s:
-
-fconstant-string-class
= class-name 设置用于实例化@...
文字的类的名称。除非你使用GNU运行时,它默认为NSConstantString
。 (如果你不知道自己是不是,你不是。) -
-fconstant-cfstrings
strong>启用CFSTR(...)
时使用内置函数创建CFString
>
您可以使用 -fwritable-strings
禁用C字符串文字的唯一化已弃用。我不能想出一个选项的组合,将停止在$ Objective-C文件中 NSString
字面量的统一。 (任何人想要和Pascal字符串文字说话?)
你看到 -fconstant-cfstrings
code> CFString.h 定义 CFSTR()
宏用于创建 CFString
literals:
#ifdef __CONSTANT_CFSTRINGS__
#define CFSTR(cStr)((CFStringRef)__builtin___CFStringMakeConstantString cStr))
#else
#define CFSTR(cStr)__CFStringMakeConstantString(cStr)
#endif
如果你看一下 __ CFStringMakeConstantString() //www.opensource.apple.com/source/CF/CF-299.33/String.subproj/CFString.crel =nofollow noreferrer> CFString.c
,你会看到函数确实使用非常大的 CFMutableDictionary
执行uniquing:
if((result =(CFStringRef)CFDictionaryGetValue(constantStringTable,cStr))){
__CFSpinUnlock(& _CFSTRLock);
}
//。 。 。
return result;
另请参阅对问题的回复,字符串常量和字符串之间的区别是什么?
I was trying to answer another question about the == operator and I created this code:
NSString *aString = @"Hello";
NSString *bString = aString;
NSString *cString = @"Hello";
if (aString == bString)
NSLog(@"CHECK 1");
if (bString == cString)
NSLog(@"CHECK 2");
if ([aString isEqual:bString])
NSLog(@"CHECK 3");
if ([aString isEqual:cString])
NSLog(@"CHECK 4");
NSLog(@"%i", aString);
NSLog(@"%i", bString);
NSLog(@"%i", cString);
But was surprised at the results:
Equal[6599:10b] CHECK 1
Equal[6599:10b] CHECK 2
Equal[6599:10b] CHECK 3
Equal[6599:10b] CHECK 4
Equal[6599:10b] 8240
Equal[6599:10b] 8240
Equal[6599:10b] 8240
Is there some compiler trickery going on here?
There is clearly string uniquing going on, at least within a single compilation unit. I recommend you take a brief tour through man gcc
during which you visit all uses of "string". You'll find a few options that are directly relevant to literal NSString
s and their toll-free-bridged counterparts, CFString
s:
-fconstant-string-class
=class-name sets the name of the class used to instantiate@"..."
literals. It defaults toNSConstantString
unless you're using the GNU runtime. (If you don't know if you are, you aren't.)-fconstant-cfstrings
enables use of a builtin to createCFString
s when you writeCFSTR(...)
.
You can disable uniquing for C string literals using -fwritable-strings
, though this option is deprecated. I couldn't come up with a combination of options that would stop the uniquing of NSString
literals in an Objective-C file. (Anyone want to speak to Pascal string literals?)
You see -fconstant-cfstrings
coming into play in CFString.h
's definition of the CFSTR()
macro used to create CFString
literals:
#ifdef __CONSTANT_CFSTRINGS__
#define CFSTR(cStr) ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))
#else
#define CFSTR(cStr) __CFStringMakeConstantString("" cStr "")
#endif
If you look at the implementation of the non-builtin __CFStringMakeConstantString()
in CFString.c
, you'll see that the function does indeed perform uniquing using a very large CFMutableDictionary
:
if ((result = (CFStringRef)CFDictionaryGetValue(constantStringTable, cStr))) {
__CFSpinUnlock(&_CFSTRLock);
}
// . . .
return result;
See also responses to the question, "What's the difference between a string constant and a string literal?"
这篇关于是由编译器优化的字符串形成吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!