您是否将模块特定功能声明为静态?

时间:2008-11-24 16:02:45

标签: c++ c static function

我认为将它们声明为静态是最佳做法,因为它使它们在模块外部不可见。

您对此有何看法?

13 个答案:

答案 0 :(得分:26)

对于C ++,比静态更好的是将它放在一个未命名的(匿名)命名空间中。这是防止全局命名空间污染的首选方法。

namespace {
void myLocalFunction() {
// stuff
}
}

答案 1 :(得分:9)

如果它真的是一个只有.c文件内部的函数,那么是的。它应该有助于避免污染全局命名空间。此外,我认为如果函数是静态的,编译器能够使用调用约定进行一些优化,因为它知道没有其他源文件需要知道如何调用它。这只适用于c,因为正如其他人所说,c ++有名称空间来解决这个问题。

答案 2 :(得分:2)

在C ++中,您应该使用匿名命名空间,如下所示:

// foo.cpp
namespace
{
   class Core { ... };
   void InternalFandango(Core *);
}

void SomeGloballyVisibleFunction()
{
   InternalFandango(&core);
}

优点:这也适用于结构/类声明。
在C中,只需将功能标记为“静态”。在C ++中也没有反对使用“静态”,但我学会了更喜欢命名空间,因为它是一个适用于所有声明的单一概念。

答案 3 :(得分:2)

有很多关于实施细节的内容,而不是关于概念的内容。

限制变量/函数等的范围确实是一个很好的做法。这是面向对象设计的基本概念 - 您希望将私有保密。这样,您的界面更清晰,代码维护更容易。你不会发现有一天会改变你认为是私人破坏编译的东西,因为项目的另一部分人喜欢你的功能并决定使用它。

答案 4 :(得分:2)

在C中,我将所有内容 - 函数和变量 - 在文件范围内保持静态,直到我可以证明它们在文件外是必要的。如果只有那个函数会使用它们并且它们不是太大,我会在函数中使事物静止。基本上,如果声明大于函数的其余部分,我可以将声明放在函数之外。当然,还有一个源文件提供的公共服务标题。

答案 5 :(得分:2)

同意。因此,静态函数的原型必须位于.c文件的顶部,而不是.h文件中。

答案 6 :(得分:1)

我认为C和C ++对static有不同的约束:在C中你没有命名空间而.c文件是你的模块,所以将所有非公共函数作为静态放入真的非常重要防止错误!

答案 7 :(得分:1)

关于我在C ++中使用“静态”的唯一可能有用的属性,即匿名命名空间不提供,是在GCC中有一个警告,你可以打开未使用的静态函数(一种形式的死代码)。对于匿名命名空间中未使用的函数,你不会得到它,所以在你不想要的情况下,你希望编译器在你停止使用函数时告诉你,就这样做。

答案 8 :(得分:1)

here之前提出了一个非常类似的问题。有一个边缘案例,声明函数static会导致行为与未命名的命名空间函数完全不同。查看我的answer

答案 9 :(得分:1)

在C代码中,默认情况下使您的函数保持静态。仅为其他模块需要的函数创建非静态函数和.h声明。

在C ++代码中,将文件本地的那些函数放入匿名命名空间使它们成为静态。至少在GNU编译器中,这将产生最佳和最小的代码,因为如果所有使用都是内联的,则不会写入任何函数。如果您打算将其内联,那么当然标记内联甚至比静态更好。

我不知道为什么g ++会将匿名命名空间中未调用的函数体写入输出中,但确实如此。具有隐藏可见性的功能似乎也显示出来;标记为隐藏符号,但仍在目标文件中生成未使用的代码块。 GCC可能不明白在这些情况下不需要代码。或者我错过了一些东西,总是可能的。

答案 10 :(得分:1)

如果您正在使用GCC,那么您应该查看可见性标记(有关完整讨论,请参阅http://gcc.gnu.org/wiki/Visibility)。

它会完全隐藏符号,而不是标记它们无法访问。这减少了符号表,并有助于减少链接时间。

不仅如此,它打开了更多内联的大门,如果这就是你所追求的。

答案 11 :(得分:-1)

如果通过'module'你只是指一个CPP文件,你可以将声明和定义放在CPP文件中。

答案 12 :(得分:-1)

在C ++中,你将这个函数声明为private:

class MyClass
{                           
public:                 
void publiclyAccessibleFunction();            
private:                
    void onlyAccesibleFromWithinTheClass();
int some_member_parameter;          
};

请注意onlyAccesibleFromWithinTheClass()功能。