VS 2012字节对齐,Release vs Debug [英] VS 2012 byte alignment, Release vs Debug

查看:116
本文介绍了VS 2012字节对齐,Release vs Debug的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将我的app(现在的v10.4)C ++代码库从VS2008移到VS2012。在VS2008中,它已经运行了多年。在VS2012 Debug下,它运行也很完美,但在Release模式下,一个非常简单的测试(解码用new运算符创建的LPSTR缓冲区)将地址关闭1并且解码失败。我对调试模式中的保护字节非常熟悉。



例如,我可以创建包含\rI:0x1a的最简单的4字节缓冲区。缓冲区的起始处有一个指针(lpScript)。所有解码功能都必须是

(伪代码)

lpScript ++;

TestNextCharIsAlpha();

lpScript ++;

TestNextCharis冒号();



简单,对吧?嗯,不是这样。





VS2012编译器发布模式似乎与调试模式和2008编译器不同地处理字节对齐。在Debug模式下,TestNextCharIsAlpha();正在测试我字符。在发布模式下,TestNextCharIsAlpha();正在测试:字符。 lpScript的值看起来是正确的,仍然存在这个错误。正如我所说的,这个代码在使用VS2008构建时已经工作多年了。



我在项目设置中一直在探索并找不到任何解释这个。任何想法?

I'm moving my app (now v10.4) C++ code base to VS2012 from VS2008. In VS2008 it's been working perfectly for years. Under VS2012 Debug, it runs perfectly as well, but in Release mode, a very simple test (decoding an LPSTR buffer created with the new operator) gets the address off by 1 and the decode fails. I'm very familiar with guard bytes in debug mode.

For example, I can create the simplest 4 byte buffer containing "\rI:0x1a". There's a pointer (lpScript) to the start of the buffer. All the decode function has to do is
(in pseudo code)
lpScript++;
TestNextCharIsAlpha();
lpScript++;
TestNextCharis Colon();

Simple, right? Well, not so.


The VS2012 compiler Release mode seems to handle byte alignment differently to debug mode and the 2008 compiler. In Debug mode, TestNextCharIsAlpha(); is testing the "I" character. In Release mode, TestNextCharIsAlpha(); is testing the ":" character. The values of the lpScript look correct, and still there's this bug. And as I said, this code has been working for years when built with VS2008.

I've poked around in the project setups and can't find anything that explains this. Any ideas?

推荐答案

我认为调试/发布之间的对齐不同,而是结构的大小不同。查看类/结构的定义,看看是否有任何#ifdef _DEBUG或类似的代码(实际上,如果你的类包含其他类,你需要递归地执行此操作)。



如果你自己进行内存管理,也会出现这种问题。如果您不知道这意味着什么,请查看您的任何类是否实现operator new(两种类型)和/或使用内存池。内存分配需要正确对齐;很多时候它做得不好。这是常见的内存管理错误。
I would think that instead of the alignment being different between debug/release, instead it is the size of the structure that is different. Look at the definition for the class/struct and see if there is any "#ifdef _DEBUG" or similar code in it (actually you need to do this recursively if your class contains other classes).

This kind of problem can also occur if you do your own memory management. If you don't know what that means, look to see if any of your classes implement operator new (both types) and/or use a memory pool. The memory allocation needs to be aligned properly; many times it is not done properly. This is a common memory management mistake.


这与字节对齐无关。字节数组中的字节总是彼此连续分配,至少在英特尔架构上是这样。如果您有例如,则对齐将设置为结构中的double成员,编译器必须决定是否在8字节边界上对齐它。



在你的情况下,bug最有可能在您自己的代码,遗憾的是您没有显示。看看如何初始化lpScript。为什么lpScript没有传递给TestNextCharIsAlpha?我会密切关注你在那里做的事情。如果您愿意,请使用改进问题粘贴您的代码,以便我们查看它。
This has nothing to do with "byte alignment". Bytes in a byte array are always allocated contiguous to each other, at least on the Intel architecture. Alignment would set in if you have e.g. a double member in a structure and the compiler has to decide whether to align it on a 8-byte boundary or not.

