C Arduino compiler crash on basic struct/string function mix

Hi, could someone explain that ?
IDE is 2.3.2 target is MEGA 2560

#include <stdio.h>
struct tst_g
{
  char m[5]; 
  int nb[]; 
};
tst_g g[]=
{
  {"GGA",{1,2,3}},
  {"RMC",{1,2,3}}
};
char a[10];
void setup()
{
  strncpy(a,g[1].m,2);
}

void loop()
{
  
}

lto1.exe: internal compiler error: in output_constructor_regular_field, at varasm.c:5031
Please submit a full bug report,
with preprocessed source if appropriate.
See https://gcc.gnu.org/bugs/ for instructions.
lto-wrapper.exe: fatal error: C:\Users\VM_42_1\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc returned 1 exit status
compilation terminated.
c:/users/vm_42_1/appdata/local/arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/../lib/gcc/avr/7.3.0/../../../../avr/bin/ld.exe: error: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

struct tst_g
{
  char m[5];
  int nb[];
};

Is there a reason you cannot specify the number of elements in the nb array?

No errors compiling this for the Uno.

#include <stdio.h>
struct tst_g
{
  char m[5];
  int nb[3];
};
tst_g g[] =
{
  {"GGA", {1, 2, 3}},
  {"RMC", {1, 2, 3}}
};
char a[10];
void setup()
{
  strncpy(a, g[1].m, 2);
}

void loop(){}

You're trying to use a flexible array member. This is not allowed in C++. Even in C, you cannot initialize it like that. See Struct declaration - cppreference.com

If a struct defines at least one named member, it is allowed to additionally declare its last member with incomplete array type. When an element of the flexible array member is accessed (in an expression that uses operator . or -> with the flexible array member's name as the right-hand-side operand), then the struct behaves as if the array member had the longest size fitting in the memory allocated for this object. If no additional storage was allocated, it behaves as if an array with 1 element, except that the behavior is undefined if that element is accessed or a pointer one past that element is produced. Initialization and the assignment operator ignore the flexible array member.

Fix the size of the array, or make it a template parameter.

  • why is this a basic struct?
  • why isn't the size of the integer array specified? (certainly an error)
  • in the code below note the difference between specifying an char array, const char m [5];, and a pointer to a char string, const char *m;

  • note that a char * requires only 2 bytes in a struct and that the string is not actually part of the struct but stored elsewhere and that the struct just include a pointer to it

  • note that even if the byte array size may be 5, it may be initialized with fewer values (but the size of the array must be fixed in the definition of the struct)

output:

AB
  size tst_g 6, other 9, size char* 2
struct other {
    byte        nb [4];
    const char  m [5];
};

struct tst_g {
    byte        nb [4];
    const char *m;
};

tst_g g [] = {
    { {1,2,3}, "ABC" },
    { {1,2,3}, "a longer string" },
};

char a[90];

void setup()
{
    Serial.begin (9600);
    strncpy (a, g[0].m, 2);
    Serial.println (a);

    sprintf (a, "  size tst_g %d, other %d", sizeof(tst_g), sizeof(other));
    Serial.print   (a);

    sprintf (a, ", size char* %d", sizeof(char *));
    Serial.println (a);
}

void loop()
{
}

Many thanks Greg, looks like it solved my compilation error problem.

At least I have learned something this morning, I was ignoring that the compiler is able to implicitly create a const string "ABC" while placing its pointer into the structure the way you showed me.

Now, I'm not sure it's normal that the compiler is doing a kind of bug report rather than giving a lead to find the error.

No, it is not normal. You should be able to throw anything at all at a compiler and it should handle it without requesting that you bring it to the attention of someone who cares.

You were asked

Please submit a full bug report,
with preprocessed source if appropriate.
See GCC Bugs - GNU Project for instructions.

which you might want to take the time to do. I am sure it will be appreciated… this is not normal and only by the reports from users can defects like this be eliminated.

In the old days, it was not uncommon to find real compiler errors. Now anyone who turns first to the idea that the compiler is broken or has somehow changed since Wednesday is almost certainly barking up the wrong tree.

So you might be awarded a feather, and attain immortality in the form of a comment deep in the guts of the compiler when someone finds, and fixes, the flaw you have provoked.

a7