在编写大型代码库的一些测试和分析过程中,我不得不用自己的方法替换对 alloca() 的数千次调用。在我的目标平台上,如果数字为零,alloca() 将失败,因此我们要断言是这种情况。我们还希望提供一个单一调用的对齐版本。但是, alloca() 具有与范围相关的特定生命周期,所以虽然我想写
void * CheckAndAllocate( size_t sizeInBytes )
{
assert( sizeInBytes > 0 );
return alloca(p); // not safe; allocation goes out of scope on return
}
void * p = CheckAndAllocate( sizeInBytes );
显然,这不是一个选项,因为 alloca() 不会超过 CheckAndAllocate()。
在解决这个问题的过程中,我使用临时写了这个替代方案:
struct CheckSize
{
inline CheckSize( size_t size ) { assert( size > 0 ); }
inline void * operator=(void* other) { return other );
}
#define my_alloca(size) CheckSize(size) = alloca(size)
void foo(size_t size)
{
void * p = my_alloca(size);
// becomes
void * p = CheckSize(size) = alloca(size);
// ... use p locally for work
}
此外,我还将对齐版本定义为:
struct CheckSizeAndAlign
{
size_t _align;
inline CheckSizeAndAlign( size_t size, size_t align ) : _align(align) { assert( size > 0 ); }
inline void * operator=(void* other) { return AlignUp(other, _align ); }
#define my_alloca_aligned( size, align ) CheckSizeAndAlign(size, align ) = alloca(size + align)
void foo(size_t size, size_t alignment)
{
void * p = my_alloca_aligned( size, alignment);
// becomes
void * p = CheckSizeAndAlign( size, alignment) = alloca( size + alignment )
// ... use p locally for work
}
我的问题是 - 鉴于 alloca 返回的值是通过临时的,这是否因为任何类型的作用域而违反了 alloca 的分配?
我认识到 alloca 存在缺陷,并且有多种解决方案可以解决此问题,但我希望将这些更改注入代码库而不更改任何其他内容,而只是添加一些诊断。
我也只是对这种特定模式感到好奇。
这是 MSVC2019、CLANG 和小众实时系统编译器。