ObjectiveC测试,如果int是长还是不/ CGFloat的是float或double [英] ObjectiveC test if int is long or not / CGFloat is float or double
问题描述
苹果公司现在要求所有iOS code是32/64位二元。这是伟大的 - 除了有他们的一些图书馆的不完全支持的两重性
Apple now requires all iOS code to be 32/64 bit dualistic. That's great - except there's a few of their libraries that don't fully support the duality.
例如。一个项目使用NSScanner,支持scanInteger(正确的),但没有scanCGFloat - 而不是你要scanFloat或scanDouble(中文codeD的方法名!)
e.g. one project uses NSScanner, which supports "scanInteger" (correct) but no "scanCGFloat" - instead you have to "scanFloat" or "scanDouble" (encoded in the method names!).
更新:NSScanner比我认识一个厉害的例子;它需要指针作为ARGS。
UPDATE: NSScanner is a nastier example than I realised; it takes pointers as args.
- (BOOL)scanFloat:(float *)result;
- (BOOL)scanDouble:(double *)result;
...啊。
这影响了一大堆东西 - 另一个例子就是math.h中(类似:浮动VS双恩是函数名codeD),虽然你至少可以切换到tgmath.h和摆脱类型是,在该名愚蠢。
It affects a whole bunch of stuff - another example is math.h (similarly: float vs double is encoded in function names), although there you can at least switch to tgmath.h and get rid of the "type-is-in-the-name" silliness.
什么是正确的,一般情况下,解决这个问题的?
What's the correct, general, solution to this problem?
推荐答案
C11引入了一个新的功能一般的选择,它可以被用来
让编译器选择合适的方法,这取决于 CGFloat的
的类型。
C11 has introduced a new feature "Generic selection" that can be used to
let the compiler choose the right method, depending on the type of CGFloat
.
@implementation NSScanner (MyCategory)
-(BOOL) myScanCGFloat:(CGFloat *)cgFloatValue
{
return _Generic(*cgFloatValue,
double: [self scanDouble:(double *)cgFloatValue],
float: [self scanFloat:(float *)cgFloatValue]);
}
@end
注:
- 的
_Generic
关键字在C11标准的6.5.1.1一般选择(描述的 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf )。另一种描述是在这里:
http://www.robertgamble.net/2012/01/c11-generic -selections.html 。 - 选择匹配code通过的编译的,而不是在运行时。 完成
- 选择检查
CGFloat的
是浮动
兼容或双击
不如果当前目标架构是32位或64位。 - 该解决方案不依赖于任何preprocessor宏。
- 为x code 5.0.2,锵支持
_Generic
关键字,即使在默认GNU99模式。我没有测试过早期X code /锵版本。
- The
_Generic
keyword is described in "6.5.1.1 Generic selection" of the C11 standard (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf). Another description is here: http://www.robertgamble.net/2012/01/c11-generic-selections.html. - Selecting the matching code is done by the compiler, not at runtime.
- The selection checks if
CGFloat
is compatible tofloat
ordouble
, not if the current target architecture is 32-bit or 64-bit. - This solution does not depend on any preprocessor macros.
- As of Xcode 5.0.2, Clang supports the
_Generic
keyword, even in the default GNU99 mode. I have not tested earlier Xcode/Clang versions.
previous答案:的一种可能的解决办法是不要模仿 CGFloat的定义
并让preprocessor选择正确的版本:
Previous answer: One possible solution would be do mimic the definition of CGFloat
and let the preprocessor choose the correct version:
CGFloat f;
#if __LP64__
[scanner scanDouble:&f];
#else
[scanner scanFloat:&f];
#endif
或者你定义自定义宏:
Or you define a custom macro:
#if __LP64__
#define scanCGFloat scanDouble
#else
#define scanCGFloat scanFloat
#endif
// ...
CFFloat f;
[scanner scanCGFloat:&f];
另外,使用一个临时变量:
Alternatively, use a temporary variable:
double tmp;
[scanner scanDouble:&tmp];
f = tmp;
这篇关于ObjectiveC测试,如果int是长还是不/ CGFloat的是float或double的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!