Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.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_Arrays_Linker_Constants_Incomplete Type - Fatal编程技术网

C-访问链接文件中的不完整类型

C-访问链接文件中的不完整类型,c,arrays,linker,constants,incomplete-type,C,Arrays,Linker,Constants,Incomplete Type,我在C语言中链接多个文件时遇到了一个问题。我想在编译时定义一个表示数组长度的常量,但用户每次都要在文件中实现它 要点如下: h-定义一些常量 extern const int data[]; extern const int DATA_SIZE; //other functions, not relevant int get_second_item(void); library_data.c-实现data.h中的一些函数 #include "data.h" const int DATA_SIZ

我在C语言中链接多个文件时遇到了一个问题。我想在编译时定义一个表示数组长度的常量,但用户每次都要在文件中实现它

要点如下:

h-定义一些常量

extern const int data[];
extern const int DATA_SIZE;
//other functions, not relevant
int get_second_item(void);
library_data.c-实现data.h中的一些函数

#include "data.h"
const int DATA_SIZE = sizeof(data) / sizeof(data[0]); 
//can't compile because data is an incomplete type and hasn't been defined yet

int get_second_item(void) 
{
    return data[1];
}
public_data.c-用户使用其数据更改此设置

#include "data.h"
const int data[] = {1, 2, 3};
library_data.c和data.h首先编译为.o文件,而其他库文件#包括data.h,因此需要使用data_SIZE。移动的

const int DATA_SIZE = sizeof(data) / sizeof(data[0]) 

公开_data.c当然可以,但不是一个好的解决方案。

您不能在未指定大小的
extern
数组上使用
sizeof
(例如
extern const int data[];

发件人:

未指定大小的外部数组是不完整类型;你不能 对其应用sizeof。sizeof在编译时运行,并且没有 它了解在另一个数组中定义的数组大小的方法 文件

您有三种选择:

  • 声明一个包含数组大小的伴随变量,该变量在同一源文件中定义并初始化(使用sizeof),其中 数组定义如下:

    file1.c:file2.c:

    int数组[]={1,2,3};外部内部数组[]
    int-arraysz=sizeof(数组);外部内部arraysz

    (另见问题6.23。)

  • #为大小定义清单常量,以便在定义和外部声明中一致使用:

    file1.h:

    #定义ARRAYSZ 3

    extern int数组[ARRAYSZ]

    file1.c:file2.c:

    #包括“file1.h”#包括“file1.h”

    int数组[ARRAYSZ]

  • 在数组的最后一个元素中使用一些sentinel值(通常为0、-1或NULL),这样代码就可以在不使用显式 尺寸指示:

    file1.c:file2.c:

    int数组[]={1,2,3,-1};外部内部数组[]


  • 一种解决方案可能是在data.c中添加一个初始化函数,然后您必须确保在生成任何程序时调用该函数来准备数据大小

    int initupdate_datasize() {
    
      DATA_SIZE = sizeof(data) / sizeof(data[0]);
    
      return 0;
    
    }
    
    您必须从data.h和library_data.c中删除常量

    另一种方法是传递一个编译器定义,例如-DDATASZ=96,您将获得所有需要它的源文件。对于任何给定的平台,如果很少更改,您可以手动更新它,或者您甚至可以创建一个测试数据大小程序,该程序将从initupdate_datasize函数(或者类似的C宏)输出数据大小。根据您的构建系统,应该可以将该参数作为编译器定义传递

    例如,在Makefile中,如果您使用GNU make,这可能会有所帮助:

    DATA_SIZE = $(shell ./test-datasize)
    
    CFLAGS = -O3 -Wall -DDATASZ=$(DATA_SIZE)
    

    为什么不在同一个文件中定义
    data[]
    data\u SIZE
    (即public\u data.c,顾名思义,这似乎是一个合适的位置)?考虑到无论数据是什么,定义public\u数据的每个人都必须定义数据大小,这很麻烦。我知道这是一个解决方案,而且会起作用,但我想知道是否有更好的方法可以解决这个问题,用户只需定义他们的数据,库就可以处理其余的数据。“更好”的方法是首先避免全局变量,并将数据和数据量作为各种API的参数进行传递。作为一种可怕而卑鄙的做法,你可以要求用户通过你提供的一个宏定义他们的
    数据
    ,而这个宏对他们来说是隐藏的,并且还规定了幅值常数。然而,我强烈建议不要对未来的代码维护者进行如此残酷的惩罚。为什么不让数据大小成为一个函数呢?或者制作一个类来保存您需要的抽象,怎么样。@JonathanKelsey不清楚您这里所说的“类”是什么意思。谢谢-这3个解决方案就是我提出的,但不幸的是,它们都要求另一端的用户做些什么。也许extern int arraysz是最好的解决方案。