关于C#:返回函数中的静态结构

return a static structure in a function

c89 海湾(海合会)性 P / < >

你好, P / < >

我someones软件维护和我找到了这个功能,returns的地址的静态结构。这应该让S级的静态会表示,它在全球的地址,所以英语的结构将可用直到terminates计划。 P / < >

1
2
3
4
5
6
7
8
DRIVER_API(driver_t*) driver_instance_get(void)
{
    static struct tag_driver driver = {
    /* Elements initialized here */
    };

    return &driver;
}

用像这样: P / < >

1
2
driver_t *driver = NULL;
driver = driver_instance_get();

可变的司机用实际生活的计划,直到它terminates。 P / < >

一些问题: P / < >

  • 它是很好的练习要做,像这样吗?
  • 也没有任何declaring都到它的静态外同步功能在文件级吗?
  • 为什么不通过它的记忆池中的功能和allocate记忆结构,这样的结构也declared上堆吗?
  • 许多谢谢为任何suggestions, P / < >


  • 只要您意识到任何修改函数返回指针的代码都在修改与其他获得相同指针的代码所引用的相同变量,这不是一个大问题。"只要"是一个相当重要的问题,但它是有效的。这通常不是最佳实践-例如,返回指向单个静态变量的指针的c函数(如asctime())不如将其结果放入用户提供的变量(尤其是在线程代码(函数不可重入)中)的函数容易使用。然而,在这种情况下,您似乎正在实现一个单例模式;您可能只需要一个"驱动程序"的副本,所以对我来说这看起来是合理的-但是我们需要更多关于用例的信息,然后再自言自语"这是非常错误的"。

  • 函数static和文件static变量之间没有太大的区别。不同之处在于实现代码(文件中的任何代码都可以访问文件静态变量;函数静态变量只能在一个函数中访问),而不是在使用者代码中。

  • "内存池"不是标准的C概念。一般来说,传递要由被调用函数初始化的结构可能更好,但这取决于上下文。正如它所代表的那样,就其设计目的而言,它是可以的。

  • 注意:代码最好写为:

    1
    driver_t *driver = driver_instance_get();

    优化器可能无论如何都会将代码优化到这一点,但是没有必要分配空值,然后立即重新分配。


  • 一般来说,不会。它使函数不可重入。它可以在代码作者真正知道他们在做什么的情况下与约束一起使用。

  • 在外部声明它将污染具有结构对象名称的文件级命名空间。由于不需要在其他任何地方直接访问该对象,因此在函数内部声明它更有意义。没有别的区别。

  • 在堆上分配?性能会受到影响。会发生内存碎片。调用程序将承担显式释放内存的任务。在可以避免的情况下强制用户使用动态内存通常不是一个好的实践。

    对于可重入实现,更好的方法是从外部传递指向目标结构的指针。这样,调用者就可以完全自由地以他们认为合适的方式分配接收者内存。

  • 当然,您在这里看到的只是一个类似于singleton的习语的C实现(很可能是,根据函数的名称判断)。这意味着函数每次都应该返回相同的指针,也就是说,所有调用方都应该通过返回的指针查看和共享相同的结构对象。而且,可能的话,您甚至可能期望修改同一个对象(假设没有并发性)。在这种情况下,您在这里看到的是一个全局变量的函数包装实现。所以,在这种情况下改变任何东西都会破坏目标。