在另一个函数内部的函数前置声明

5

代码优先:

void foo(int x)
{
    void bar(int);  //is this forward-decl legal?
    bar(x);
}

void bar(int x)
{
    //do stuff
}

在上面的代码中,foo 调用了 bar。通常情况下,我会将 bar 的前向声明放在 foo 外面,就像这样:
void bar(int);
void foo(int x) 
{
    bar();
}

首先,我认为将 bar 的前向声明放在 foo 内部是可以的,对吗?

其次,考虑这种情况,如果 bar 是一个像这样的 static 函数:

static void bar(int x)
{
    //do stuff
}

那么我应该如何前向声明它?我的意思是,前向声明应该带有还是不带 static


如果您在使用C++,则问题中不应该有 "c" 标签,而应该使用未命名的命名空间而不是 static 关键字。如果您在使用C,则问题中不应该有 "c++" 标签,而应将前向声明标记为 static - ruakh
1
@ruakh:使用 static 并没有被弃用,尽管一些人仍然坚称已经过时。static 和匿名命名空间各有各的优点。 - Ben Voigt
@BenVoigt,优点是什么?比如说? - Alcott
3
@Alcott 写道:“不要膨胀外部名称表,这意味着链接器需要做更少的工作。C++03 中未命名命名空间的最大优点是它与模板参数兼容,但在 C++11 中,它们不再需要外部链接。” - Ben Voigt
@BenVoigt:谢谢您提供的信息。(为了所有像我一样遇到了这个持久性声明并对Ben Voigt的评论感到惊讶的读者,事实是,C++11的一些工作草案曾经表示,在命名空间范围内声明对象时“static”已被弃用,但该声明后来被删除。) - ruakh
2个回答

7
  1. 在另一个函数中放置前向声明是合法的。但这个声明只能在该函数中使用。同时,它会使用所在函数的命名空间,因此请确保匹配。

  2. 标准规定:“对于给定实体的连续声明所暗示的链接必须一致。”(第7.1.2节)。因此,原型必须也是静态的。然而,在另一个函数中放置具有静态链接的函数的原型似乎根本不被允许。“块内不能有静态函数声明”(同一节)。


那么简单来说,如果barstatic的话,我不能在foo内前向声明bar,对吗? - Alcott
根据我对标准的理解,是正确的。建议使用Comeau try-it-out进行测试,他们在标准方面拥有接近完美的兼容性(好吧,针对C++03,他们正在开发C++11版本)。 - Ben Voigt

4

是的,把前向声明放在函数内部是可以的。只要编译器在你调用该函数之前已经看到了它,它所在的位置并不重要。你也可以在命名空间中进行函数的前向声明。然而,原型的作用域是有限制的:

int blah() {
    { void foo(); }

    foo(); // error: foo not declared
}

其次,您只需要在原型上加上static,否则编译器会抱怨bar被声明为extern(所有原型都被隐式地声明为extern,除非它们通过例如static的显式标记而明确指定)。请注意,static函数原型不能出现在函数内部。

“静态函数原型不能出现在函数内部”这句话的意思是,如果 barstatic 的话,那我就不能在 foo 内部前置声明 void bar(int); 或者 static void bar(int);,是这个意思吗? - Alcott
你不能在不同的命名空间中前向声明函数。 - Ben Voigt
@Alcott 你不能在 foo 内前向声明 static void bar(int); - Seth Carnegie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接