Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中声明私有结构_C_Struct_Private - Fatal编程技术网

在C中声明私有结构

在C中声明私有结构,c,struct,private,C,Struct,Private,是否可以声明仅在使用该结构的.c文件中可见的结构类型?我知道,通过将static放在外部数据对象前面,可以将变量的链接更改为内部链接。但是是否可以将static放在新的结构类型的声明前面,如下所示 static struct log{ ...; ...; }; typedef struct log log; 如果无法将结构类型(如上面的log)设置为“私有”,这是否意味着即使其他源文件不知道该结构的名称(在我的示例中为log)的存在,如果它们将一

是否可以声明仅在使用该结构的.c文件中可见的结构类型?我知道,通过将static放在外部数据对象前面,可以将变量的链接更改为内部链接。但是是否可以将static放在新的结构类型的声明前面,如下所示

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”的结构?我认为不能执行“双日志”如果已知日志是类型名。。。