Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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
C++ 我如何看待<;优化输出>;C+中的变量+;?_C++_Gdb_G++ - Fatal编程技术网

C++ 我如何看待<;优化输出>;C+中的变量+;?

C++ 我如何看待<;优化输出>;C+中的变量+;?,c++,gdb,g++,C++,Gdb,G++,我用gdB调试C++程序。< /p> 我有以下代码: int x = floor(sqrt(3)); 我想查看x的值。然而,gdb声称x是“优化的”。如何查看x的值?我应该更改编译器标志吗?在高优化级别上,编译器可以消除中间值,正如您在这里看到的。有多种选择: 您可以降低优化级别,使调试器更容易跟踪事件-O0肯定会工作(但会慢很多),-O1也可以工作 您可以添加一些显式打印语句来记录输出值 通常,您还可以通过使其易失性来强制编译器保留此特定值(但请记住在完成后取消使其易失性!)。然而,请注意

我用gdB调试C++程序。< /p> 我有以下代码:

int x = floor(sqrt(3));

我想查看x的值。然而,gdb声称x是“优化的”。如何查看x的值?我应该更改编译器标志吗?

在高优化级别上,编译器可以消除中间值,正如您在这里看到的。有多种选择:

  • 您可以降低优化级别,使调试器更容易跟踪事件
    -O0肯定会工作(但会慢很多),
    -O1
    也可以工作
  • 您可以添加一些显式打印语句来记录输出值
  • 通常,您还可以通过使其易失性来强制编译器保留此特定值(但请记住在完成后取消使其易失性!)。然而,请注意,由于控制流在优化代码中也会发生更改,即使您可以看到变量的值,当您查看所讨论的变量时,可能并不完全清楚代码中的哪一点

如果不能或不想禁用优化,则可以尝试将变量声明为volatile。 这通常足以使编译器在最终代码中保留变量

或者,在最近的GCC版本中,您可以仅对一个函数禁用优化,如下所示:

void my_function() __attribute__((optimize(0)))
{
  int x = floor(sqrt(3));
}

创建您自己的“全局变量”,并将优化后的输出变量打印到此全局变量中。确保在完成调试后删除这些由您创建的全局文件

使用反向调试时,请尽量后退到变量的定义点附近

如所示:通常情况下,在函数中:

  • 在函数开始时,可以观察变量的值
  • 然而,函数快结束时,变量越来越有可能变成
    ,因为由于优化,它只存储在寄存器中,而不存储在堆栈上的内存中。因此,当不再需要它时,寄存器可能会被重用,并被另一个变量覆盖,然后调试元数据会通知GDB这一点
因此,如果您正在使用某种类型的变量,只要您尝试一次,就会一直这样做,那么一个很好的选择就是尝试使用
reverse finish
+
reverse next
后退到变量的定义点/最后一次使用点,看看您是否可以在那里观察到它


这一点可以通过中所示的示例代码具体观察到,并为我节省了几次时间,特别是当运行未优化的程序使其花费太长时间才能到达关注点时(这并不奇怪,因为在该答案中,
-O0
生成的汇编效率极低).

如果您在编译时没有优化ie-O0Yes,那么它应该是可用的。是的,您通常应该在禁用优化的情况下调试代码。使用
-O0
标志。这是否回答了您的问题?您通常还可以反汇编函数并推断“优化输出”变量真正驻留在哪个寄存器中,然后打印该变量。目前正在进行开发工作,以使GCC发出足够详细的调试信息,以便GDB将来能够为您这样做。@EmployedRussian,如果变量确实存在,这可以工作,但计算变量的实际工作可能会被取消,所以它并不是在所有情况下都有效。局部变量也可能只存在于寄存器中
gcc
可以通过这种方式优化您的代码,这是导致无法查看变量的另一个可能原因。有关如何查看寄存器变量,请参见此答案:对于我来说,此属性未定义。当我改用
optnone
时,变量得到了优化(clang3.8)。