Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c CG_内联做什么?_Objective C_Cocoa_Ios - Fatal编程技术网

Objective c CG_内联做什么?

Objective c CG_内联做什么?,objective-c,cocoa,ios,Objective C,Cocoa,Ios,我在翻阅有关CGPoint的定义,以获得如何创建自己函数的提示,但我不知道CG\u INLINE的用途。这里的幕后发生了什么 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 =

我在翻阅有关
CGPoint
的定义,以获得如何创建自己函数的提示,但我不知道
CG\u INLINE
的用途。这里的幕后发生了什么

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;
}

CG_INLINE是一个
#为
静态内联定义
。这会导致编译器为函数内联创建代码,而不是在堆栈上创建函数调用。有关详细信息,请参见和。

CG_INLINE
是一个宏,用于将方法标记为内联函数。确切的语法取决于编译器,并且通过预处理器检查为编译器选择了正确的语法

对于当前的GCC,它应该解析为
静态内联

标有
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);
}
这节省了一个函数调用,在某些体系结构上,该函数调用可能非常昂贵,并且可能非常明显,例如,当您在循环中调用该函数数千次时


请注意,这只意味着编译器可以执行此转换,但并不一定意味着它可以执行此转换。取决于编译器设置。

内联函数被编译到调用站点,而不是编译为单个函数代码块和使用函数时发出的调用指令。小心地,这将提供更快的速度和更多的缓存命中数。但是,在C和C++中,<>代码>内联的历史是不稳定的,因此这个宏有效地提供了一个编译器无关的代码>静态内联< /代码>行为。看看定义:

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

  • 对于提供适当版本(在本例中>=C99)的
    \uuu STDC\u VERSION\uuu
    的编译器,这意味着
    静态内联
    (因为C99本机允许)
  • 类似于MeMeReksCode战士或C++编译器,它们支持代码< >内联
  • 对于不支持C99的GCC,它解析为
    static\uuuuu inline\uuuu
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    是以前的C标准中不支持内联的特定于GCC的内联说明符:
  • 如果所有这些都失败了,它就不需要内联了——它只是
    静态的
  • 为什么要为所有这些定义而烦恼呢?因为苹果,在他们的历史上,已经通过了相当多的编译器。在过去,Codewarrior C编译器是用户的首选工具。自从OSX以来,苹果一直使用目标C和C++通过(原修改)GCC。最近,他们正在向叮当声过渡。这个宏涵盖了所有情况(考虑到新的核心图形,我怀疑它是旧宏的修改版本)


    然而,现在许多编译器将忽略内联注释,因为它们的优化程序比程序员提供的提示更好。在您自己的代码中,除非您确实需要它(并且已经通过评测证明它是有用的),否则不要麻烦它(以本机形式,或通过此宏)。当然,您可能仍然需要
    静态
    ——以上建议涵盖了
    内联
    行为。

    +1对于“在您自己的代码中,不要麻烦它(以本机形式,或通过此宏),除非您确实需要它(并通过评测证明它很有用)。”谢谢。我认为定义函数(相对于方法)仍然有用;这是真的吗?是的,函数(即纯C)可以比方法(目标C方法)更好,因为它们不会产生调用开销,而这种开销有时会随着目标C消息传递而增加。它们也更容易绑定到其他语言(并在其他纯C/++库中重用)。