不灵活的阵列成员 [英] Inflexible array members

查看:70
本文介绍了不灵活的阵列成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


无法在C中返回指向数组类型的指针,因为C没有第一个
类数组类型。但是可以通过非法但广泛支持的零数组结构返回指向包含

不完整数组的结构的指针

hack:


#include< stdlib.h>


typedef struct byte_vector_t byte_vector_t;


struct byte_vector_t {

unsigned char byte [0];

};


int main(){

byte_vector_t * byte_vector = malloc(10) ;

byte_vector-> byte [9] = 42;

返回0;

}


经常声明灵活的数组成员可以替代零数组结构攻击。让我们看看(通过编译文件array.c下面

与GNU C):


#include< stdlib.h>


typedef struct byte_vector_t byte_vector_t;

struct byte_vector_t {

unsigned char byte [];

};


int main(){

byte_vector_t * byte_vector = malloc(10);

byte_vector-> byte [ 9] = 42;

返回0;

}


$ gcc -std = c99 array.c

array.c:6:错误:其他空结构中的灵活数组成员


GCC拒绝编译此代码,因为C99声明(6.7.2.1,

第2段):


结构或联合不得包含具有不完整或

函数类型的成员(因此,结构不应包含

本身的实例,但可能包含指向其自身实例的指针),除了

,具有多个命名成员的结构的最后一个成员可能
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^

的数组类型不完整;这样的结构(以及任何包含,可能是递归的
,这种结构的成员)不应该是结构或数组元素的成员。


第16段重复了这一限制。


结构类型用作自我记录代码并停止
我错误地将指针索引到单个值(反之亦然)。

Typedef也导致自我记录代码但不提供额外的

编译 - 时间类型安全。


这对灵活阵列成员的限制是否合理?核心语法

和语义更好,因为一个数组不应该索引过去元素(而零大小的数组没有元素)。有没有标准的方法

我可以用不完整的数组

成员维护结构的额外类型安全性,而不必用非零大小的标题填充那些结构?非常感谢,

Adam

解决方案

gcc -std = c99 array .c

array.c:6:错误:其他空结构中的灵活数组成员


GCC拒绝编译此代码,因为C99声明(6.7.2.1 ,

第2段):


结构或联合不得包含具有不完整或

