【发布时间】:2018-02-23 21:12:11
【问题描述】:
基本上我是在问声明是否
unsigned char myBuffer[128] __attribute__((section (".some_section")));
与
相同static unsigned char myBuffer[128] __attribute__((section (".some_section")));
即我想知道是否将变量声明为放入特定部分将提供不可覆盖的功能,就像 static 声明所做的那样。或者myBuffer 的内存是否分配在其代码范围内,可供其他人(范围外)覆盖?当我稍后回到myBuffer 的代码范围时,它可能根本不包含与以前相同的值?
测试起来并不简单,因为“未定义”行为通常(在简单的代码 sn-p 测试中)表现得非常明确。
编辑: 感谢您的回答和讨论。这里是对意图的澄清。
就我而言,在buf.c 中,我有一个结构ms 和一个uint32_t-array 成员(以及其他成员,但让我们把它们排除在外)。
buf.c
#include <stdio.h> // and many other includes
typedef struct myStruct {
uint32_t a[BUFSIZE];
} MyStruct_t;
MyStruct_t ms __attribute__ ((__section__(".do_not_init_section")));
void startUpCode() {
// Init all members of struct to some values...
}
void foo(uint32_t* buf, int bufsize) {
// figure out the right position in array to write to, i.e. find posInStruct. And memcpy...
memcpy(&ms.a[posInStruct], buf, bufsize)
}
main.c 在while 循环中,main.c 中的所有其他函数都可以在bar.c 中调用foo(...)
我当然希望ms.a 在程序的整个生命周期内只能由bar.c 修改,它就是这样。 (好的,它不受 extern 的保护,因为它不是静态的,但没关系,没有其他文件是 extern-ing ms in bar.c。)
但是我的问题是ms 是否真的受到保护。 ms 的内存是在整个生命周期中专用于 ms 还是只有 static 声明才能处理?
我希望在整个程序生命周期内“记住”所有修改,例如我在开头向数组ms.a[] 写入一些值,然后在bar.c 中退出foo(...)。下一次(在程序中的所有其他函数都完成了它们所做的事情之后),我在bar.c 中对foo(...) 进行了新调用,现在我希望ms.a[] 保持完整并包含与我上次离开它时相同的值.这与其他函数是否显式更改ms 的值无关,更多的是当ms 不在范围内时它们是否隐式碰巧写入ms 的内存,因为超出范围时内存不是专用的!?
如果它与globals 或sections 无关,我会通过声明结构static 来确定问题不会存在。但是我对section-ing 部分有点不确定,它是否真的在内存中保护并保持ms 的值完好无损。
我的天啊,我从来没有编辑过这么多的文字,我希望有人可以编辑并使它更紧凑和聪明。
【问题讨论】:
-
请解释一下您的问题中不可覆盖的功能是什么意思。你在说什么功能?
-
@LuisColorado 我的意思是,对于
static,变量的内存被分配并单独为该变量保留......没有其他人(即使在变量范围之外)可以意外覆盖该部分记忆 -
带或不带静态,除了在 fortran 中,允许共享空间(公共)所有变量都单独保留一个空间(不能共享)但如果您的问题不是意外覆盖该变量,例如缓冲区溢出,在这种情况下你是不安全的。即使属于不同的部分,内存保护也不适用于此处。所有可写部分由链接器放在一起。那么,为什么不问你真正担心的是什么,而不是对
static关键字做出假设呢?这是 XY 问题的一个实例。 -
@LuisColorado 我认为您回答了问题中的“EDIT2”。我不知道你认为我对静态的假设有什么问题?想象一下这个问题不包括
section,我会说我想在调用C文件之间记住我的变量的值,其中变量的作用域是全局的。你会告诉我声明变量为静态的,不是吗?