在C/C++中取消初始化变量
这是一个理论问题而不是实际问题,但我想知道是否有可能在C(或C)中取消初始化变量.所以我们假设我们有以下代码:
void some_fun() { int a; // <-- Here a is an un-initialized variable,it's value is the value // found in the memory at the given location. a = 7; // Now I have initialized it // do something with a ... // and here do something again with a that it // will have the same state (ie: indeterministic) as before initialization } (不,我不想在a中添加一个随机值,因为那也是初始化,也不是0,因为这是一个非常好的值,…我只是希望它再次出现在“我不知道”知道它的任何事情“在初始化之前就已经开始了.” (是的我知道:What happens to a declared,uninitialized variable in C? Does it have a value?) 解决方法
您可以使用setjmp()和longjmp()来获取所需的行为,并重新安排代码.下面的代码将a初始化为1,以便print语句不会调用未定义的行为.
jmp_buf jb; void some_func (void) { int a = 1; if (setjmp(jb) == 0) { a = 7; // do something printf("a = %d (initialized)n",a); // use longjmp to make `a` not initialized longjmp(jb,1); // NOTREACHED } else { printf("a = %d (not initialized)n",a); } } longjmp()调用返回到保存的setjmp()上下文,移动到else情况意味着a尚未初始化. 当使用GCC进行优化编译时,上述函数输出: a = 7 (initialized) a = 1 (not initialized) 如果您希望在未启用优化的情况下执行此操作,请尝试将寄存器存储类添加到声明中. A demo. 更长的解释 那么,为什么我认为setjmp()和longjmp()会起作用?这就是C.??11§7.13?1-2对它的评价:
这解释了应该发生的事情是,通过调用setjmp将longjmp返回到jmp_buf中保存的上下文,就像在longjmp调用之前运行的代码是递归函数调用一样,longjmp就像一个从递归调用返回setjmp.对我而言,这意味着自动变量将是“未初始化的”. int a; // the following expression will be false if returning from `longjmp` if (setjmp(jb) == 0) { // this section of code can be treated like the `setjmp` call induced // a recursive call on this function that led to the execution of the // code in this body a = 7; //... // assuming not other code modified `jb`,the following call will // jump back to the `if` check above,but will behave like a recursive // function call had returned longjmp(jb,1); } else { // `a` expected to be uninitialized here } 但是,似乎有一个问题.从C.11§7.13.2?3:
由于a是本地的,不是volatile限定的,并且在setjmp和longjmp调用之间已经更改,因此它的值是不确定的,即使它在调用setjmp之前已正确初始化! 因此,在修改自动非易失性变量之后使用longjmp返回本地setjmp将始终导致在返回到setjmp之后使这些修改后的变量“未初始化”. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |