CG_INLINE是做什么的?

我在CGPoint的定义中寻找如何创build自己的函数的提示,但是我不知道CG_INLINE的用途。 这里幕后发生了什么?

 CG_INLINE CGPoint CGPointMake(CGFloat x, CGFloat y) { CGPoint p; px = x; py = y; return p; } CG_INLINE CGSize CGSizeMake(CGFloat width, CGFloat height) { CGSize size; size.width = width; size.height = height; return size; } 

内联函数被编译到调用站点中,而不是被编译成function代码和使用该函数时发出的调用指令的单个块。 小心,这提供了更多的速度和更多的caching命中。 但是,C和C ++中的inline历史是非常棘手的,所以这个macros有效地提供了一个独立于编译器的static inline行为。 看一下定义:

 #if !defined(CG_INLINE) # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L # define CG_INLINE static inline # elif defined(__MWERKS__) || defined(__cplusplus) # define CG_INLINE static inline # elif defined(__GNUC__) # define CG_INLINE static __inline__ # else # define CG_INLINE static # endif #endif /* !defined(CG_INLINE) */ 

所以…

  1. 对于提供适当版本的__STDC_VERSION__的编译器(在本例中为> = C99),这意味着static inline (因为C99本身允许)
  2. 对于Metrowerks Codewarrior或C ++编译器来说也是如此,它们本地支持inline
  3. 对于不支持C99的GCC,它parsing为static __inline__ 。 使用__inline__是以前C标准的GCC特定内联说明符,其中内联不受支持: http : //gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Alternate-Keywords.html 。
  4. 如果所有这些都失败了,那么就不用费心思了 – 这只是static

为什么要打扰所有这些定义? 因为苹果在历史上已经经历了一些公平的编译器。 在此之前,Codewarrior C编译器是用户的首选工具。 由于OS X,Apple通过(最初修改)GCC使用Objective C和C ++。 最近,他们正在过渡到叮当声。 这个macros涵盖了所有的情况(并且,鉴于新的Core Graphics是什么,我怀疑它是旧macros的修改版本)。

但是,现在很多编译器会忽略内联注释,因为它们的优化器比程序员提供的提示更好。 在你自己的代码中,除非你真的确定需要它(并且通过分析certificate它是有用的),否则不要打扰它(以本地forms或通过这个macros)。 当然,你可能仍然需要static – 上面的build议涵盖了inline行为。

CG_INLINE是一个用来将方法标记为内联函数的macros。 确切的语法是(是?)编译器依赖的,并且通过预处理器检查为你的编译器select了正确的语法。

对于当前的GCC,它应该parsing为static inline

inline标记的函数的一点是,编译器可以在调用该函数的地方插入该函数的主体的等价物,而不是进行(稍微更昂贵的)函数调用。 所以如果你有:

 inline int foo(int a, int b) { return a + b; } void bar(int a, int b) { NSLog(@"%d", foo(a, b)); } 

然后编译被允许内部转换为:

 void bar(int a, int b) { NSLog(@"%d", a + b); } 

这样可以节省一些函数调用,在某些体系结构中调用这个函数可能代价很高,例如在数千次循环中调用该函数时可能会非常明显。

请注意,这只意味着编译器可能会进行这种转换,但并不一定意味着它会这样做。 取决于编译器设置。

CG_INLINE是static inline#define 。 这会导致编译器为内联函数创build代码,而不是在堆栈上创build函数调用。 看到这里和这里的更多信息。