NO

Author Topic: structure initialization refused by pocc  (Read 7350 times)

japheth

  • Guest
structure initialization refused by pocc
« on: June 16, 2009, 10:34:09 PM »

Hello,

I tried to compile JWasm with PellesC. Almost everything compiles without errors, with one exception. The issue is the initialization of a structure which contains 2 bitfields and a character array of "unknown" size:

Code: [Select]

#include <stdio.h>

typedef unsigned int uint_32;
typedef unsigned char uint_8;

typedef struct line_item {
    struct line_item *next;
    uint_32 lineno:20, srcfile:12;
    uint_32 list_pos; /* position .LST file */
    uint_8 macrolevel; /* just a bit (macrolevel > 0?) is needed */
    char line[];
} line_item;

line_item endl = { NULL, 0, 0, 0, 0, "END" };

pocc complains:

main3.c(15): warning #2213: Multiple initializers for the same element (at offset 13).
main3.c(15): error #2139: Too many initializers.

while MSVC, OW and gcc don't see a problem.

How is this supposed to be defined in Pelles C ?


Offline Robert

  • Member
  • *
  • Posts: 247
Re: structure initialization refused by pocc
« Reply #1 on: June 17, 2009, 07:44:06 AM »
I would guess that

uint_32 lineno:20, srcfile:12;

is not being parsed as expected

Does

uint_32 lineno:20;
uint_32 srcfile:12;

compile with Pelle's C without warning or error?

Robert Wishlaw

Offline AlexN

  • Global Moderator
  • Member
  • *****
  • Posts: 394
    • Alex's Link Sammlung
Re: structure initialization refused by pocc
« Reply #2 on: June 17, 2009, 07:56:14 AM »
I have tried something with your code. I my opion the error message are not related to the bitfields (when you remove the bitfield size you get the same error message). The problem seem to be the empty char array. If you use an empty string instead of "END" it compiles.
But at the moment I have no good solution for you. Is it possible to use a pointer to the char array?
best regards
 Alex ;)

japheth

  • Guest
Re: structure initialization refused by pocc
« Reply #3 on: June 17, 2009, 08:24:26 AM »
But at the moment I have no good solution for you. Is it possible to use a pointer to the char array?

No, that's not an option. There's a workaround, of course, but since the item's size is actually defined by the length of the <line> member, it's rather ugly and needs dynamic allocation:

Code: [Select]
#ifdef __POCC__
        line_item *endl = AsmAlloc( sizeof( line_item ) + 4 );
        endl->next = NULL;
        endl->srcfile = 0;
        endl->lineno = LineNumber;
        endl->list_pos = 0;
        strcpy( endl->line, "END");
        LineStoreHead = endl;
#else
        endl.lineno = LineNumber;
        LineStoreHead = &endl;
#endif

JohnF

  • Guest
Re: structure initialization refused by pocc
« Reply #4 on: June 17, 2009, 11:45:43 AM »
Can't you declare the string var to have the right size?

Code: [Select]
typedef struct line_item {
    struct line_item *next;
    uint_32 lineno:20, srcfile:12;
    uint_32 list_pos; /* position .LST file */
    uint_8 macrolevel; /* just a bit (macrolevel > 0?) is needed */
    char line[4];
} line_item;

John

japheth

  • Guest
Re: structure initialization refused by pocc
« Reply #5 on: June 18, 2009, 10:03:10 AM »
Can't you declare the string var to have the right size?

No, it's variable. The sample which I posted is a test case only.

Offline AlexN

  • Global Moderator
  • Member
  • *****
  • Posts: 394
    • Alex's Link Sammlung
Re: structure initialization refused by pocc
« Reply #6 on: June 18, 2009, 01:28:21 PM »
No, it's variable. The sample which I posted is a test case only.

I think this is also no good solution for your example?

Code: [Select]
char line[] = {"\0\0\0\0\0\0\0\0\0\0\0\0\0END"};
line_item *uendl = (line_item *)line;
:)
best regards
 Alex ;)

JohnF

  • Guest
Re: structure initialization refused by pocc
« Reply #7 on: June 18, 2009, 02:18:22 PM »
Can't you declare the string var to have the right size?

No, it's variable. The sample which I posted is a test case only.

From the original code.

Code: [Select]
void StoreLine( char * string )
{
    int i;

    i = strlen(string) + 1;
    LineStoreCurr = AsmAlloc( i + sizeof(line_item) );
    LineStoreCurr->next = NULL;
    LineStoreCurr->lineno = LineNumber;
    LineStoreCurr->list_pos = list_pos;
    LineStoreCurr->macrolevel = MacroLevel;
    memcpy( LineStoreCurr->line, string, i );
    LineStoreTail->next = LineStoreCurr;
    LineStoreTail = LineStoreCurr;
}