函数类型的成员(因此,一个结构不应该包含一个

本身的实例,但可能包含一个指向其自身实例的指针,除了

,结构的最后一个成员有一个以上指定成员可能

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

有不完整的数组类型;这样的结构(以及任何包含,可能是递归的
,这种结构的成员)不应该是结构或数组元素的成员。


第16段重复了这一限制。


结构类型用作自我记录代码并停止
我错误地将指针索引到单个值(反之亦然)。

Typedef也导致自我记录代码但不提供额外的

编译 - 时间类型安全。


这对灵活阵列成员的限制是否合理?核心语法

和语义更好,因为一个数组不应该索引过去元素(而零大小的数组没有元素)。有没有标准的方法

我可以用不完整的数组

成员维护结构的额外类型安全性,而不必用非零大小的标题填充那些结构?非常感谢,

Adam


Adam Warner写道:


大家好,


无法在C中返回指向数组类型的指针,因为C没有第一个
类数组类型。



当然可以。通常,你不是真的想要,但它是可能的。


typedef char array [10];

array * f(void ){

/ * ... * /

}


您也可以在没有typedef的情况下编写它


char(* f(无效))[10] {

/ * ... * /

}


你也可以省去大小。


typedef char array [];

array * f(void){

/ * ... * /

}





char(* f(虚空))[] {

/ * ... * /

}


其余信息似乎之后无关紧要。


2006年7月8日星期六00:32:05 -0700,Harald van D?3k写道:


Adam Warner写道:


>大家好,

一个人无法返回指针C中的数组类型,因为C没有第一类数组类型。



当然可以。通常,你不是真的想要,但它是可能的。


typedef char array [10];

array * f(void ){

/ * ... * /

}


您也可以在没有typedef的情况下编写它


char(* f(无效))[10] {

/ * ... * /

}


你也可以省去大小。


typedef char array [];

array * f(void){

/ * ... * /

}





char(* f(无效))[] {

/ * ... * /

}



优秀!谢谢你的更正。


#include< stdint.h>

#include< stdlib.h>


typedef uint8_t octet_vector_t [];


int main(){

octet_vector_t * vector = malloc(10);

(* vector)[9] = 42;

返回0;

}


如果有,请告诉我'是一种避免每个阵列访问的显式解除引用

语法的方法。


问候,

Adam


Hi all,

One cannot return a pointer to an array type in C because C has no first
class array types. But one can return a pointer to a struct containing an
incomplete array via the illegal but widely supported zero array struct
hack:

#include <stdlib.h>

typedef struct byte_vector_t byte_vector_t;

struct byte_vector_t {
unsigned char byte[0];
};

int main() {
byte_vector_t *byte_vector=malloc(10);
byte_vector->byte[9]=42;
return 0;
}

It is frequently stated that flexible array members are a substitute for
the zero array struct hack. Let''s see (by compiling file array.c below
with GNU C):

#include <stdlib.h>

typedef struct byte_vector_t byte_vector_t;

struct byte_vector_t {
unsigned char byte[];
};

int main() {
byte_vector_t *byte_vector=malloc(10);
byte_vector->byte[9]=42;
return 0;
}

$ gcc -std=c99 array.c
array.c:6: error: flexible array member in otherwise empty struct

GCC refuses to compile this code because C99 states (6.7.2.1,
paragraph 2):

A structure or union shall not contain a member with incomplete or
function type (hence, a structure shall not contain an instance of
itself, but may contain a pointer to an instance of itself), except
that the last member of a structure with more than one named member may
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
have incomplete array type; such a structure (and any union containing,
possibly recursively, a member that is such a structure) shall not be a
member of a structure or an element of an array.

This restriction is repeated in paragraph 16.

The struct types are intended to serve as self-documenting code and stop
me from incorrectly indexing a pointer to a single value (and vice versa).
Typedefs also lead to self-documenting code but provide no additional
compile-time type safety.

Is this restriction upon flexible array members sensible? The core syntax
and semantics are better because one should not index past the elements of
an array (and a zero sized array has no elements). Is there a standard way
I can maintain the extra type safety of structs with an incomplete array
member without having to pad those structs with a non-zero sized header?

Many thanks,
Adam

解决方案

gcc -std=c99 array.c
array.c:6: error: flexible array member in otherwise empty struct

GCC refuses to compile this code because C99 states (6.7.2.1,
paragraph 2):

A structure or union shall not contain a member with incomplete or
function type (hence, a structure shall not contain an instance of
itself, but may contain a pointer to an instance of itself), except
that the last member of a structure with more than one named member may
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
have incomplete array type; such a structure (and any union containing,
possibly recursively, a member that is such a structure) shall not be a
member of a structure or an element of an array.

This restriction is repeated in paragraph 16.

The struct types are intended to serve as self-documenting code and stop
me from incorrectly indexing a pointer to a single value (and vice versa).
Typedefs also lead to self-documenting code but provide no additional
compile-time type safety.

Is this restriction upon flexible array members sensible? The core syntax
and semantics are better because one should not index past the elements of
an array (and a zero sized array has no elements). Is there a standard way
I can maintain the extra type safety of structs with an incomplete array
member without having to pad those structs with a non-zero sized header?

Many thanks,
Adam


Adam Warner wrote:

Hi all,

One cannot return a pointer to an array type in C because C has no first
class array types.

Sure you can. Typically, you won''t really want to, but it''s possible.

typedef char array[10];
array *f(void) {
/* ... */
}

You can also write it without a typedef as

char (*f(void))[10] {
/* ... */
}

You can also leave out the size.

typedef char array[];
array *f(void) {
/* ... */
}

or

char (*f(void))[] {
/* ... */
}

The rest of your message seems irrelevant after that.


On Sat, 08 Jul 2006 00:32:05 -0700, Harald van D?3k wrote:

Adam Warner wrote:

>Hi all,

One cannot return a pointer to an array type in C because C has no first
class array types.


Sure you can. Typically, you won''t really want to, but it''s possible.

typedef char array[10];
array *f(void) {
/* ... */
}

You can also write it without a typedef as

char (*f(void))[10] {
/* ... */
}

You can also leave out the size.

typedef char array[];
array *f(void) {
/* ... */
}

or

char (*f(void))[] {
/* ... */
}

Excellent! Thank you for the correction.

#include <stdint.h>
#include <stdlib.h>

typedef uint8_t octet_vector_t[];

int main() {
octet_vector_t *vector=malloc(10);
(*vector)[9]=42;
return 0;
}

Please let me known if there''s a way to avoid the explicit dereferencing
syntax for every array access.

Regards,
Adam


这篇关于不灵活的阵列成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