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.height = height; return size;
}
An inline function is one for which the compiler copies the code from the function definition directly into the code of the calling function rather than creating a separate set of instructions in memory. This eliminates call-linkage overhead and can expose significant optimization opportunities.
In an inline function, a function call is replaced by the actual program code. Most of the Inline functions are used for small computations. They are not suitable for large computing. An inline function is similar to a normal function. The only difference is that we place a keyword inline before the function name.
An Inline function is a kind of function that is declared with the keyword "inline" just before the function declaration. Once a function is declared inline, the compiler does not allocate any memory for this function, instead the compiler copies the piece of code virtually at the calling place at runtime.
In C, static means the function or variable you define can be only used in this file(i.e. the compile unit) So, static inline means the inline function which can be used in this file only.
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...
__STDC_VERSION__
of an appropriate version (in this case >= C99), this means static inline
(as C99 allows this natively)inline
natively.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.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With