Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用goto传递POD堆栈变量时,POD堆栈变量的作用域和生存期 我的问题与CG9/GNU-C和C++中堆栈变量的生存时间有关,当GOTO传递给它们时。这里有许多相关的问题,但没有一个真正回答了我的问题。考虑下面的代码示例: void Foo(char *ptr) { label1: if (ptr) { char string1[50]; strcpy(string1, ptr); strupr(string1); printf("upcased string = %s\n", string1); return; } #if CASE_1 char string2[50] = "test"; #else char string2[50]; strcpy(string2, "test"); #endif ptr = string2; goto label1; }_C++_C_Scope_Goto - Fatal编程技术网

使用goto传递POD堆栈变量时,POD堆栈变量的作用域和生存期 我的问题与CG9/GNU-C和C++中堆栈变量的生存时间有关,当GOTO传递给它们时。这里有许多相关的问题,但没有一个真正回答了我的问题。考虑下面的代码示例: void Foo(char *ptr) { label1: if (ptr) { char string1[50]; strcpy(string1, ptr); strupr(string1); printf("upcased string = %s\n", string1); return; } #if CASE_1 char string2[50] = "test"; #else char string2[50]; strcpy(string2, "test"); #endif ptr = string2; goto label1; }

使用goto传递POD堆栈变量时,POD堆栈变量的作用域和生存期 我的问题与CG9/GNU-C和C++中堆栈变量的生存时间有关,当GOTO传递给它们时。这里有许多相关的问题,但没有一个真正回答了我的问题。考虑下面的代码示例: void Foo(char *ptr) { label1: if (ptr) { char string1[50]; strcpy(string1, ptr); strupr(string1); printf("upcased string = %s\n", string1); return; } #if CASE_1 char string2[50] = "test"; #else char string2[50]; strcpy(string2, "test"); #endif ptr = string2; goto label1; },c++,c,scope,goto,C++,C,Scope,Goto,我读到goto并没有引入新的作用域,因此变量应该在声明之前就可以访问(理论上)。string2存在于函数作用域中,但在声明之前无法从代码中直接访问它。另一方面,使用goto和指针变量,可以访问它。 我知道C++需要调用析构函数,当GOTO向后地初始化对象时,但我没有找到内置/POD类型的生命。 使用GCC进行的测试表明,当ptr未分配给string2时,编译器重用堆栈空间,当分配完成时,它将停止重用堆栈空间,好像它“知道”在goto之后可以对其进行寻址 C99/C++标准(甚至可能仅限于GCC)

我读到goto并没有引入新的作用域,因此变量应该在声明之前就可以访问(理论上)。string2存在于函数作用域中,但在声明之前无法从代码中直接访问它。另一方面,使用goto和指针变量,可以访问它。 我知道C++需要调用析构函数,当GOTO向后地初始化对象时,但我没有找到内置/POD类型的生命。 使用GCC进行的测试表明,当ptr未分配给string2时,编译器重用堆栈空间,当分配完成时,它将停止重用堆栈空间,好像它“知道”在goto之后可以对其进行寻址

C99/C++标准(甚至可能仅限于GCC)中是否有明确规定,是否允许这样做?我对C++特别感兴趣。 编辑:


  • 处理C++的部分是“代码>”3.7.3-1块范围变量显式声明登记或未显式声明静态或外部具有自动存储持续时间。这些实体的存储持续到它们被创建的块的“./CODE”,而这似乎证明上述代码是正当的,事实并非如此,因为很明显,当编译器知道自动变量的堆栈空间将不再被使用时,它将重用自动变量的堆栈空间作为优化。因此,需要回答的问题是:编译器是否可以假设变量在声明之前未在该位置使用,即使程序流将携带引用
  • 我添加了另一个案例,似乎有不同的规则
  • 要回答任何问题,首先我为什么要使用如此丑陋的构造:这肯定不是我想要编写普通代码的方式。它应该是compatibility宏的一部分,以允许对G使用结构化异常处理++

  • 关于C++,C++ 11标准的第6/1段规定:

    […]从循环、块中传出,或通过初始化变量返回 自动存储持续时间涉及销毁处于自动存储持续时间的对象 范围在从转移到的点,但不在转移到的点。[……]

    第3.7.3/3段规定:

    如果具有自动存储持续时间的变量具有初始化或具有副作用的析构函数,它不应 在其块结束之前被销毁,也不能作为优化消除,即使它看起来是 未使用,除非类对象或其复制/移动可以按照12.8中的规定消除

    由于
    string2
    具有初始化,因此程序具有未定义的行为


    也就是说,当您可以使用结构化编程时,为什么要使用
    goto
    对于不具有可变长度数组类型的对象,其生存期从进入与其关联的块开始,一直到该块的执行以任何方式结束。(输入封闭块或调用函数会暂停但不会结束当前块的执行。)如果以递归方式输入块,则每次都会创建对象的新实例。对象的初始值是不确定的。如果为对象指定了初始化,则每次在执行块时达到声明或复合文字时都会执行初始化;否则,每次到达声明时,该值都变得不确定


    string2
    的生存期是执行块的整个时间,因此在第一次初始化后使用
    ptr
    if
    分支中访问它会发现具有确定内容的对象。

    我可以取消初始化:
    char string2[50];strcpy(string2,“测试”)所以在这个case@Timo:在这种情况下,它是格式良好的,因为3.7.3/1(“这些实体的存储持续到创建它们的块退出为止”)和3.8/1(“类型T的对象的生存期在以下情况下结束:如果T是具有非平凡析构函数的类类型(12.4)),析构函数调用开始;或者,对象占用的存储被重用或释放。“关于第一个QoE:“在从传输点的范围内,但不在传输点的范围内”,但考虑到作用域就是函数,跳转后它不会超出作用域,只有名称是未定义的。关于第二点:我可以去掉初始化:
    char string2[50];strcpy(string2,“test”);
    所以在这种情况下,第二部分也不适用。很抱歉,但我不相信有害的gotos法则,事实上它们可以使代码更可读(就像在错误处理案例中一样),但要回答您的问题:为什么:因为我可以;)“这些实体的存储会一直持续到创建它们的块退出为止。”@Timo:goto
    所谓的良好品质,你忽视了几十年来证明相反的实践和原则。对于错误处理,C++有例外。如果在跳回之前,变量的地址被保留,变量会继续保持其值,直到达到声明并变得不确定。