这个数组如何合法?

时间:2013-12-28 03:05:24

标签: c++ c arrays

CoreAudioTypes.h中,有以下声明:

struct AudioBuffer
{
    UInt32  mNumberChannels;
    UInt32  mDataByteSize;
    void*   mData;
};
typedef struct AudioBuffer  AudioBuffer;

/*!
    @struct         AudioBufferList
    @abstract       A variable length array of AudioBuffer structures.
    @field          mNumberBuffers
                        The number of AudioBuffers in the mBuffers array.
    @field          mBuffers
                        A variable length array of AudioBuffers.
*/
struct AudioBufferList
{
    UInt32      mNumberBuffers;
    AudioBuffer mBuffers[1]; // this is a variable length array of mNumberBuffers elements
} ;
typedef struct AudioBufferList  AudioBufferList;

我的问题与mBuffers AudioBufferList成员有关。它们将它声明为一个大小为1的数组,但它被用作mNumberBuffers所指示的(任何大小)。

这在C和C ++中是不是非法(代码应该在两者中都有效)?

此代码:

int m[1];
m = new int[ 40 ] ;

在C ++中不起作用,那么是什么呢?

修改

这是用法:

bufferList = (AudioBufferList *)malloc(
  sizeof (AudioBufferList) + sizeof (AudioBuffer) * (channelCount - 1) ) ;

所以,用下面的答案解释这个,大小为1的数组就像一个数组......但是数组{{1}中有多个元素(s) }。多么奇怪的黑客。

3 个答案:

答案 0 :(得分:6)

在C中,声明一个元素作为结构成员的数组当然是合法的。访问元素0之外的元素不是非法(在某种意义上,编译器不需要将其诊断为错误),但这样做具有未定义的行为。但由于它是一种常见的习惯用法,称为“结构黑客”,只要你分配足够的内存来容纳其他元素,它就很有效。

1999 ISO C标准添加了一个新功能,灵活数组成员,旨在取代结构黑客,但具有明确定义的行为。使用空方括号[]声明灵活的数组成员。

C ++中的情况类似 - 除了C ++从未采用过灵活的数组成员。 (C ++的通常建议是使用一些容器类(例如vector)而不是原始数组。

comp.lang.c FAQ的问题2.6讨论了结构黑客。

答案 1 :(得分:3)

这在技术上是非法的,或者至少调用未定义的行为,但是GCC会让你安全地执行它,因为它支持相关的Zero-Length Array技术as an extension

通常,您会遵循该技术并使用0的数组维度来完成此任务,但最终结果基本相同。

在C ++中你应该使用一个向量;除了极少数情况外,动态分配确实不会有问题。

答案 2 :(得分:2)

这是'struct hack';它通常有效,尤其是因为它是C99在使用相关但不同的符号建立“灵活阵列成员”之前处理业务的主要方式:

struct AudioBufferList
{
    UInt32      mNumberBuffers;
    AudioBuffer mBuffers[];
};

这些类型不能是数组的元素(当然,它们的指针可以出现在数组中)。出于所有实际目的,必须动态分配此类结构。

这不是标准C ++的一个特性,尽管GNU C ++编译器确实支持它。

'struct hack'不是正式的便携式,不是标准化的。