在C中声明私有结构
是否可以声明仅在使用该结构的.c文件中可见的结构类型?我知道,通过将static放在外部数据对象前面,可以将变量的链接更改为内部链接。但是是否可以将static放在新的结构类型的声明前面,如下所示在C中声明私有结构,c,struct,private,C,Struct,Private,是否可以声明仅在使用该结构的.c文件中可见的结构类型?我知道,通过将static放在外部数据对象前面,可以将变量的链接更改为内部链接。但是是否可以将static放在新的结构类型的声明前面,如下所示 static struct log{ ...; ...; }; typedef struct log log; 如果无法将结构类型(如上面的log)设置为“私有”,这是否意味着即使其他源文件不知道该结构的名称(在我的示例中为log)的存在,如果它们将一
static struct log{
...;
...;
};
typedef struct log log;
如果无法将结构类型(如上面的log)设置为“私有”,这是否意味着即使其他源文件不知道该结构的名称(在我的示例中为log)的存在,如果它们将一些变量命名为log,仍可能发生意外的名称冲突(假设我将链接所有对象文件)
编辑:我不熟悉编译器/链接器的工作原理。如果有一个全局变量名log,并且包含全局变量的文件链接到定义了结构log的唯一源文件,链接时会不会造成任何混乱,一个log是一个变量ble名称,而另一个log是类型名称?否。使
结构
私有化的唯一方法是只在使用它的文件中提供它的定义——不要将它放在公共头文件中。如果它只在一个源文件中使用,则只在该源文件中定义它,但如果它在多个源文件中使用文件,您有一个棘手的问题:您可以在每个源文件中定义它,但这很脆弱,因为您必须记住在进行任何更改时更改它的每个实例;或者,您可以在私有头文件中定义它,并确保只有那些源文件包含私有头文件
不同源文件中的名称冲突是可以的,只要它们不试图以任何方式相互接口。如果在一个文件中定义了
struct log
,在另一个文件中定义了不同的struct log
,请不要将一个log
传递给另一个。在C中,结构名称不会变成pa对象文件中的任何符号名称的RT——特别是,没有函数名的名称包含参数类型(如C++),因为函数重载在C.< /P> <非法>代码>静态< /COD>是存储类型;将它应用到变量声明之外的类型是没有意义的。
如果不想在头文件中定义struct log
,则不必这样做。只需将typedef写成:
typedef struct log log;
只要您只处理log*
指针,就足够了。但是,您需要完整的结构定义来声明log
(或采用sizeof(log)
),因为结构的大小取决于它包含的内容
关于名称冲突,请记住结构和类型不是由链接器管理的。链接器只关心全局可见的符号,如函数和变量。也就是说,您可能应该在类型名称上应用前缀(例如,
mylib\u log\t
)为了避免混淆,特别是因为log
是标准库中的一个数学函数。您有理由这样写:
static int a;
因为它阻止链接器与其他地方定义的相结合。链接器与
struct
s无关,因此不必担心放入不同的c文件。只要它在不同的c文件中,就不会有名称混淆。这在一般情况下是不可能的。但我可以想到一种可能在某些编译器上工作的黑客 之所以很难做到这一点,是因为C编译器需要知道结构的外观,以便生成对以结构实例为参数的函数的调用 因此,假设您使用以下标题定义了一个库:
struct foo {
int32_t a, b;
};
foo make_foo(int arg);
foo do_something(foo p1, foo p2);
然后要编译一个调用do_something的程序,你的编译器通常需要知道foo的结构是什么样的,这样它就可以把foo作为一个参数来传递。编译器在这里可以做各种奇怪的事情,比如通过寄存器传递结构的一部分,通过堆栈传递结构的一部分,所以它确实需要知道str是什么结构看起来像
但是,我相信在某些编译器中,可以给出结构应该完全通过堆栈传递的指示。例如,如果您将i386作为目标体系结构(),则regparm(0)
function属性应该适用于GCC
在这种情况下,应该可以这样做:创建头文件的“公共版本”,并在该文件中,而不是布局完整结构,而是创建它的无差别版本:
struct foo {
uint8_t contents[SIZE_OF_STRUCT_FOO];
}
其中,
SIZE\u OF_STRUCT\u FOO
是当您以常规方式定义结构时返回的sizeof(STRUCT FOO)
值。您基本上是说“FOO”是一个具有SIZE\u OF_struct\u FOO
字节的结构。然后,只要调用约定以相同的方式处理这两个结构,它就应该可以工作。因此,在另一个源文件中,我可以定义一个全局变量“int log;”,甚至定义另一个也称为“log”的结构?我认为不能执行“双日志”如果已知日志是类型名。。。