2011-03-10 31 views
8

我想有我在我的.c文件中定义之前声明静态函数:函数声明中的静态关键字在函数定义中可能会丢失?

//file a.c version 1 
static int foo(); 
... 
static int foo() 
{ 
... 
} 

然而,似乎我可以离开static关键字出来的函数定义和我没有得到任何编译器警告...例如

//file a.c version 2 
static int foo(); 
... 
int foo() 
{ 
... 
} 

我正确地假设这两种形式是完全一样的吗?
如果是这样,为什么这种差异是允许的,我应该使用哪种形式?

+0

我认为他/她做运动,不写一个真正的大计划。我的意见,首先谷歌这种类型的问题,因为它是如此微不足道。 – 2011-03-10 14:51:33

+1

非常感谢Erik和AProgrammer回答这个问题!为什么在未来的声明/定义中能够省略静态关键字是可取的 - 在我看来,这会让人感到困惑而不会增加任何好处。 – Arrakis 2011-03-10 15:24:11

回答

7

是7.1.1/6

没有存储类说明符在命名空间范围内声明的名称有外部链接,除非它有内部联系,因为先前的声明,并且未声明const

参见7.1.1/7

+0

这正是我读到的:)在C++ 0x FCD中出现了一个转变7.1.1/6已经变成7.1.1/7(对于那些感兴趣的人)。措辞保持一致。 – 2011-03-10 14:57:03

+0

@Matthieu,我们交叉张贴... – AProgrammer 2011-03-10 15:02:42

+0

你在哪里找到这个? :/ – sami1592 2016-02-12 08:34:34

1

静态 - 在此上下文中 - 仅影响范围,当您声明静态函数时它具有文件范围。因此,您可以通过尝试从其他来源访问该功能来轻松检查它是否相同。

这样,我们避免对编译器语言等的讨论

3

7.1.1/7:连续 声明对于给定的实体应 同意暗示

的联系。也就是说,在给定范围内,每个声明 声明相同的 对象名称或相同的重载 函数名称应暗示相同的 链接。

7.1.1/6:(感谢史蒂夫 - 这也是需要的答案是明确的)

没有存储类说明符的命名空间范围 声明的名称有 外部链接,除非它具有 内部链接,因为前面的 声明并且规定它不是 声明为const。声明为const 且未明确声明为extern 的对象具有内部链接。

是的,这两个是一样的。

然而,这是无效的:

int foo(); 

static int foo() { 
    return 0; 
} 
+1

..以及他们在提问者案例中同意的原因是7.1.1/6:“在没有存储类别说明符的名称空间范围内声明的名称具有外部链接,除非它由于先前的声明而具有内部链接”。他们出于同样的原因不同意你的榜样。 – 2011-03-10 14:56:38

+0

之前插入了一些东西,n3225的第7个是C++ 03的6个。 – AProgrammer 2011-03-10 15:00:06

0

实施例中的静态属性改变能见度到编译单元。这允许在不同的文件中为不同的目的使用相同的名称。你应该只使用一次静态。如果你有一个原型,你必须在这里做。

当你要求C++你不应该使用静态的,而是匿名命名空间,使symbold私人的编译单元:

namespace { 
    int foo(); 
} 

void bar() 
{ 
    foo(); 
} 
0

一点题外话,C++提供了static一种更好的选择。您还可以使用具名命名空间在这里

例,

namespace 
{ 
    void f() 
    { 
    } 
} 

看到这些:

Superiority of unnamed namespace over static?
Why an unnamed namespace is a "superior" alternative to static?

+0

我不觉得它(所以)功能优越。它允许更多的声明(类/类型定义),所以使用它也用于函数和常量使统一的语法(并删除关键字的一些重载),但“静态”更简洁。 – 2011-03-10 14:59:10

+0

虽然当然,你可以使用*既*命名空间*和*静态。 – Lundin 2011-03-10 15:20:11

+0

此上下文中的'static'关键字在某些版本的C++ 0x草稿中被宣告已过时。然后,这一决定被撤销,并被废除。特别是对于函数,当声明函数“静态”时,某些编译器比使用未命名的名称空间时有更好的诊断。事实上,在某些编译器中,'static'关键字确实会影响编译器针对该特定的自由函数所做的决定(优化器),而这些自由函数在未命名的名称空间中声明相同的函数时不会执行。 – 2011-03-10 15:41:31