8

在 C 中是否可以有相互引用的静态变量初始值设定项,如下例所示?

如果将第 2 行添加到预先声明的“B”中,则该示例将在 gcc -Wall 中编译,而不会发出警告。第 2 行令人讨厌,因为它也定义了 B,第 4 行也是如此。带有 -weak 检查的 splint lint 程序警告“B”被定义了两次:“变量 B 重新定义。函数或变量被重新定义。声明之一应该使用外部。”

通常会使用 extern 关键字进行声明,但 extern 和 static 不能一起使用,并且不会在 gcc 下编译。

#include <stdio.h>                               /*1*/
volatile static void * B;                        /*2*/
volatile static void * A = &B;                   /*3*/
volatile static void * B = &A;                   /*4*/
int main()                                       /*5*/
{                                                /*6*/
    printf("A = %x, B = %x\n", (int)A, (int)B);  /*7*/
    return 0;                                    /*8*/
}                                                /*9*/

谢谢

4

3 回答 3

5

尽管volatile与 相关的位置很奇怪static,但您发布的代码是完全有效的 C。它使用称为tentative definitions的 C 特定功能。此功能确保B您的程序中只有一个:B定义相同实体的两个定义。没有什么“令人反感”的。

您从夹板收到的警告无效。在 C++ 语言中,这确实会构成一个多定义错误,但在 C 中则不然。关于externC 语言的上下文中的注释没有任何意义。

于 2012-10-02T21:42:45.523 回答
3

这是没有意义的。

编辑:

是的,'extern' 中没有必要(谢谢,AndreyT 和 Adam Rosenfield),但&B类型为void**, not void*

当然,void**强制转换为void*,但有什么意义呢?如果你想要别名或指针,那么只需声明第三个变量“缓冲区”,并在 A 和 B 中指向它。

unsigned char SomeBuffer[LENGTH];

void* A = SomeBuffer;
void* B = SomeBuffer;
于 2012-10-02T21:38:10.890 回答
0

看起来您正在定义一个循环循环,但实际上并非如此。C&运算符是地址运算符,用于获取相关变量的地址。

正如@AndreyT 指出的那样,第 2 行具有暂时定义 B的效果,以便第 3 行知道它。您可以第 2 行视为分配内存位置B,然后在第 4 行中放置一个值。

该代码在功能上与您编写如下代码相同:

volatile static void * A;
volatile static void * B;
int main()
{
    A = &B;
    B = &A;
    printf("A = %x, B = %x\n", (int)A, (int)B);
    return 0;
}                    

因此,在第 3 行中,您定义A指向B. 在第 4 行中,您定义B指向 的地址A

可以这么说AB具有以下内存地址:

&A == 0xAAAAAAAA
&B == 0xBBBBBBBB

第 3 行中的代码执行以下操作:

A = 0xBBBBBBBB;

然后在第 4 行,它执行以下操作:

B = 0xAAAAAAAA;

现在,如果你要取消引用AB你会得到以下结果(警告,你必须先转换为可取消引用的指针类型):

*A --> 0xAAAAAAAA
*B --> 0xBBBBBBBB

这是完全有效的,但可能不是您打算对代码执行的操作。

请记住,有两个不同的价值观在起作用。首先是指针的值。其次是指针的地址。

您需要使用的唯一原因extern是使用在另一个目标文件中定义的变量(即,file1.c您想使用在 中定义的全局变量file2.c)。static应用于全局变量时的关键字意味着该变量是文件静态的,或者它只能在该文件中使用。所以这两者显然是不和的。

于 2012-10-02T23:41:10.663 回答