在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) }。多么奇怪的黑客。
答案 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'不是正式的便携式,不是标准化的。