【问题标题】:What is the use case of declaring functions methods within bodies other functions?在其他函数的主体中声明函数方法的用例是什么?
【发布时间】:2014-11-04 10:59:07
【问题描述】:

我在 FreeRTOS 源码中看到了这篇文章:

void vApplicationIdleHook( void )
{

    /* The simple blinky demo does not use the idle hook - the full demo does. */
    #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
    {
        extern void vFullDemoIdleHook( void );

        //* Implemented in main_full.c. */
        vFullDemoIdleHook();
    }
    #endif

}

为什么要声明这样的函数/方法?有什么好处?我在 Java 中也看到过类似的代码。

【问题讨论】:

  • 函数声明与Java如何做事无关。
  • 有可能,但不常见。多亏了这种可能性,我们才有了最麻烦的解析。
  • @user694733 Java 可以在方法中定义方法,不是吗?
  • @AtillaFiliz 这是函数声明,而不是定义
  • @AtillaFiliz void vApplicationIdleHook( void ) 从哪一行开始?在 C 语言中,源文件很长是很常见的。也许他们正在将一段代码重构为一个函数,只是懒得滚动到顶部。 :) 无论如何,代码质量低。

标签: c++ c


【解决方案1】:

我假设这是项目中唯一使用vFullDemoIdleHook 的地方,因此将声明和函数调用全部保留在这几行代码中是清晰简洁的。

将声明放在别处有什么好处?考虑替代方案...这可能是您更习惯看到的:

/* The simple blinky demo does not use the idle hook - the full demo does. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
extern void vFullDemoIdleHook( void );
#endif


void vApplicationIdleHook( void )
{

  /* The simple blinky demo does not use the idle hook - the full demo does. */
  #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
  {
    //* Implemented in main_full.c. */
    vFullDemoIdleHook();
  }
  #endif

}

我认为这样做没有任何好处

【讨论】:

  • 一个优点可能是它更“正常”,因此会减少混乱和浪费时间。
  • 我认为这个论点在这里不适用;没有人会对它的作用感到困惑。这只会让人们措手不及。
【解决方案2】:

我想说没有理由在函数内部声明函数,因为它给人的错误印象是它在某种程度上仅限于该函数,而实际上并非如此。 默认情况下,函数具有外部链接(除了您的代码专门为函数 vFullDemoIdleHook() 提供了 extern),声明内部函数应被视为一种不好的做法(但有效)。

原型应该在头文件中(如果没有头文件,则在源文件的顶部)。我会将声明移至main_full.h

 extern void vFullDemoIdleHook( void ); /* extern keyword is redundant here */

main_full.c:

void vApplicationIdleHook( void )
{
    /* The simple blinky demo does not use the idle hook - the full demo does. */
    #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
    {
        //* Implemented in main_full.c. */
        vFullDemoIdleHook();
    }
    #endif
}

除非您打算将相同的函数名称 vFullDemoIdleHook 用于不同的目的(这会很糟糕),否则您不需要有条件地 (#if) 声明函数原型。

【讨论】:

  • “因为它给人的错误印象是它在某种程度上仅限于该功能,而它不是”。你能解释一下你的意思吗?从 C99 开始,每个函数都必须在调用之前声明。
  • 即在另一个函数中声明一个函数的原型。
  • 如果我错了,请纠正我,但是这样的原型被它的范围(例如块)缩小了,并且这样的函数在其他地方是“不可调用的”(除非有更多的声明,例如在包含的头文件中或在所考虑的翻译单元内的任何功能之外)。这意味着这样的功能被有效地限制(从程序员的角度来看)这样的块(考虑我上面指出的 C99/C11 语义)。
  • 函数是外部的(除非另有限定)并且在所有翻译单元中可见。在所有 C 标准中都是如此。函数没有“块”概念。考虑这个example。现在,如果您取消注释对yetAnotherFunc() 的调用并将其定义为另一个翻译单元中的void yetAnotherFunc() { func(); },即使原型void func(void);main() 内,它也会按预期工作。
  • 但请注意,可见(根据您的想法)和实际可调用是两个不同的东西(至少在 C99/C11 中)。有块概念,但仅在声明的情况下。请注意,我没有谈到链接方面。在您的示例中,会出现编译错误,因为 yetAnotherFunc() 未在前翻译单元中的任何地方声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 1970-01-01
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
相关资源
最近更新 更多