是否有可能声明结构类型,它是唯一可见在使用结构中.c文件?我知道,通过把静态的外部数据对象的面前,你改变变量的联动,是内部的。但是,它可能把静中有新的结构类型的声明前,如下所示?
static struct log{
...;
...;
};
typedef struct log log;
如果它是不可能使结构类型,比如说如上日志,是“私人”,这是否意味着即使其他源文件不知道名字的存在(这是在我的例子日志)结构的如果他们说出一些变量日志(假设我将链接所有目标文件)意外的名称冲突仍然发生呢?
编辑:我不熟悉的编译器/连接器是如何工作的。如果有一个全局变量名的日志,并包含全局变量与在结构日志定义的唯一来源文件的文件,也不会引起任何混乱链接时,一个日志,而另一个日志中的变量名是一种叫什么名字?
号作出struct
私人唯一的办法是只在使用它的文件中提供的定义 - 不要把它放在一个公共的头文件。如果它在一个源文件中只使用,那么只需把它定义在源文件中,但如果它在多个源文件中使用,你有一个棘手的问题:你可以在每一个源文件中定义它,但这是脆弱的,因为你有要记住,当你做任何改变来改变它的每一个实例;或者,你可以在私人头文件中定义它,并确保只有那些源文件包括私有头。
在不同的源文件名冲突是正常的,只要他们不试图以任何方式相互连接。如果你在一个文件中,并在不同的文件struct log
的不同定义所定义的struct log
,永远不要通过一个log
到其他。在C语言中,结构的名字不会成为目标文件中的任何符号名称的一部分 - 尤其是有函数名称没有名称重整包括的参数类型(如C ++一样),因为函数重载是非法C.
号static
是存储型;这是没有意义的将其应用到一个类型的变量声明之外。
如果你不想来定义你的头文件struct log
,你不必。简单地写的typedef为:
typedef struct log log;
就足够了,只要你只log *
指针处理。但是,您将需要结构的完整定义来声明log
(或采取sizeof(log)
),由于结构的大小取决于它所包含的内容。
对于名称冲突,记住,结构和类型不通过链接进行管理。链接器只关心全局可见的符号,如函数和变量。话虽这么说,你应该申请一个前缀为您的类型名称(例如,mylib_log_t
),以避免混淆,特别是因为log
是在标准库数学函数。
你有理由这样写:
static int a;
因为它防止连接器将其与定义的其他地方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是什么样的,所以它可以把它作为一个参数。编译器可以做各种奇怪的事情在这里,就像通过堆栈通过寄存器和部分传递结构的一部分,所以它真正需要知道的结构是什么样子。
但是,我认为,在一些编译器,可以给其结构应通过堆栈完全传递的指示。例如,regparm(0)
功能属性应海湾合作委员会的工作,如果你已经I386作为你的目标体系(docs)。
在这种情况下,它应该可以做这样的事情:创建头文件的“公版”,并在该文件中,而不是摆出完整的结构,你创建它的一个未分化的版本:
struct foo {
uint8_t contents[SIZE_OF_STRUCT_FOO];
}
其中SIZE_OF_STRUCT_FOO
是什么sizeof(struct foo)
返回时您可以定义通常的方式结构。你是那么基本上说,“富”是SIZE_OF_STRUCT_FOO
字节的结构。然后,只要调用约定以同样的方式对待这两个结构中,它应该工作。