![]() |
1
20
规则是堆栈帧中调用setjmp的任何非易失性、非静态局部变量 可以 打电话给朗吉姆普让我大吃一惊。处理它的最简单方法是确保调用setjmp的帧不包含任何您关心的此类变量。这通常可以通过将setjmp单独放入一个函数中,并传入对已在另一个不调用setjmp的函数中声明的内容的引用来完成:
还注意到在这方面, 克劳巴林 实际上只是意味着重置为调用setjmp时的值。所以,如果longjmp在修改了一个本地文件之后永远无法调用,那么您也可以。 编辑 关于setjmp的c99规范的准确引用是:
|
![]() |
2
5
这不是一个你应该忽略的警告,LojJMP()和C++对象不能相处。问题是编译器会自动为foo对象发出析构函数调用。longjmp()可以绕过析构函数调用。 C++异常也取消了堆栈帧,但它们保证将调用本地对象的析构函数。longjmp()没有这样的保证。要找出longjmp()是否会变成字节,需要仔细分析每个函数中的局部变量,这些变量可能由于longjmp()而提前终止。这不容易。 |
![]() |
3
2
如错误消息中的行号1035所示,您的代码片段大大简化了实际的问题代码。你太过分了。你是如何使用“第一”的,这一点毫无头绪。问题是编译器甚至在实际的代码中也无法发现这一点。“setjmp”的非零返回之后的“first”值恐怕不是您所认为的值。这是因为您在第一次调用(零返回)之前和之后都将其值更改为“setjmp”。如果变量存储在寄存器中,则该值可能与存储在内存中的值不同。所以编译器给你一个警告是保守的。 若要盲目跳跃并回答问题,您可以通过将“first”声明限定为“volatile”来消除警告消息。你也可以尝试让“第一”成为全球性的。也许通过删除优化级别(-o标志),可以使编译器将变量保留在内存中。这些都是快速修复,实际上可能隐藏了一个bug。 你真的应该看看你的代码,以及你是如何使用'第一'。我再做一个大胆的猜测,并说你可以消除这个变量。这个名字“first”是否意味着您使用它来表示对“setjmp”的第一个调用(零返回)?如果是的话,摆脱它-重新设计你的逻辑。 如果真正的代码只是在“setjmp”的非零返回上退出(如代码片段中所示),那么“first”的值在该逻辑路径中无关紧要。不要在“setjmp”的两边使用它。 |
![]() |
4
-1
快速的答案是:删除-o1标志或将编译器还原到早期版本。任何一个都让我的系统上的警告消失了。我必须建立和使用GCC4.4在第一时间得到警告。(该死,这是一个庞大的系统) 不?我想不是。 我真的不理解C++对它的对象所做的一切,也不知道它们是如何被释放的。然而,op的评论说,如果使用一个常量来代替矢量大小的“argc”,问题就不会发生,这给了我一个伸出脖子的机会。我将冒昧地猜测,只有当初始分配不是常数时,C++才在“取消分配”时使用“第一个指针”。在更高的优化级别上,编译器更多地使用寄存器,并且在setjmp之前和之后的分配之间存在冲突…我不知道,这毫无意义。 这个警告的一般含义是“你确定你知道你在做什么吗?”编译器不知道当您执行longjmp并从“setjmp”获得非零返回时,是否知道“uu first”的值。问题是(非零)返回后的值是放入保存缓冲区的值,还是保存后创建的值。在本例中,这很令人困惑,因为您不知道您使用的是'\uu first',并且因为在这样一个简单的程序中,没有(显式的)更改为'\uu first' 编译器无法分析复杂程序中的逻辑流,因此它显然甚至不尝试任何程序。它允许您更改值的可能性。所以它只是给了你一个友好的“抬头”。编译器正在对您进行二次猜测,试图提供帮助。 如果你顽固地选择编译器和优化,有一个编程修复。在分配矢量之前保存环境。将“setjmp”移到程序顶部。根据向量的使用和实际程序中的错误逻辑,这可能需要进行其他更改。 编辑1/21---- 我的理由(使用g++-mp-4.4-wextra-o1 main.cpp):
没有警告;a.out产生:
从0 0开始
|