# 1. 什么是零长度数组？

int a[10];

C99 标准规定：可以定义一个变长数组。

int len;
int a[len];

#include <stdio.h>
int main()
{
int len;
printf("input array len:");
scanf("%d", &len);
int a[len];
for (int i = 0; i < len; i++) {
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}
printf("array print:\n");
for (int i = 0; i < len; i++) {
printf("a[%d] = %d\n", i, a[i]);
}
return 0;
}

GNU C 可能觉得变长数组还不过瘾，又扩展支持【零长度数组】。

int a[0];

#include <stdio.h>
struct buffer {
int len;
int a[0];
};
int main()
{
printf("%d\n",sizeof(struct buffer));
return 0;
}

# 2. 使用示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct buffer {
int len;
int a[0];
};
int main()
{
struct buffer *buf = NULL;
buf = (struct buffer *)malloc(sizeof(struct buffer) + 20);
if (!buf) {
printf("ERROR(%s): malloc buf error!\n", __func__);
return -1;
}
printf("%d\n",sizeof(struct buffer));
buf->len = 20;
strcpy(buf->a, "hello world!\n");
puts(buf->a);
free(buf);
return 0;
}

# 3. 内核中的零长度数组

struct urb {
/* private: usb core and host controller only fields in the urb */
struct kref kref;  /* reference count of the URB */
void *hcpriv;   /* private data for host controller */
atomic_t use_count;  /* concurrent submissions counter */
atomic_t reject;  /* submissions will fail */
int unlinked;   /* unlink error code */
/* public: documented fields in the urb that can be used by drivers */
struct list_head urb_list; /* list head for use by the urb's
* current owner */
struct list_head anchor_list; /* the URB may be anchored */
struct usb_anchor *anchor;
struct usb_device *dev;  /* (in) pointer to associated device */
struct usb_host_endpoint *ep; /* (internal) pointer to endpoint */
unsigned int pipe;  /* (in) pipe information */
unsigned int stream_id;  /* (in) stream ID */
int status;   /* (return) non-ISO status */
unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/
void *transfer_buffer;  /* (in) associated data buffer */
dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
struct scatterlist *sg;  /* (in) scatter gather buffer list */
int num_mapped_sgs;  /* (internal) mapped sg entries */
int num_sgs;   /* (in) number of entries in the sg list */
u32 transfer_buffer_length; /* (in) data buffer length */
u32 actual_length;  /* (return) actual transfer length */
unsigned char *setup_packet; /* (in) setup packet (control only) */
dma_addr_t setup_dma;  /* (in) dma addr for setup_packet */
int start_frame;  /* (modify) start frame (ISO) */
int number_of_packets;  /* (in) number of ISO packets */
int interval;   /* (modify) transfer interval
* (INT/ISO) */
int error_count;  /* (return) number of ISO errors */
void *context;   /* (in) context for completion */
usb_complete_t complete; /* (in) completion routine */
struct usb_iso_packet_descriptor iso_frame_desc[0];/* (in) ISO ONLY */
};

struct usb_iso_packet_descriptor iso_frame_desc[0];

USB 摄像头一般会支持多种分辨率，不同的分辨率视频传输，一帧图像的数据大小是不一样的，对于USB 传输的数据包大小和个数需求也不一样。那么USB 到底该如何设计，才能在不影响 USB 其他传输模式的前提下，适配不同大小的数组传输需求呢？

# 4. 指针与零长度数组

struct buffer1 {
int len;
int a[0];
};
struct buffer2 {
int len;
int *a;
};
int main(void)
{
printf("buffer1: %d\n", sizeof(struct buffer1));
printf("buffer2: %d\n", sizeof(struct buffer2));
}

buffer1: 4
buffer2: 8

int array1[10] = {1,2,3,4,5,6,7,8,9};
int array2[0];
int *p = array1[5];
int main()
{
return 0;
}

MIPS 下编译与反汇编：

mips-linux-gnu-gcc -m32 gnu2.c
mips-linux-gnu-objdump -D a.out > a.dump

004107c0 <array1>:
4107c0:   00000001    movf    zero,zero,\$fcc0
4107c4:   00000002    srl zero,zero,0x0
4107c8:   00000003    sra zero,zero,0x0
4107cc:   00000004    sllv    zero,zero,zero
4107d0:   00000005    lsa zero,zero,zero,0x1
4107d4:   00000006    srlv    zero,zero,zero
4107d8:   00000007    srav    zero,zero,zero
4107dc:   00000008    jr  zero
4107e0:   00000009    jalr    zero,zero
4107e4:   00000000    nop
004107e8 <p>:
4107e8:   004107d4    0x4107d4
4107ec:   00000000    nop
Disassembly of section .rld_map:

# 5. 总结

|

GNU C 扩展语法：关键字__attribute__ 使用
GNU C 扩展语法：关键字__attribute__ 使用
212 0
|

GNU C 扩展语法：指定初始化与语句表达式
GNU C 扩展语法：指定初始化与语句表达式
208 0
|
API C语言 开发者
|
2月前
|

GCC 编译器 详细总结
GCC 编译器 详细总结
47 0
|
2月前
|
NoSQL 编译器 开发工具
006.gcc编译器
gcc是什么？
61 0
|
2月前
|

524 1
|
16天前
|

GCC：GNU编译器
GCC：GNU编译器
15 0