gpt4 book ai didi

c - 是否允许链接器忽略两个结构定义不相等?

转载 作者:太空狗 更新时间:2023-10-29 16:06:05 25 4
gpt4 key购买 nike

如果您有两个使用相同结构 A 的翻译单元,您通常将该结构放在 header 中,即。 e.让预处理器将定义粘贴到两个 TU 中。

那么假设我们不这样做。我们可以使用不同的定义吗?为什么?

createA.c:

typedef struct {
int data;
} A;

A createA() {
A a = {10};
return a;
}

主.c:

#include <stdio.h>

typedef struct {
int value;
float x;
} A;

A createA();

int main(int argc, char *argv[])
{
A a = createA();
printf("value is %d, x is %f\n", a.value, a.x);
a.x = 3.1f;
printf("value is %d, x is %f\n", a.value, a.x);
}

VS 10 似乎很乐意将其链接在一起,即使这两个结构的大小不同。这意味着对 createA 的调用在两个 TU 中的工作方式不同(不同的堆栈修改)。这有点奇怪。当我向函数添加参数时,程序在运行时崩溃,但仍然没有链接器错误。

那么,为什么这很有趣?我想知道是否不能将这种机制用于 Pimpl 变体,而不是 impl* impl_data 你会在公共(public) header ,并转换为实现文件中的实际 impl 结构。除了实际考虑(例如确定 impl_size),这是否允许?

最佳答案

链接器不知道结构是如何定义的。或者甚至存在结构。链接器所关心的只是解析带有外部链接的名称,而结构是编译时的产物。

链接器也不知道函数原型(prototype)。所以它不知道在某个翻译单元中调用的函数的参数是否实际上对应于编译到不同翻译单元中的函数所期望的参数。链接器要做的就是确保调用调用具有该名称的函数。

因此链接器当然可以忽略一些错误。但这并不能使错误正确。它们仍然是错误。作为程序员,您有责任确保您的程序正确,并且一个翻译单元中的结构定义和原型(prototype)与另一个翻译单元中的结构定义和原型(prototype)兼容。 C不会充当你的守护天使。

这可能看起来并不完全用户友好,而且在很多方面也并非如此。有些语言旨在检测这样的错误。但是 C 没有那种理念。

关于使用struct s { char _[sizeof_struct_s]的具体例子; }; 在一个翻译单元中,而真正的 struct s 在另一个翻译单元中,结果是未定义的行为,不需要错误消息。所以它不应该用在一致的可移植代码中。尽管如此,如果您可以保证字符数组的适当对齐并且您可以正确计算大小(这将是一个很大的可维护性问题),它可能适用于许多体系结构。当然,没有任何保证,如果它坏了,你可以保留碎片。

关于c - 是否允许链接器忽略两个结构定义不相等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36483757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com