I am writing a low-lewel data manipulation code in C++ 11 and I want to use an old-known C feature of flexible arrays at the end of the struct (see some info here).
struct variableCell
{
/**
* @brief Size in bytes of following data.
*/
std::uint32_t cellSize;
/**
* @brief Data stored in overlay.
*/
std::uint8_t cellData[];
};
Once I use GCC with the paramaters
-Wall -pedantic -std=c++11
I get this waring
xxx.h:xx: warning: ISO C++ forbids zero-size array 'variableCell' [-Wpedantic]
This used to be a perfectly correct feature. Please, do not tell me that my approach is wrong - it is and always has been correct way for low-level data manipulation.
Why the standard changed this and how to disable just this one particular warning?
Thanks
Edit:
My apologies, I mistaken the C only feature which turned to be one of the exceptions which does not the C++ include. I will consider using a different approach. But just for my curiosity, which compilers allows this as a non-standard extension and how to make them accept it without the warning?
Thanks
As reference Incompatibilities Between ISO C and ISO C++ states in Flexible array members section:
C++ does not support flexible array members.
(This feature might be provided as an extension by some C++ compilers, but would probably be valid only for POD structure types.)
gcc does support this as an extension as well as clang. Apparently this also works in Visual Studio - see it live if you don't use /Za
which I can find any documentation on besides this post by Stephan T. Lavavej.
I don't think there is a portable way to silence the warning, but something like Partially disable pedantic warnings in gcc within source should work for gcc
.
You can emulate it with c++ with a custom operator new
struct VariableCell {
VariableCell( std::uint32_t sz ) : cellSize(sz) {}
std::uint8_t* data() { return reinterpret_cast<std::uint8_t*>(this+1); }
static void* operator new(std::size_t sz, std::uint32_t dataSz) {
return ::operator new(sz+dataSz);
}
private:
std::uint32_t cellSize;
};
std::unique_ptr<VariableCell> CreateVariableCell( std::uint32_t size ) {
return std::unique_ptr<VariableCell>{ new (size) VariableCell{size} };
}
You have to check which standards, C++11 still disallows 0-length arrays (§8.3.4/1), and also C99 (§6.7.5.2/1). It seems they're a C only feature, but I'd rather say an old C hack. Are you sure you can't find a better solution for that?