如何在Objective-C中编写“全局”内联函数(使用C语法)

时间:2022-09-07 20:13:08

Assuming I'm including a header file in my precompiled header that includes a bunch of inline functions to be used as helpers wherever needed in any of the project's TUs -- what would be the correct way to write those inlines?

假设我在我的预编译头中包含了一个头文件,其中包含了一堆内联函数,在项目的任何一个项目中都需要作为助手使用,那么如何正确地编写这些代码呢?

1) as static inlines? e.g.:

1)静态内联吗?例如:

static inline BOOL doSomethingWith(Foo *bar)
{
   // ...
}

2) as extern inlines? e.g.:

2)见习内联吗?例如:

in Shared.h

在Shared.h

extern inline BOOL doSomethingWith(Foo *bar);

in Shared.m

在Shared.m

inline BOOL doSomethingWith(Foo *bar)
{
   // ...
}

My intention with inlines is to:

我的意图是:

  • make the code less verbose by encapsulating common instructions
  • 通过封装通用指令,使代码更简洁
  • to centralize the code they contain to aid with future maintenance
  • 集中它们所包含的代码以帮助将来的维护
  • to use them instead of macros for the sake of type safety
  • 为了类型安全而使用它们而不是宏
  • to be able to have return values
  • 才能有返回值

