C 使用指针从另一个编译单元访问和更改静态变量

C 使用指针从另一个编译单元访问和更改静态变量,c,pointers,static,C,Pointers,Static,如果在第一个.c文件中有一个静态变量my_var,指针ptr\u my_var指向该变量,那么使用另一个编译单元的ptr\u my_var指针访问和更改变量my_var是否正常 // first.c ... static float my_var; float *ptr_my_var = &my_var; ... // second.c ... extern float *ptr_my_varl; void bar() { (*ptr_my_varl) = 777.777; }

如果在第一个.c文件中有一个静态变量
my_var
,指针ptr\u my_var指向该变量,那么使用另一个编译单元的
ptr\u my_var
指针访问和更改变量
my_var
是否正常

// first.c
...
static float my_var;
float *ptr_my_var = &my_var;
...

// second.c 
...
extern float *ptr_my_varl;

void bar() {
  (*ptr_my_varl) = 777.777;
}

// third.c
extern float *ptr_my_varl;

void foo() {
  (*ptr_my_varl) = 1.233;
}

这被广泛认为是非常糟糕的编程实践*)

将变量声明为静态的全部目的是减少变量的作用域,使其对其所在的模块私有。这是C语言的实现方式,是面向对象程序设计的基石之一



*)例如,请参见MISRA-C:2012规则8.8。

为什么不使用简单的全局变量?它定义得很好。“正常”还是“良好风格”取决于上下文,也可能取决于您的提问方式。@larsmans我想不出任何情况适用于任何类型的应用程序,从任务关键型实时嵌入式应用程序到Windows桌面应用程序,在这些应用程序中,这将是良好的风格,甚至是合理的。@Lundin它不漂亮,我不推荐它,但有时你必须跳出篮筐。(想想DLL,遗留代码。)@larsmans如果你最终不得不使用糟糕的编程实践,这意味着你在程序的其他地方遇到了更大的问题。证书规则是不相关的。MISRA标准没有打开,所以我无法阅读。此外,我可以想象这样一种情况:例如,变量(或查找表)的初始化代码在定义它的编译单元之外,然后向它传递指针是使它工作的唯一方法。@anatolyg它不是无关的。读一下。“风险评估。允许太多对象具有外部链接可能会使用描述性标识符,从而导致更复杂的标识符、违反抽象模型以及可能与库发生名称冲突。如果编译单元实现数据抽象,它还可能会暴露从外部对私有函数的调用。”bstraction.“@anatolyg通过良好的程序设计,初始化代码始终与变量位于同一模块(文件)中。如果程序设计不好,任何事情都是可能的。此外,除了提到的编码标准外,当您使用具有静态存储持续时间的变量时,还存在多线程问题。处理线程安全访问私有变量的所有代码都需要与该变量位于同一个模块中,否则您将创建一个意大利面代码地狱。