Even the original has to allocate for a string of unknown length. The most elegant way would be to make a func that deals with this issue.

EDIT: Here's a page on 'flexible array members' which is what you are using.

http://books.google.co.uk/books?id=iRa-3L4jLhEC&pg=PA554&lpg=PA554&dq=flexible+array+member&source=bl&ots=dXiybr7a3K&sig=1BM5U1NosUCz_5w1YZpG80G9Xd0&hl=en&ei=Yk46So7-NJm6jAe_zvimDQ&sa=X&oi=book_result&ct=result&resnum=7

John

« Last Edit: June 18, 2009, 04:33:17 PM by JohnF »

Seltsamuel

  • Guest
Re: structure initialization refused by pocc
« Reply #8 on: June 18, 2009, 11:29:56 PM »
Hi,

no time to test but this should really work ;-)

#include <stdio.h>

typedef unsigned int uint_32;
typedef unsigned char uint_8;

typedef struct line_item {
    struct line_item *next;
    uint_32 lineno:20, srcfile:12;
    uint_32 list_pos; /* position .LST file */
    uint_8 macrolevel; /* just a bit (macrolevel > 0?) is needed */
    char *line;
} line_item;

line_item endl = { NULL, 0, 0, 0, 0, "END" };

Greetings

Seltsamuel

Offline AlexN

  • Global Moderator
  • Member
  • *****
  • Posts: 394
    • Alex's Link Sammlung
Re: structure initialization refused by pocc
« Reply #9 on: June 19, 2009, 07:26:13 AM »
no time to test but this should really work ;-)
Code: [Select]
#include <stdio.h>

typedef unsigned int uint_32;
typedef unsigned char uint_8;

typedef struct line_item {
    struct line_item *next;
    uint_32 lineno:20, srcfile:12;
    uint_32 list_pos; /* position .LST file */
    uint_8 macrolevel; /* just a bit (macrolevel > 0?) is needed */
    char *line;
} line_item;

line_item endl = { NULL, 0, 0, 0, 0, "END" };
I think also this is a good solution, but japheth don't like it. :(

So I would prefer a constructor like:

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned int uint_32;
typedef unsigned char uint_8;

typedef struct line_item {
    struct line_item *next;
    uint_32 lineno:20, srcfile:12;
    uint_32 list_pos; /* position .LST file */
    uint_8 macrolevel; /* just a bit (macrolevel > 0?) is needed */
    char line[];
} line_item;

line_item *endl;

line_item *create_line_item(line_item *next, uint_32 srcfile, uint_32 lineno, uint_32 list_pos, uint_8 macrolevel, char * string )
{
        line_item *litem = (line_item *)malloc( sizeof( line_item ) + strlen(string) + 1 );
        litem->next = next;
        litem->srcfile = srcfile;
        litem->lineno = lineno;
        litem->list_pos = list_pos;
        litem->macrolevel = macrolevel;
        strcpy( litem ->line, string);
        return litem;
}

void destroy_line_item(line_item *li)
{
if (li != NULL)
{
free(li);
}
}

int main(int argc, char *argv[])
{
endl = create_line_item( NULL, 0, 0, 0, 0, "END" );
printf("%s\n", endl->line);
destroy_line_item(endl);
return 0;
}


Alex ;)

best regards
 Alex ;)

nicolas.sitbon

  • Guest
Re: structure initialization refused by pocc
« Reply #10 on: June 21, 2009, 10:28:37 AM »
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

typedef struct line_item
{
   struct line_item * next;
   uint32_t lineno  :20;
   uint32_t srcfile :12;
   uint32_t list_pos;   /* position .LST file */
   uint8_t  macrolevel; /* just a bit (macrolevel > 0?) is needed */
   char     line[];
}
line_item;

static line_item *create_line_item(line_item const * item, char const * line)
{
   size_t line_size  = strlen(line) + 1;
   line_item * litem = malloc(line_size + sizeof *litem);

   if(litem != NULL)
   {
      *litem = *item;
      memcpy(litem->line, line, line_size);
   }

   return litem;
}

static inline void destroy_line_item(line_item * item)
{
   free(item);
}

int main(void)
{
   line_item * endl = create_line_item(&(line_item){NULL, 0, 0, 0, 0}, "END");
   puts(endl->line);
   destroy_line_item(endl), endl = NULL;

   return 0;
}

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Re: structure initialization refused by pocc
« Reply #11 on: June 21, 2009, 01:34:37 PM »
The last member (line) is what the C standard calls a "flexible array member" - this was added in C99. AFAIK, initialization of a structure with a flexible member stops just before such a member - the error is correct (and the warning is just noice). Before C99, this was an extension in several C compilers which may or may not agree on the behaviour...
/Pelle