在 C 中使用静态函数和变量的原因

发布于 2024-09-04 01:50:23 字数 693 浏览 8 评论 0原文

我想知道在 C 语言中使用 static 关键字作为文件中变量的范围限制。

我认为构建 C 程序的标准方法是:

  • 有一堆定义的 C 文件函数和变量,可能受 static 限制范围。
  • 有一堆 h 文件声明相应 c 文件的函数和可能的变量,供其他 c 文件使用。私有函数和变量不会在 h 文件中发布。
  • 每个 c 文件都单独编译为 o 文件。
  • 所有 o 文件都链接在一起到一个应用程序文件。

如果变量没有在 h 文件中发布,我认为将 gobal 声明为静态的有两个原因:

  • 一是为了可读性。告知未来的读者(包括我自己),变量不会在任何其他文件中访问。
  • 第二个是防止另一个 c 文件将变量重新声明为 extern。我认为链接器不喜欢同时是 externstatic 的变量。 (我不喜欢文件将其他人拥有的变量重新声明为 extern 的想法,这样可以吗?)

还有其他原因吗?

static 函数也是如此。如果原型没有在 h 文件中发布,其他文件无论如何都可能不会使用该函数,那么为什么要定义它static呢? 我可以看到同样的两个原因,但仅此而已。

I wonder about the use of the static keyword as scope limiting for variables in a file, in C.

The standard way to build a C program as I see it is to:

  • have a bunch of c files defining functions and variables, possibly scope limited with static.
  • have a bunch of h files declaring the functions and possibly variables of the corresponding c file, for other c files to use. Private functions and variables are not published in the h file.
  • every c file is compiled separately to an o file.
  • all o files are linked together to an application file.

I see two reasons for declaring a gobal as static, if the variable is not published in the h file anyway:

  • one is for readability. Inform future readers including myself that a variable is not accessed in any other file.
  • the second is to prevent another c file from redeclaring the variable as extern. I suppose that the linker would dislike a variable being both extern and static. (I dislike the idea of a file redeclaring a variable owned by someone else as extern, is it ok practice?)

Any other reason?

Same goes for static functions. If the prototype is not published in the h file, other files may not use the function anyway, so why define it static at all?
I can see the same two reasons, but no more.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

绝不放开 2024-09-11 01:50:23

当您谈论通知其他读者时,请将编译器本身视为读者。如果将变量声明为static,则可能会影响优化的启动程度。

static 变量重新定义为extern 是不可能的,但编译器会(像往常一样)给你足够的绳子来吊死你自己。

如果我在一个文件中写入 static int foo; 并在另一个文件中写入 int foo;它们将被视为不同的变量,尽管它们具有相同的名称和type - 编译器不会抱怨,但稍后尝试读取和/或调试代码时您可能会感到非常困惑。 (如果我在第二种情况下编写 extern int foo; ,除非我在其他地方声明一个非静态 int foo; ,否则链接将失败。)

全局变量很少出现在头文件中,但当它们这样做时,应该将它们声明为 extern。如果不是,根据您的编译器,您将面临包含该标头的每个源文件都将声明其自己的变量副本的风险:最好的情况是这会导致链接失败(多重定义的符号),最坏的情况会导致一些令人困惑的遮蔽情况。

When you talk about informing other readers, consider the compiler itself as a reader. If a variable is declared static, that can affect the degree to which optimizations kick in.

Redefining a static variable as extern is impossible, but the compiler will (as usual) give you enough rope to hang yourself.

If I write static int foo; in one file and int foo; in another, they are considered different variables, despite having the same name and type - the compiler will not complain but you will probably get very confused later trying to read and/or debug the code. (If I write extern int foo; in the second case, that will fail to link unless I declare a non-static int foo; somewhere else.)

Global variables rarely appear in header files, but when they do they should be declared extern. If not, depending on your compiler, you risk that every source file which includes that header will declare its own copy of the variable: at best this will cause a link failure (multiply-defined symbol) and at worst several confusing cases of overshadowing.

死开点丶别碍眼 2024-09-11 01:50:23

当您声明静态函数时,对该函数的调用是“近调用”,理论上它的性能比“远调用”更好。你可以谷歌一下了解更多信息。 是我通过简单的谷歌搜索找到的。

When you declare a static function the call to the function is a "near call" and in theory it performs better than a "far call". You can google for more information. This is what I found with a simple google search.

战皆罪 2024-09-11 01:50:23

通过在文件级别声明变量static(函数内的static有不同的含义),您可以禁止其他单元访问它,例如,如果您尝试在另一个单元内使用该变量(用extern声明),链接器找不到这个符号。

By declaring a variable static on file level (static within function has a different meaning) you forbid other units to access it, e.g. if you try to the variable use inside another unit (declared with extern), linker won't find this symbol.

等待我真够勒 2024-09-11 01:50:23

如果将全局变量声明为静态,编译器有时可以比不声明为静态时进行更好的优化。因为编译器知道无法从其他源文件访问该变量,所以它可以更好地推断代码正在执行的操作(例如“此函数不会修改此变量”),这有时会导致生成更快的代码。很少有编译器/链接器可以跨不同的翻译单元进行此类优化。

If a global variable is declared static, the compiler can sometimes make better optimizations than if it were not. Because the compiler knows that the variable cannot be accessed from other source files, it can make better deductions about what your code is doing (such as "this function does not modify this variable"), which can sometimes cause it to generate faster code. Very few compilers/linkers can make these sorts of optimizations across different translation units.

攒眉千度 2024-09-11 01:50:23

如果您在文件 ac 中声明变量 foo 而不将其设为静态,并在文件 bc 中声明变量 foo 而不将其设为静态,则两者都自动为 extern,这意味着如果您初始化这两个变量,并分配相同的内存位置(如果没有),则链接器可能会抱怨不要抱怨。期待调试代码的乐趣。

如果您在文件 ac 中编写函数 foo () 而不将其设为静态,并在文件 bc 中编写函数 foo () 而不将其设为静态,则链接器可能会抱怨,但如果没有这样做,则所有对 foo () 的调用都将调用相同的功能。期待调试代码的乐趣。

If you declare a variable foo in file a.c without making it static, and a variable foo in file b.c without making it static, both are automatically extern which means the linker may complain if you initialise both, and assign the same memory location if it doesn't complain. Expect fun debugging your code.

If you write a function foo () in file a.c without making it static, and a function foo () in file b.c without making it static, the linker may complain, but if it doesn't, all calls to foo () will call the same function. Expect fun debugging your code.

花伊自在美 2024-09-11 01:50:23

我最喜欢的静态用法是能够存储我不必注入或创建要使用的对象的方法,在我看来,私有静态方法总是有用的,而公共静态方法你必须花更多时间思考你正在做些什么来避免疯狂苏格兰人所定义的那样,给自己套太多绳子,结果不小心把自己吊死了!

我喜欢为我的大多数项目保留一个 Helper 类的文件夹,这些项目主要由静态方法组成,可以快速高效地快速完成任务,不需要任何对象!

My favorite usage of static is being able to store methods that I wont have to Inject or create an object to use, the way I see it is, Private Static Methods are always useful, where public static you have to put some more time in thinking of what it is your doing to avoid what crazyscot defined as, getting your self too much rope and accidentally hanging ones self!

I like to keep a folder for Helper classes for most of my projects that mainly consist of static methods to do things quickly and efficiently on the fly, no objects needed!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文