不灵活的阵列成员 [英] Inflexible array members
问题描述
大家好,
无法在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屋!