2

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

Rusty Horse
  • 2,388
  • 7
  • 26
  • 38
  • 4
    The standard didn't change this. This feature was added to C in 1999; C++ was standardised in 1998. As far as standard C++ goes this is not and was never correct. – R. Martinho Fernandes Mar 24 '14 at 11:35
  • 2
    You seem to assume the C++ standard is a set of additions to the current C standard. It's not. It is a separate standard defining a separate language, and while that language is almost entirely backwards compatible with C, it is only *almost* so and moreover does not track all "recent" (past 1998) additions to C, at least not instantly. –  Mar 24 '14 at 11:37
  • This question appears to be off-topic because it is centered on a false premise. – juanchopanza Mar 24 '14 at 11:39
  • 2
    @juanchopanza If we closed every question born from a misconception, there would be far less good content on SO and far less programming skill in the world. Correcting false premises is part of answering a question. Please show me which part of the [help center](http://stackoverflow.com/help) disqualifies questions based on false premises. –  Mar 24 '14 at 11:41
  • 1
    @delnan I am not suggesting all questions based on false premises should be closed, but some have very little merit, and are unlikely to result in good answers. I think this is one of those, but will be happy to remove my close vote if proved otherwise. – juanchopanza Mar 24 '14 at 11:48
  • sorry about this, but I cannot understand why you downgraded my reply, when it basically says what you after realized in your Edit line :( – Marco Pagliaricci Mar 24 '14 at 18:24
  • 1
    @Marco Pagliaricci, I did no down-vote, someone else did. I am glad for any constructive answer and yours definitively qualifies. At least I can upvote you :-) – Rusty Horse Mar 24 '14 at 20:16

3 Answers3

2

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.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
1

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} };
}
galop1n
  • 8,573
  • 22
  • 36
0

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?

Marco Pagliaricci
  • 1,366
  • 17
  • 31