内联函数返回不正确的结果
我正在使用 C++ 开发一个大型应用程序,并且我们有一个类,其中内联函数返回错误的值。看起来它们被一项抵消了。
下面是如何设置代码的示例:
class Test
{
private:
uint myVal1;
uint myVal2;
uint myVal3;
uint myVal4;
public:
uint myFunct1() const { return myVal1 };
uint myFunct2() const { return myVal2 };
};
我们看到 myFunct1 返回 myVal2,myFunct2 返回 myVal3。如果我不将函数内联,一切都会按预期进行。
关于为什么会发生这种情况有什么想法吗?
提前致谢。
I have a large application that I am working on in C++, and we have a class where the inline functions are returning the wrong value. It looks like they are offset by one entry.
Here is an example of how the code is set up:
class Test
{
private:
uint myVal1;
uint myVal2;
uint myVal3;
uint myVal4;
public:
uint myFunct1() const { return myVal1 };
uint myFunct2() const { return myVal2 };
};
What we are seeing is that myFunct1 returns myVal2 and myFunct2 returns myVal3. If I dont make the functions inlined everything works as expected.
Any ideas on why this would be happening?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
(我假设您上面发布的内容实际上是某个头文件的片段。)
当程序中的不同源文件使用不同的内存布局相关设置(例如类打包和对齐设置)编译时,通常会发生类似的情况。您的头文件包含在这些不同的翻译单元中,并且由于内存布局设置的差异而被不同地解释。
一旦开始在这些翻译单元之间传递
Test
对象,问题就会显现出来。一个翻译单元创建一个具有一种内存布局的Test
对象,然后另一个翻译单元在假设完全不同的内存布局的情况下读取或写入它。在您的情况下,您的内联函数在每个翻译单元中得到不同的解释。如果将成员函数定义为非内联函数,它们将采用特定于定义它们的源文件的类内存布局。这将把问题一扫而光,并使事情“正常”(因为访问功能现在绑定到一个内存布局),但尽管如此,这仍然不是一个好情况。它仍然可能导致未来出现类似性质的各种问题。
确保程序中的所有源文件都使用完全相同的类内存布局设置进行编译。
PS 正如 Fred 在评论中指出的那样,翻译单元之间类内存布局的差异可能是由于修改源文件所依赖的头文件后忘记重新编译源文件等平淡无奇的事情引起的。
此类问题的另一个“流行”来源是依赖于预处理器指令的类定义(即由
#ifdef
/#endif
段“定制”的类布局)。如果您忘记在包含头文件的某些源文件中#define 某些重要内容,则该源文件中的类可能会得到不同的内存布局。(I assume that what you posted above is actually a fragment from some header file.)
Things like that typically happen when different source files in your program are compiled with different memory-layout-related settings, like class packing and alignment settings. Your header file is included into these different translation units and is interpreted differently because of the discrepancies in memory-layout settings.
Once you start passing your
Test
objects between these translation units, the problem reveals itself. One translation unit creates aTest
object with one memory layout, then another translation units reads it or writes into it assuming a totally different memory layout. In your case it is your inline functions that get interpreted differently in each translation unit.If you define your member functions as non-inline ones, they will assume the class memory layout specific to the source file in which they are defined. This will sweep the problem under the carpet and make things "work" (since the access functions are now tied to one memory layout), but nevertheless it is still not a good situation to have. It still can lead to various problems of similar nature down the road.
Make sure all source files in your program are compiled with exactly the same class memory layout settings.
P.S. As Fred noted in the comments, the discrepancy in the class memory layout between translation units can be caused by something as prosaic as forgetting to recompile a source file after modifying a header file the source file depends upon.
Another "popular" source of such problems is class definitions that depend on preprocessor directives (i.e. class layout "customized" by
#ifdef
/#endif
segments). If you forget to#define
something important in some source file that includes your header file, you might end up with different memory layout for the class in that source file.不,内联函数(当然)需要与非内联函数具有相同的结果。因此,问题一定出在其他地方,在您未显示的代码中。也许是神奇地设定私人成员价值观的人?
No, inlined functions are (of course) required to have the same results as non-inlined functions. So, the problem must be somewhere else, in the code you are not showing. Perhaps the one magically setting the values of the private members?