So far I have only seen variant 1) in the wild. I have read (sadly can't find it anymore) that variant 1) does not accurately move the inline function's body into the callers but rather creates a new function, and that only extern inline ensures that kind of behavior.

到目前为止,我只在野外见过变种人。我读过(遗憾的是再也找不到它了)变式1并没有准确地将内联函数的主体移动到调用者中,而是创建了一个新的函数,并且只有外部内联才能确保这种行为。

2 个解决方案

#1


5  

make the code less verbose by encapsulating common instructions

通过封装通用指令,使代码更简洁

Non-inline functions do that as well...

非内联函数也可以做到这一点……

to centralize the code they contain to aid with future maintenance

集中它们所包含的代码以帮助将来的维护

then you should have non-inline functions, don't you think?

那么你应该有非内联函数,你不觉得吗?

to use them instead of macros for the sake of type safety

为了类型安全而使用它们而不是宏

to be able to have return values

才能有返回值

those seem OK to me.

这些对我来说还可以。


Well, when I write inline functions, I usually make them static - that's typically how it's done. (Else you can get all sorts of mysterious linker errors if you're not careful enough.) It's important to note that inline does not affect the visibility of a function, so if you want to use it in multiple files, you need the static modifier.

当我写内联函数时,我通常让它们是静态的——这就是它的典型做法。(如果你不够细心的话,你可能会遇到各种各样的链接错误。)需要注意的是,内联不会影响函数的可见性,所以如果想在多个文件中使用它,需要使用静态修饰符。

An extern inline function does not make a lot of sense. If you have only one implementation of the function, that defeats the purpose of inline. If you use link-time optimization (where cross-file inlining is done by the linker), then the inline hint for the compiler is not very useful anyway.

外部内联函数没有多大意义。如果函数只有一个实现,这就违背了内联的目的。如果您使用的是链接时间优化(linker所做的跨文件内联),那么对于编译器的内联提示就不是很有用了。

only extern inline insures that kind of behavior.

只有extern内联确保了这种行为。

It doesn't "ensure" anything at all. There's no portable way to force inlining - in fact, most modern compilers ignore the keyword completely and use heuristics instead to decide when to inline. In GNU C, you can force inlining using the __attribute__((always_inline)) attribute, but unless you have a very good reason for that, you shouldn't be doing it.

它根本不能“保证”任何事情。没有强制内联的可移植方法——事实上,大多数现代编译器完全忽略关键字,而是使用启发式来决定何时内联。在GNU C中,您可以使用__attribute__((always_inline))属性强制内联,但除非您有很好的理由,否则您不应该这么做。

#2


5  

Skipping whether you should be inlining at all for the reasons you give, the standard way to inline in Cocoa is to use the predefined macro NS_INLINE - use it either in the source file using the function or in an imported header. So your example becomes:

忽略您是否应该在所有的原因中内联,在Cocoa中内联的标准方法是使用预定义的宏NS_INLINE -在源文件中使用该函数,或者在导入的头文件中使用。举个例子你就变成:

NS_INLINE BOOL doSomethingWith(Foo *bar)

For GCC/Clang the macro uses static and the always_inline attribute.

对于GCC/Clang,宏使用静态和always_inline属性。

Most (maybe all) compilers won't inline extern inline as they operate on a single compile unit at a time - a source file along with all its includes.

大多数(可能是所有)编译器不会内联的,因为它们一次只对一个编译单元进行操作——一个源文件及其所有的包含。

#1


5  

make the code less verbose by encapsulating common instructions

通过封装通用指令,使代码更简洁

Non-inline functions do that as well...

非内联函数也可以做到这一点……

to centralize the code they contain to aid with future maintenance

集中它们所包含的代码以帮助将来的维护

then you should have non-inline functions, don't you think?

那么你应该有非内联函数,你不觉得吗?

to use them instead of macros for the sake of type safety

为了类型安全而使用它们而不是宏

to be able to have return values

才能有返回值

those seem OK to me.

这些对我来说还可以。


Well, when I write inline functions, I usually make them static - that's typically how it's done. (Else you can get all sorts of mysterious linker errors if you're not careful enough.) It's important to note that inline does not affect the visibility of a function, so if you want to use it in multiple files, you need the static modifier.

当我写内联函数时,我通常让它们是静态的——这就是它的典型做法。(如果你不够细心的话,你可能会遇到各种各样的链接错误。)需要注意的是,内联不会影响函数的可见性,所以如果想在多个文件中使用它,需要使用静态修饰符。

An extern inline function does not make a lot of sense. If you have only one implementation of the function, that defeats the purpose of inline. If you use link-time optimization (where cross-file inlining is done by the linker), then the inline hint for the compiler is not very useful anyway.

外部内联函数没有多大意义。如果函数只有一个实现,这就违背了内联的目的。如果您使用的是链接时间优化(linker所做的跨文件内联),那么对于编译器的内联提示就不是很有用了。

only extern inline insures that kind of behavior.

只有extern内联确保了这种行为。

It doesn't "ensure" anything at all. There's no portable way to force inlining - in fact, most modern compilers ignore the keyword completely and use heuristics instead to decide when to inline. In GNU C, you can force inlining using the __attribute__((always_inline)) attribute, but unless you have a very good reason for that, you shouldn't be doing it.

它根本不能“保证”任何事情。没有强制内联的可移植方法——事实上,大多数现代编译器完全忽略关键字,而是使用启发式来决定何时内联。在GNU C中,您可以使用__attribute__((always_inline))属性强制内联,但除非您有很好的理由,否则您不应该这么做。

#2


5  

Skipping whether you should be inlining at all for the reasons you give, the standard way to inline in Cocoa is to use the predefined macro NS_INLINE - use it either in the source file using the function or in an imported header. So your example becomes:

忽略您是否应该在所有的原因中内联,在Cocoa中内联的标准方法是使用预定义的宏NS_INLINE -在源文件中使用该函数,或者在导入的头文件中使用。举个例子你就变成:

NS_INLINE BOOL doSomethingWith(Foo *bar)

For GCC/Clang the macro uses static and the always_inline attribute.

对于GCC/Clang,宏使用静态和always_inline属性。

Most (maybe all) compilers won't inline extern inline as they operate on a single compile unit at a time - a source file along with all its includes.

大多数(可能是所有)编译器不会内联的,因为它们一次只对一个编译单元进行操作——一个源文件及其所有的包含。