如何声明静态变量但不定义它

发布于 2024-08-14 07:02:38 字数 510 浏览 4 评论 0原文

有时我们需要预先声明一个静态变量然后使用它。 但是这个声明的变量名可能是错误的,编译器无法检测到,哎呀!

示例:

/* lots of codes */
static some_type some_name; /* pre-declaration */
                            /* but it may define "some_name" */
/* use some_name */

/* lots of codes */

static some_type someName = initialization; /* definition */
/* use someName */

/* lots of codes */

“some_name”和“someName”不同,我们在开始时使用了错误的变量。 如果预声明语句没有定义任何东西,编译器就会检测到错误。

那么,如何声明静态变量而不定义它呢?如何将预声明更改为新的预声明,以使编译器可以检测到错误的名称?

Some times we need to pre-declare a static variable and then use it.
But the variable name of this declaration may be wrong, and the compiler can not detect it, oops!

Example:

/* lots of codes */
static some_type some_name; /* pre-declaration */
                            /* but it may define "some_name" */
/* use some_name */

/* lots of codes */

static some_type someName = initialization; /* definition */
/* use someName */

/* lots of codes */

"some_name" and "someName" are different, we use a wrong variable at the begin.
If the pre-declaration statement does not define any thing, the compiler will detect the mistake.

So, how to declare a static variable but not define it? How can I change the pre-declaration to a new one which makes compiler can detects wrong names?

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

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

发布评论

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

评论(7

逆蝶 2024-08-21 07:02:38

gcc 将在您描述的情况下发出警告:

./x.c:3010: warning: 'someName' defined but not used

解决方案:执行您当前正在执行的操作,但不要忽略编译器警告;)

编辑:

使用您的更新的问题:不,我不相信有一种方法可以简单地声明静态变量(而不定义它)。

常见的解决方案是确保所有全局范围变量仅声明一次,并在需要时使用初始化程序。

gcc will give a warning in the case you've described:

./x.c:3010: warning: 'someName' defined but not used

Solution: Do what you're currently doing, but don't ignore compiler warnings ;)

Edit:

With your updated question: No, I don't believe there is a way to simply declare a static variable (without also defining it).

The common solution is just to make sure all your global scope variables are declared once only, with an initialiser if they need it.

划一舟意中人 2024-08-21 07:02:38
static some_type some_name; /*definition */

静态变量some​​_name已被初始化为0;它是定义,而不仅仅是声明。

IMO,静态变量不能仅使用 extern 说明符在 C 中声明,因为它的链接始终是内部的。

static some_type some_name; /*definition */

The static variable some_name has been initialized by 0; it is the definition, not just a declaration.

IMO, a static variable cannot be just declared in C using extern specifier as its linkage is always internal.

无言温柔 2024-08-21 07:02:38

在 C 语言中不可能创建具有内部链接的对象的非定义声明(即术语中的“预声明”)。

您可以尽可能接近的是一个暂定定义,这就是您在示例中的内容。但如果出现拼写错误,暂定定义将隐式产生独立定义,而不是链接器错误。

It is not possible to create a non-defining declaration (i.e. "pre-declare" in your terminology) of an object with internal linkage in C language.

As close as you can get to that is a tentative definition, which is what you have in your example. But in case of a typo tentative defintion will implictly produce an independent definition, not a linker error.

嘿嘿嘿 2024-08-21 07:02:38

一点背景知识:

正如其他人指出的那样,静态变量具有内部链接,这意味着它们只能在同一“编译单元”或源文件中使用。这意味着您不能在头文件中声明它,在一个编译单元中为其赋值,并期望该值出现在另一个编译单元中。

当您初始化全局变量(静态或非静态)时,编译器只是将初始值放入可执行文件中为该变量分配的内存位置。换句话说,它总是有一个初始值。当然,您可以稍后使用赋值语句覆盖该值。

建议:

如果您确实不知道编译时变量的值,那么您应该在初始化函数中动态分配它。

static some_type some_variable; /* = 0 by default */

/* some code */

void MyInitializations()
{
    some_variable = some_value;
}

如果您想在一个地方声明变量,例如头文件,并在源文件中定义它,那么您应该使用“extern”声明,它告诉编译器不必担心变量在哪里。链接器将找到变量的位置,就像在另一个文件中查找函数并填写地址一样。

标头:

extern some_type some_variable;

源文件 1:

void UseSomeVariable()
{
    x = some_variable;
}

源文件 2:

some_type some_variable = some_value;

/* possible also uses some_variable */

如果您只想在一处声明变量并在另一处定义它,请不要使用“static”关键字。这样做的缺点是您不能在不同的编译单元(.c 文件)中使用相同的全局变量,也不能在头文件中使用它。

