- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我基本上确信我遇到了一些 g++ 4.8.3 错误,但我想我会先问这个列表,因为我对 setjmp/longjmp 的经验很少。我已将相关代码简化为以下 foo.cxx:
#include <setjmp.h>
#include <string.h>
// Changing MyStruct to be just a single int makes the compiler happy.
struct MyStruct
{
int a;
int b;
};
// Setting MyType to int makes the compiler happy.
#ifdef USE_STRUCT
typedef MyStruct MyType;
#elif USE_INT
typedef int MyType;
#endif
void SomeFunc(MyType val)
{
}
static void static_func(MyType val)
{
SomeFunc(val);
}
int main(int argc, char **argv)
{
jmp_buf env;
if (setjmp(env))
{
return 1;
}
MyType val;
#ifdef USE_STRUCT
val.a = val.b = 0;
#elif USE_INT
val = 0;
#endif
// Enabling the below memset call makes the compiler happy.
//memset(&val, 0, sizeof(val));
// Iterating 1 or 2 times makes the compiler happy.
for (unsigned i = 0; i < 3; i++)
{
// calling SomeFunc() directly makes the compiler happy.
static_func(val);
}
return 0;
}
我使用 g++ 4.8.3 编译这段代码。令我感兴趣的是,当我定义 USE_STRUCT 时,编译失败但使用 USE_INT 编译成功。代码中有注释进一步说明了如何使用 USE_STRUCT 使编译成功。使用 g++ 的 -fPIC 选项时编译也会失败,但这是我的环境中的必需参数。
查看编译错误:
g++ -DUSE_STRUCT -Wextra -Wno-unused-parameter -O3 -Werror -fPIC foo.cxx
foo.cxx: In function ‘int main(int, char**)’:
foo.cxx:26:5: error: variable ‘val’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered]
但是使用一个简单的 int 是可以的:
g++ -DUSE_INT -Wextra -Wno-unused-parameter -O3 -Werror -fPIC foo.cxx
有人可以向我解释为什么如果 val 是一个结构体,它可能会被破坏,但如果它是一个 int,则不会?如代码中的注释中所示,对结构编译成功的其他方法有何见解?或者这是否指向编译器错误?
非常感谢任何见解和评论。
最佳答案
setjmp()
保存当前堆栈。因为它是在 val
声明之前调用的,所以该变量不会在保存的堆栈中。
在 setjmp()
之后,变量被初始化,如果代码稍后跳回到 setjmp
点,变量将被再次初始化,破坏旧变量。如果存在应在旧实例上调用的非平凡析构函数,则这是未定义的行为 (§18.10/4):
A
setjmp
/longjmp
call pair has undefined behavior if replacing thesetjmp
andlongjmp
bycatch
andthrow
would invoke any non-trivial destructors for any automatic objects.
可能不会调用旧实例的析构函数。我的猜测是 gcc 不会针对原始类型发出警告,因为它们没有析构函数,但会针对可能存在问题的更复杂类型发出警告。
关于c++ - 不一致警告 : variable might be clobbered by ‘longjmp’ or ‘vfork’ ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27802892/
我想使用 setjmp/longjmp 在主函数中重用一些代码(注意:这只是一个练习,而不是我在现实世界中认真计划做的事情)。 以下代码是我想出的: #include #include jmp_b
根据我的理解,setjmp 保存当前上下文,它应该在调用 longjmp 时恢复它。然而,下一段代码打印出 15(我使用 -g 编译并且没有进行任何优化)。我是不是误解了这个结构,还是遗漏了其他任何东
来自问题: Is it good programming practice to use setjmp and longjmp in C? 留下的两条评论说: "You can't throw an
我正在使用以下代码尝试读取来自用户的输入,如果超过 5 秒则超时并退出。这是通过 setjmp/longjmp 和 SIGALRM 信号的组合来实现的。 代码如下: #include #includ
Michael Kerrisk 的“Linux 编程接口(interface)”中的练习 6.2 要求: Write a program to see what happens if we try t
我需要了解 longjmp 函数的工作原理;我知道它的作用,但我需要知道它是如何做到的。 我试图对 gdb 中的代码进行 disas,但我无法理解某些步骤。代码是: 0xb7ead420 :
下面的代码无法正常工作。谁能指出原因 #define STACK_SIZE 1524 static void mt_allocate_stack(struct thread_struct *mythr
这是我的代码: #include #include #include jmp_buf buf; void handler(int s); int main(int argc, char **ar
一段代码在这里 jmp_buf mark; int Sub_Func() { int be_modify, jmpret; be_modify = 0; jmp
我的问题针对的是 setjmp/longjmp 关于局部变量的行为。 示例代码: jmp_buf env; void abc() { int error; ... if(error)
我必须使用 setjmp/longjmp 实现用户级线程库作为作业。这是我写的代码: #include #include #include #include #include #includ
我正在尝试使用 longjmp 在 c 中实现控制的重新反转,目前我有以下代码: #include #include jmp_buf env; int arg; typedef void (*fp
这个问题来自 SetJmp/LongJmp: Why is this throwing a segfault? 当我使用 Debug模式运行代码时,它确实按预期崩溃了。但是如果我使用 release
#include #include #include #include static jmp_buf env_alrm; static void sig_alarm(int signo) {
所以我有一个库(不是我写的),不幸的是它使用 abort() 来处理某些错误。在应用程序级别,这些错误是可恢复的,所以我想处理它们而不是让用户看到崩溃。所以我最终写了这样的代码: static jmp
我的问题针对的是 setjmp/longjmp 关于局部变量的行为。 示例代码: jmp_buf env; void abc() { int error; ... if(error)
我正在调查setjmp/longjmp,发现setjmp 保存指令指针、堆栈指针等寄存器... 然而,我在这里没有得到的是,在调用 setjmp 和 longjmp 之间,不能修改线程本身堆栈中的数据
在 Why volatile works for setjmp/longjmp , 用户 greggo评论: Actually modern C compilers do need to know t
据我了解,setjmp()的典型用法和 longjmp()是异常处理(libpng 中的用法应该是一个著名的例子)并且最多只有一次调用 longjmp()一个 setjmp()称呼。 是否允许安全地做
有没有办法使用 setjmp 来实现多任务处理?和 longjmp职能 最佳答案 这是所谓的用户空间上下文切换的一种形式。 这是可能的,但很容易出错,特别是如果您使用 setjmp 和 longjmp
我是一名优秀的程序员,十分优秀!