开发者

What does CG_INLINE do?

I was poking around the definitions for things like CGPoint for hints on how to create my own functions but I don't know the purpose of CG_INLINE. What is happening behind the scenes here?

CG_INLINE CGPoint
CGPointMake(CGFloat x, CGFloat y)
{
  CGPoint p; p.x = x; p.y = y; return p;
}

CG_INLINE CGSize
CGSizeMake(CGFloat width, CGFloat height)
{
  CGSize size; size.width = width; size.h开发者_开发问答eight = height; return size;
}


Inline functions are compiled into the call site, rather than being compiled as a single block of function code and call instructions issued when the function is used. With care, this provides a little more speed and greater numbers of cache hits. However, the history of inline in C and C++ is rocky, so this macro effectively provides a compiler independent static inline behaviour. Looking at the definition:

#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) */

So...

  1. For compilers providing __STDC_VERSION__ of an appropriate version (in this case >= C99), this means static inline (as C99 allows this natively)
  2. Similarly for Metrowerks Codewarrior or C++ compilers, which support inline natively.
  3. For GCCs not supporting C99, it resolves to static __inline__. The use of __inline__ is the GCC specific inline specifier for previous C standards where inline is unsupported : http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Alternate-Keywords.html.
  4. If all of these fail, it doesn't bother with inline - it's just static.

Why bother with all of these definitions? Because Apple, in their history, have been through a fair few compilers. In the days of yore, the Codewarrior C compiler was the tool of choice for users. Since OS X, Apple have been using Objective C and C++ via an (originally modifier) GCC. Recently, they're transitioning to clang. This macro covers all the cases (and, given how new Core Graphics is, I suspect is a modified version of an older macro).

However, many compilers will ignore inline annotations these days, as their optimisers are better than the hints provided by the programmer. In your own code, don't bother with it (in native form, or via this macro) unless you're really sure you need it (and have proven it useful via profiling). Of course, you may still want static - the above advice covers the inline behaviour.


CG_INLINE is a macro that is used to mark a method as an inline function. The exact syntax is (was ?) compiler dependent, and through preprocessor checks the correct one is chosen for your compiler.

For current GCCs, it should resolve to static inline.

The point of a function marked with inline is that the compiler may insert the equivalent of that function's body where the function was called, instead of making a (slightly more costly) function call. So if you have:

inline int foo(int a, int b)
{
   return a + b;
}

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

The compile then is allowed to internally transform it to:

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

This saves a function call which on some architectures might be costly and might be very noticeable for example when you're calling the function in a loop a few thousand times.

Note that it only means the compiler may do this transformation, it doesn't necessarily mean it does do it. Depends on compiler settings.


CG_INLINE is a #define for static inline. This causes the compiler to create the code for the function inline, rather that creating a function call on the stack. See here and here for more information.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