A little background:

As others have pointed out, static variables are have internal linkage, which means that they can only be used in the same "compilation unit" or source file. That means you cannot declare it in a header file, assign a value to it in one compilation unit, and expect that value to appear in another.

When you initialize a global variable (static or not), the compiler simply puts the initial value into the executable file at the memory location allocated for the variable. In other words, it always has an initial value. Of course you can always override the value later by using an assignment statement.

Suggestions:

If you really don't know the value of the variable at compile-time, then you should assign it dynamically in your initialization function.

static some_type some_variable; /* = 0 by default */

/* some code */

void MyInitializations()
{
    some_variable = some_value;
}

If you want to declare the variable in one place, say a header file, and define it in a source file, then you should use an 'extern' declaration which tells the compiler to not worry about where the variable is. The linker will find the location of the variable much like it finds a function in another file and fill in the address.

Header:

extern some_type some_variable;

Source file 1:

void UseSomeVariable()
{
    x = some_variable;
}

Source file 2:

some_type some_variable = some_value;

/* possible also uses some_variable */

If you just want to declare the variable in one place and define it in another, don't use the 'static' keyword. The downside of this is that you can't use the same global variable in different compilation units (.c files) and you can't use it in a header file.

命硬 2024-08-21 07:02:38

您需要预先声明变量吗?如果没有,则将初始值设定项放在唯一的声明上。如果您的初始值设定项不是常量(这需要 C++,而不是 C、IIRC),那么我可以理解为什么您需要在使用它的某些函数之前预先声明它。但是初始化程序所需的一切都可以在它之前预先声明。

因此,将常量定义和静态变量放在每个文件的顶部,以便静态初始化器可以紧接在常量之后。那么你就不需要单独的初始化行。

在任何其他情况下,caf 是对的:值得让您的代码使用 gcc 进行编译,只是为了从其警告中受益。我已经为 C++ 中的 MFC GUI 的 g++ 做到了这一点。 (编译,而不是运行!)

据我所知,C 没有办法编写弱定义,如果稍后没有带有初始值设定项的定义,该定义将产生错误。由于变量位于 BSS 部分,因此始终存在隐式 0。

Do you need to pre-declare the variable? If not, then put the initializer on the only declaration. If your initializer is not a constant (which would require C++, not C, IIRC), then I can understand why you need to pre-declare it before some functions that use it. But then everything you need for the initializer could be pre-declared before it.

So put your constant defs and static variables up at the top of each file, so your initializer for the static can come right after the constants. Then you don't need a separate initialization line.

In any other case, caf's right: It can be worth getting your code to compile with gcc just to get the benefit of its warnings. I've done that for g++ for an MFC GUI in C++. (compile, not run!)

AFAIK C doesn't have a way to write a weak definition that will produce an error if there isn't a definition with an initializer later. There's always an implicit 0, since the variable goes in the BSS section.

樱花落人离去 2024-08-21 07:02:38

在 C++ 中(不是 C),可以使用 未命名命名空间 而不是静态。像这样声明:

namespace {
    extern some_type some_name;
}

extern 使此成为非定义,但是由于未命名的命名空间,some_name 无论如何都有内部链接,就好像声明为 static (参考:https://en.cppreference.com/w/cpp/语言/storage_duration#Linkage)。

对应的定义简单来说就是这样:

namespace {
    some_type some_name = initialization;
}

In C++ (not in C), it can be done using an unnamed namespace instead of static. Declare like this:

namespace {
    extern some_type some_name;
}

extern makes this non-definition but, due to the unnamed namespace, some_name has internal linkage anyway, as if declared as static (ref.: https://en.cppreference.com/w/cpp/language/storage_duration#Linkage).

The corresponding definition is simply this:

namespace {
    some_type some_name = initialization;
}
月下凄凉 2024-08-21 07:02:38

如果我理解你的问题,也许你只是没有以正确的方式面对它。

使用 extern SomeType someVar_; 会不会更好,它对你的程序说,我知道这个变量将会被知道,但我现在不想告诉你它是什么。

因此,您可以在一个单独的文件中声明您的变量,例如

static SomeType SomeVar_;

在您的文件中,放置

extern SomeType SomeVar_

并且将初始化放在您想要的任何位置。

If I understand your problem maybe your just not facing it the right way.

Would you not be better with extern SomeType someVar_; which says to your program, I know that this variable will be known, but I don't want to tell you what it is now.

You can therefore, in a separate file declare your variable say

static SomeType SomeVar_;

In your file, put

extern SomeType SomeVar_

And than put the initialization wherever you want.

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