sizeof()的值是由编译器还是链接器确定的?

4
我是一名有用的助手,可以为您翻译文本。

我正在尝试解决一个C++问题,其中我的代码的两个部分返回sizeof()运算符的不同结果。

以下是我运行的内容:

MyClass* foo = new MyClass();
int size = sizeof(*foo)

我将这段代码放在项目的两个不同部分,得到了两个不同的结果。一次是2254,另一次是2284。我可以查看内存布局,其中一个区域显示内部成员按字节对齐,而另一个区域则按字对齐。
我查看反汇编代码并发现sizeof()值实际上是机器码的一部分。这是编译器或链接器中的错误吗?为什么同一项目的两个部分会以不同方式查看相同的类?
编辑:
让我提供一个更清晰的示例,以表明这不是ODR违规。
我刚刚创建了一个全新的类,如下所示:
class TestAlignClass
{
public:  
    TestAlignClass() { }
    ~TestAlignClass() { }

private:
    char charArray[3];
    int myInt;
};

如果类对齐到4,则应返回sizeof() = 8,这正是我想要的。但我的代码中有某些类返回sizeof() = 7。
实际上,当我进入new()运算符时,有时它会分配7个字节,有时它会分配8个字节。
我正在将几个项目链接在一起,起初我以为这与项目设置有关,但同一项目的不同部分将显示差异。

2
sizeof(whatever)的大小由编译器决定。为什么会发生这种情况 - 我不知道,可能是ODR违规? - jrok
2
很明显 sizeof 函数运行正常:你以某种方式有两个 MyClass 的定义,一个是按字节对齐的,一个则不是。 - alexis
4
像往常一样,始终假设错误出现在你的代码中,而不是编译器中。 - Mooing Duck
你能提供一个最小化的示例来演示问题吗? - John Dibling
很不幸,它正在被交叉编译为一个嵌入式系统,并且使用了其他几个第三方库。我会尝试提供一个更好的实例。 - Dan
显示剩余5条评论
1个回答

8

sizeof 在编译时计算。

至于为什么相同的构造在两个不同的地方返回不同的值,这可能是因为类在不同的翻译单元中被定义了不同的方式。我首先会查看的一个地方是包装方式。如果一个TU中有一个 #pragma pack (1) 类型表达式而另一个没有,则可以解释这种差异。它也可能表示违反了一个定义规则,但这是另一回事。

另一个也许更奇特的要查找的地方是存在影响类的内容的 #ifdef 类型宏。

正如 @MooingDuck 在评论中所指出的那样,极有可能是您代码中的错误。不要认为编译器出现了问题。


请查看我的测试类编辑。没有使用#ifdef。我想看看是否有任何杂散的#pragma packs被包含进来了。 - Dan
@DanQ: 我看到了。我正在考虑。由于您说它发生在单个模块中,并且您确信它不是ODR违规,所以您能否提供一个完整但最小的示例来演示问题? - John Dibling
2
@DanQ:顺便说一下,sizeof返回7强烈暗示了某处正在进行打包。现代CPU不会在7字节边界上对齐。 :)(免责声明:我不做嵌入式系统。买家自负。) - John Dibling
@DanQ 无论是嵌入式还是非嵌入式,交叉编译还是非交叉编译,除非你的编译器真的很奇怪和非标准化,否则这不应该成为问题。请尽可能提供更多信息(编译器、版本、主机和目标平台等等...当然,最少量的代码也是一个好的补充)。 - syam
好的,之前我的main()函数返回sizeof() = 7。我清空了所有的包含文件,只留下了我的测试类,现在它返回8了。一定是某个包含文件中有一个流氓的#pragma指令。感谢你让我想起来这一点。现在我只需要找出是哪一个... - Dan
@DanQ:嗯,你已经完成了一半。试着让编译器为你完成这项工作。或者使用grep命令。祝你好运。 - John Dibling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接