Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.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++_C_Embedded_Stack_Local - Fatal编程技术网

C++ 嵌入式C++;,有没有避免只用于返回堆栈上的值的局部变量的提示?

C++ 嵌入式C++;,有没有避免只用于返回堆栈上的值的局部变量的提示?,c++,c,embedded,stack,local,C++,C,Embedded,Stack,Local,我有一个局部函数,它只用于检查另一个函数的结果,并在满足某些条件时传递它。大多数情况下,这一标准永远不会得到满足。我有什么办法可以避免这种“额外的”本地的吗 我的二进制文件只有大约1MB的存储空间,我有几千个函数调用遵循这种模式。我知道这是一件小事,但如果有更好的模式我想知道 SomeDataType myclass::myFunction() { SomeDataType result; // do I really need this local??? // i need t

我有一个局部函数,它只用于检查另一个函数的结果,并在满足某些条件时传递它。大多数情况下,这一标准永远不会得到满足。我有什么办法可以避免这种“额外的”本地的吗

我的二进制文件只有大约1MB的存储空间,我有几千个函数调用遵循这种模式。我知道这是一件小事,但如果有更好的模式我想知道

SomeDataType myclass::myFunction()
{
   SomeDataType result;  // do I really need this local???

   // i need to check the result and pass it on if it meets a certain condition
   result = doSomething();
   if ( ! result ) {
      return result;
   }

   // do other things here
   ...

   // normal result of processing
   return SomeDataType(whatever);
}

SomeDataType
有多复杂?它有很多成员吗?它在构造函数中做了很多工作吗?如果是这样的话,我会避免这样。如果没有,您可能会发现编译器将为此生成良好的代码。例如,编译器可能会很好地处理整数类型


对于这样的问题,答案几乎总是:查阅编译器的汇编输出。

正如asveikau所指出的,如果某个数据类型“适合于寄存器”(例如,它是一个普通的旧int),那么本地数据类型(取决于平台)将不会浪费任何内存。我同意asveikau的观点,您应该参考程序集输出以评估是否存在这种情况。

取决于编译器是否具有返回值opitmization,以及某个数据类型是大还是小。安全的一面是,如果对象较大,则对此类模式使用智能指针。如果它们是POD,它们可能会被优化并在寄存器中返回。

如果将函数更改为

void myclass::myFunction(SomeDataType* pResult)
{
  // i need to check the result and pass it on if it meets a certain condition
   *pResult = doSomething();
   if ( ! *pResult ) {
      return;
   }

   // do other things here
   ...

   // normal result of processing
  *pResult = SomeDataType(whatever);
}

如果未在函数的其他位置使用结果变量,可以尝试以下操作:

if (!doSomething())
{
    return;
}
do
{
    if (!doSomething())
    {
        break;
    }
// ...
} while (false);
return;
上面的示例允许编译器在必要时创建临时变量,而不是告诉编译器创建一个临时变量

如果您是结构化编程的坚持者,您可以尝试以下方法:

if (!doSomething())
{
    return;
}
do
{
    if (!doSomething())
    {
        break;
    }
// ...
} while (false);
return;

此示例只允许函数中有一个返回点。在处理质量和可追溯性准则时,这可能是一件好事。

如果您有一个重复在数千个函数中的模式,您可以考虑用一个函数和一个查找表替换它。


(如果不了解您的详细情况,我真的不能说得更具体。)

我会反汇编代码,并找出编译器在生成代码时正在执行的操作。现代编译器做一些棘手的事情,试图猜测如何节省代码空间并不明显——有时我很少看到从源代码到程序集的通信。源代码更多的是关于清晰性和维护-生成程序集有不同的标准。

我建议您检查编译器选项,并确保它们设置为“大小优化”,因为这是您担心的问题。如果您的编译器没有这样的设置,那么也许是时候检查另一个设置了。

在对doSomething()的调用中,您可以返回一些数据类型(无论什么)。

我建议您不要担心它。在这个级别进行优化并不是一个很好的时间利用,因为任何一个好的编译器都会最小化所需的本地存储量。堆栈是可重用的,数千次调用都无关紧要,因为内存只在使用它的上下文中需要,除此之外与上下文无关


如果确实需要关心堆栈上的几个字节的临时存储,那么您可能应该使用汇编。我怀疑这是真的,所以不要着急,把时间花在其他更有趣、更重要的问题上

在我的例子中,SomeDataType是一个非常简单的具体(非虚拟)类,只有一个整数成员变量和十几个成员函数。构造函数只执行赋值。我知道,只要有可能,在堆栈上创建一个返回值比创建一个本地值要便宜得多。然而,如果存在的话,我真的希望有一个通用的解决方案,因为我不能保证某个数据类型总是这样。事实上,当我为具有严格内存限制的平台编写代码时,像这样的问题使我的C++非常“C”。我同意,你应该看看编译器生成的程序集。如果这个变量可以放入寄存器,那么任何好的嵌入式编译器都应该为您优化它。澄清:我不担心RAM的使用,我更担心可执行文件大小的闪存消耗。我确信它可以放入寄存器,但是额外的本地文件会增加我的obj文件的大小。我的第一个问题是,你真的需要在赋值之后单独使用默认构造吗?
SomeDataType result=doSomething()有什么问题?通过消除SomeDataType::SomeDataType()调用,这可能会节省更多的闪存。你可能是对的,我不需要默认的构造。“额外的本地将增加我的obj文件的大小”-我不确定我是否遵循。额外的本地文件将如何增加obj文件大小?它是驻留在RAM(或寄存器)中的数据。也许是正确的方向,但我不确定。我刚刚尝试了一个快速的编译器测试,向函数调用添加额外的参数似乎消耗了与本地完全相同的空间量,但我不确定这是否正确,因为我可能没有通过这么小的测试达到最小的exe大小。别忘了从函数返回对象时会发生操作,它实际上包括创建临时对象,将返回值赋值给abject,而不是将函数的结果赋值给变量ASGN运算符,如果不赋值,而是使用myFunction()之类的东西。doSomething()不会赋值,但大多数情况下的典型用法是var=myFunction()RVO:Good call,但是有很多的警告要依赖于它。我刚刚在Dobbs博士身上找到了一篇好文章,主题是:啊。我是真的