1

I am building a parser using C++ 11/14 (Visual Studio 2015). How do I create and initialize a table within the class, and have it compute the length of the table?

I get the following errors from the compiler:

1>d:\temp\win32project1\win32project1\source1.cpp(49): warning C4200: nonstandard extension used: zero-sized array in struct/union

1> d:\temp\win32project1\win32project1\source1.cpp(49): note: This member will be ignored by a defaulted constructor or copy/move assignment operator

1>d:\temp\win32project1\win32project1\source1.cpp(49): error C2997: 'tlv::_requests': array bound cannot be deduced from an in-class initializer

1> d:\temp\win32project1\win32project1\source1.cpp(45): note: see declaration of 'tlv::_requests'

typedef enum _TLV_TYPE : UINT32
    {
    tlv_type_read,
    tlv_type_write,
    tlv_type_param,
    tlv_type_status
    } TLV_TYPE;

typedef struct
    {
    TLV_TYPE    type;
    UINT32      length;
    } TLV_RECORD, *pTLV_RECORD;

typedef std::function <UINT32 (pTLV_RECORD Record)> pTLV_PARSER;

typedef struct
    {
    TLV_TYPE            type;
    pTLV_PARSER         parse_routine;
    vector <TLV_RECORD> parameters;
    vector <TLV_RECORD> response;
    } TABLE, *pTABLE;

class tlv
{
public:
    tlv (SOCKET Socket);
    ~tlv ();
    UINT32 start_parse (pTLV_RECORD Record);

protected:
    pTLV_PARSER parse_read;
    pTLV_PARSER parse_write;

const TABLE _requests [] =
    {
        {tlv_type_read, parse_read, {{tlv_type_param, 4}, {tlv_type_param, 0}, {tlv_type_param, 4}}, {{tlv_type_status, 4}}},
        {tlv_type_write, parse_write,{{tlv_type_param, 4}}, {{tlv_type_status, 4}}},
    };

};  // End of class tlv
Community
  • 1
  • 1
Brian
  • 305
  • 1
  • 11
  • 1
    Possible duplicate of [C++ typedef member function signature syntax](http://stackoverflow.com/questions/4832275/c-typedef-member-function-signature-syntax) – Barmar Apr 14 '17 at 21:17
  • 4
    Off topic: Most of that `typdef`ing isn't required in C++. – user4581301 Apr 14 '17 at 21:26
  • 3
    `typedef struct/enum _foo { ... } foo;` is an anti-pattern in C++. The proper way to write your definition would be `enum TLV_TYPE : UINT32 { ... };`. The `typedef` crap you're doing is used in C, but not C++. – cdhowie Apr 14 '17 at 21:33
  • This code [compiles fine for me](http://coliru.stacked-crooked.com/a/fbd3ee2eda41d9c7). If you are getting errors, please include them in your question. – cdhowie Apr 14 '17 at 21:36
  • @cdhowie, I am getting these errors: warning C4200: nonstandard extension used: zero-sized array in struct/union note: This member will be ignored by a defaulted constructor or copy/move assignment operator error C2997: 'tlv_::_requests': array bound cannot be deduced from an in-class initializer note: see declaration of 'tlv_::_requests' error C2229: class 'tlv_' has an illegal zero-sized array – Brian Apr 14 '17 at 23:44
  • @Brian What happens if you declare the length of the array? `const TABLE _requests[2] = { ... };` (See [this answer](http://stackoverflow.com/a/29593683/501250) which explains why, according to the standard, object member array lengths cannot be deduced by their initializers. Note that, while G++ accepts the code without a diagnostic, Clang rejects it with the same error you received.) – cdhowie Apr 15 '17 at 02:53
  • @cdhowie, Yes, adding the length of the array works. Thank you for your help! – Brian Apr 15 '17 at 17:25

2 Answers2

0

The type to store a pointer to a member function is declared like that:

typedef int (tlv::*pTLV_PARSER)(pTLV_RECORD Record);

I'm not clear on what exactly your parser functions return, so just used an int data type in declaration

YePhIcK
  • 5,816
  • 2
  • 27
  • 52
0

For the reasons specified in the link provided by @cdhowie in the comments, the array length must be specified because the C++ standard, for reasons best known to the committee, has rather bizarre and non-obvious rules on how member initializers are treated (see the link, and the link in the link), and the interpretation of these rules vary from one compiler to another.

Brian
  • 305
  • 1
  • 11