In your case the bug sits most likely in your own code, which you unfortunately haven't shown. Look at how lpScript is initialized. Why is lpScript not passed to TestNextCharIsAlpha? I'd take a close look on what you are doing there. If you like, paste your code with "Improve question" so we can a look at it.


感谢您的建议。我找到了一个代码解决方案,但目前还不知道为什么它对VS2012编译器很重要。一点历史:该应用程序是我在1992年用VC4首次编写的语言翻译。代码库通过VC5,VC6,VS2003和VS2008进行,相关的代码段在我切换到VS2012之前从不需要更新。



解释器使用

Thanks for the suggestions. I have found a code solution, but have no clue at present why it matters to the VS2012 compiler. A bit of history: the app is a language interpreter I first wrote in 1992 with VC4. The code base progressed through VC5,VC6,VS2003 and VS2008, and the relevant section of code never required updating until I switched to VS2012.

The interpreter uses
extern LPSTR lpScriptIP; // loaded from the app script code file.

// Here's the section of code that was breaking in VS2012 Release mode. The 
// content of lpScripIP was   "\rI:0x1a"

BOOL CheckPointLabel (VOID)
{
    extern LPSTR lpScriptIP;
	
    /* Check whether point is the start of an identifier or label.
     lpScriptIP does not get modified. */

    if (FALSE == CheckPointIdentifier ())
    {
	 return (FALSE);  
    }

    /* Check whether character before starting point is an EOL: CR, LF or EOF */

    --lpScriptIP;   
	 
    // Call the updated CheckCharEOL that passes the script pointer
    // instead of using the extern pointer.
    // I found that a MessageBox call to report details here was all that
    // required the bug to go away. Similarly, a SetTimer(NULL, NULL,1,NULL); 
    // call would also remove the bug. Neither were an acceptable solution. 
    // Eventually, I updated the call to pass lpScriptIP to the function.
 
    if (FALSE == CheckCharEOL_new (lpScriptIP))
    {
        return (FALSE);  // Point is not the start of a label
    }
    
    ++lpScriptIP;   // Reset script pointer to start of label

    /* Check whether identifier is followed by CHAR_LABEL_END (:) */

    ScanIdentifierEnd();

    if (*lpScriptIP != CHAR_LABEL_END)
	 return (FALSE);
	
    ++lpScriptIP;

    /* Point is the start of a label */

    return (TRUE);
}


// Here's the old and new versions of the CheckCharEOL function.
 
BOOL CheckCharEOL_old (VOID)
{
    extern LPSTR lpScriptIP;

    switch (*lpScriptIP) 
    {
       case CHAR_CR:
       case CHAR_LF:
       case CHAR_EOF:
	 return (TRUE);

       default:
	 return (FALSE);
    }
}

BOOL CheckCharEOL_new (LPSTR lpScript)
{
    switch (*lpScript) 
    {
       case CHAR_CR:
       case CHAR_LF:
       case CHAR_EOF:
	 return (TRUE);

       default:
	 return (FALSE);
    }
}





我无法解释为什么VS2012发布模式有问题。我现在的解决方案已经通过了所有的语言翻译测试,所以我很高兴暂时不管它。



这几乎就像lpScriptIP在传递给CheckCharEOL_old()函数之前没有递减一样。



所有解释这一点的理论都值得赞赏。应用程序语言称为PiXCL。



I'm at a loss to explain why VS2012 Release mode has a problem with this. The solution I now have has passed all the language interpreter tests, so I'm happy to leave it alone for now.

It's almost as though the lpScriptIP was not being decremented before it was passed to the CheckCharEOL_old() function.

All theories to explain this are appreciated. The app language is called PiXCL.


这篇关于VS 2012字节对齐,Release vs Debug的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