Error initializer string for array of chars is too long fpermissive

Following program compiles fine in C with warnings but fails in compilation in C++. Why? What is the reason? #include int main(void) { char a[5]="Hello"; a[0]='y'; put...

Short answer: Because C and C++ are different languages with different rules.

Long answer: In both cases the reason is that the array is too small for the string literal. The literal consists of the five visible characters, with a zero terminator on the end, so the total size is 6.

In C, you’re allowed to initialise an array with a string that’s too long; extra characters are simply ignored:

C99 6.7.8/14: An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

The compiler helpfully warns that the string is too large, since it almost certainly indicates an error; but it can’t reject the code unless you tell it to treat warnings as errors.

In C++, the initialiser isn’t allowed to be larger than the array:

C++11 8.5.2/2: There shall not be more initializers than there are array elements.

so, for that language, the compiler should give an error.

In both languages, when you want a character array to be the right size for a string literal initialiser, you can leave the size out and the compiler will do the right thing.

char a[] = "hello";  // size deduced to be 6

Aside from the missing commas in your set of initializers, why not just skip making it a 2-dimensional array of char? You’re only passing the array data to strstr(), and all it wants are null terminated strings. Why not use the more flexible:

char* array[] = { 
    "Becky Warre, 555-1223",
    "Joe Looney, 555-0097",
    "Geri Palmer, 555-8787",
    "Lynn Presnell, 555-1212",
    "Holly Gaddis, 555-8878",
    "Sam Wiggins, 555-0998",
    "Bob Kain, 555-8712",
    "Tim Haynes, 555-7676",
    "Warren Gaddis, 555-9037",
    "Jean James, 555-4939",
    "Ron Palmer, 555-2893",
    NULL
};

Now that the array is just a set of pointers (and it’s terminated with a NULL pointer), the loop can look something like:

char *ptr = NULL;
int i;
for (i = 0; array[i] != NULL; i++)
{
        ptr = strstr(array[i], search);
        if (ptr != NULL)
                cout << array[i];
}

One advantage of this is that you can add new strings to the data without having to update any corresponding ‘size’ numbers. And you’ll never have to worry about the compiler complaining that the array is too small in one dimension or another — it’ll just make the array the size it needs to be.

murtukov

10 / 10 / 5

Регистрация: 30.01.2013

Сообщений: 99

1

Передача двумерного массива в функцию

25.02.2013, 04:17. Показов 3398. Ответов 7

Метки нет (Все метки)


Всем доброго времени суток!

В Си, при объявлении двумерного массива, можно было сразу проинициализировать его значения:

C
1
char mass[2][6] = { "Anton", "Misha" };

Но в C++ такой вариант не прокатывает. Выскакивает следующая ошибка:

error: initializer-string for array of chars is too long [-fpermissive]

Что это значит?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Kuzia domovenok

3985 / 3255 / 909

Регистрация: 25.03.2012

Сообщений: 12,102

Записей в блоге: 1

25.02.2013, 04:27

2

C++
1
char mass[2][6] = { "Anton", "Misha" };

Добавлено через 40 секунд

Цитата
Сообщение от murtukov
Посмотреть сообщение

В Си, при объявлении двумерного массива, можно было сразу проинициализировать его значения:

А в крестах что, нет?



0



murtukov

10 / 10 / 5

Регистрация: 30.01.2013

Сообщений: 99

25.02.2013, 04:57

 [ТС]

3

Цитата
Сообщение от Kuzia domovenok
Посмотреть сообщение

C++
1
char mass[2][6] = { "Anton", "Misha" };

Добавлено через 40 секунд

А в крестах что, нет?

Вы что, наполовину читаете сообщение? Я же ясно написал:

«Но в C++ такой вариант не прокатывает. Выскакивает следующая ошибка:

error: initializer-string for array of chars is too long [-fpermissive]»

Стало быть, что ТАКИМ ОБРАЗОМ нет.

IDE: Code::Blocks 12.11
Компилятор: GNU GCC

И на счет некорректного заголовка. Я сначала собирался запостить другой вопрос, но передумал, а изменить заголовок забыл.



0



52 / 41 / 16

Регистрация: 16.12.2012

Сообщений: 144

25.02.2013, 05:06

4

Цитата
Сообщение от murtukov
Посмотреть сообщение

char mass[2][6] = { «Anton», «Misha» };

Я может быть ошибаюсь , но кажется нужно поставить «;» вместо «,» между миша и антон . Попробуйте , точно не помню.
А не фигню написал сорри



0



alsav22

5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

25.02.2013, 05:31

5

Цитата
Сообщение от murtukov
Посмотреть сообщение

Вы что, наполовину читаете сообщение? Я же ясно написал:
«Но в C++ такой вариант не прокатывает.

Попробуйте написать код, как у него:

C++
1
char mass[2][6] = { "Anton", "Misha" };

Миниатюры

Передача двумерного массива в функцию
 



1



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

25.02.2013, 05:58

6

Цитата
Сообщение от murtukov
Посмотреть сообщение

error: initializer-string for array of chars is too long [-fpermissive]
Что это значит?

Что строка для инициализации массива слишком длинная. » в конец строки компилятор сам добавляет.



2



kuli4ok

32 / 32 / 17

Регистрация: 10.10.2012

Сообщений: 88

25.02.2013, 07:20

7

Цитата
Сообщение от murtukov
Посмотреть сообщение

Всем доброго времени суток!

В Си, при объявлении двумерного массива, можно было сразу проинициализировать его значения:

C
1
char mass[2][6] = { "Anton", "Misha" };

Но в C++ такой вариант не прокатывает. Выскакивает следующая ошибка:

error: initializer-string for array of chars is too long [-fpermissive]

Что это значит?

Всегда внимательно разбирайте сообщения компилятора, он лучше всякого форума вам скажет где вы ошиблись. Хотя бы просто в google переводчике перевести. Как вариант перевода: Инициализирующая строка слишком длинная для массива символов. Я думаю, вполне достаточно для того, что бы исправить ошибку.

Добавлено через 1 минуту

Не по теме:

А потом все стучат в грудь и кричат «Нафига нам английский!?» …



1



442 / 410 / 132

Регистрация: 21.01.2012

Сообщений: 974

25.02.2013, 07:23

8

murtukov, а Вы что отличия не видите?



0



Следующая программа прекрасно компилируется в C с предупреждениями, но не компилируется в C ++. Зачем? Какова причина?

#include <stdio.h>
int main(void)
{
char a[5]="Hello";
a[0]='y';
puts(a);
for(int i=0;i<5;i++)
printf("%c",a[i]);
return 0;
}

Предупреждение:

Warning:[Error] initializer-string for array of chars is too long [-fpermissive] enabled by default

Но если программа скомпилирована как программа C ++, то компилятор C ++ выдает следующую ошибку:

[Error] initializer-string for array of chars is too long [-fpermissive]

Я использую компилятор GCC 4.8.1.

5

Решение

Краткий ответ: потому что C и C ++ — это разные языки с разными правилами.

Длинный ответ: в обоих случаях причина в том, что массив слишком мал для строкового литерала. Литерал состоит из пяти видимых символов с нулевым терминатором на конце, поэтому общий размер равен 6.

В C вы можете инициализировать массив слишком длинной строкой; лишние символы просто игнорируются:

C99 6.7.8 / 14: Массив символьного типа может быть инициализирован литералом символьной строки, необязательно заключенным в фигурные скобки. Последовательные символы литерала символьной строки (включая завершающий нулевой символ, если есть место или если массив имеет неизвестный размер) инициализируют элементы массива.

Компилятор предупреждает, что строка слишком велика, поскольку почти наверняка указывает на ошибку; но он не может отклонить код, если вы не скажете, чтобы он воспринимал предупреждения как ошибки.

В C ++ инициализатору не разрешено быть больше, чем массив:

C ++ 11 8.5.2 / 2: Инициализаторов не должно быть больше, чем элементов массива.

поэтому для этого языка компилятор должен выдать ошибку.

В обоих языках, когда вы хотите, чтобы символьный массив соответствовал размеру инициализатора строкового литерала, вы можете не указывать размер, и компилятор сделает все правильно.

char a[] = "hello";  // size deduced to be 6

22

Другие решения

Проблема в нижней строке

char a[5]="Hello";

Нет места для хранения завершающего нуля.

По умолчанию, gcc не выдает никаких ошибок для этого случая с -fpermissive опция включена. Так что компилирует нормально в C,

Согласно требованию от языковых стандартов,

  • ЗаC99 стандарт, глава 6.7.9, пункт 14,

Массив символьного типа может быть инициализирован символьным строковым литералом или строковым литералом UTF-8, необязательно заключенным в фигурные скобки. Последовательные байты строкового литерала (включая завершающий нулевой символ, если есть место или массив имеет неизвестный размер) инициализируют элементы массива.

  • За C++11, глава 8.5.2, пункт 2

Инициализаторов не должно быть больше, чем элементов массива.

Итак, код компилируется (с предупреждениями) с gcc, выдает ошибку с g++,

10

Допустимая строка в C и C ++ должна иметь терминатор и в

char a[5]="Hello";

Там нет места для нулевого терминатора и не является допустимой строкой.

Так что это может не быть ошибкой в ​​C, но вы обязательно столкнетесь с проблемами при использовании встроенных строковых функций, таких как strlen() и семья.

5

Потому что «Привет» 6 charс долго и г ++ без -fpermissive не будет инициализировать 5 char массив с ним, но GCC будет.

3

This sketch does not compile in the Arduino IDE

void setup() {
  // put your setup code here, to run once:

}

struct test {
  int i;
  char variable[];
};

typedef struct test test;

test t = {
  0, "hi"
};

void loop() {
  // put your main code here, to run repeatedly:

}

Arduino throws

sketch_may09a:16: error: initializer-string for array of chars is too long [-fpermissive]

 };

 ^

exit status 1
initializer-string for array of chars is too long [-fpermissive]

However compiling with g++ works just fine. How can I fix it? Or is there a principle reason why flexible array members are not supported?

Glorfindel's user avatar

Glorfindel

5731 gold badge7 silver badges18 bronze badges

asked May 9, 2019 at 19:31

the_architect's user avatar

4

Flexible array member is a C feature. It does not exist in C++. On top of that, the way you use it to declare and initialize a static struct of flexible size is non-standard even for C.

However, GNU-C language supports it as an extension. Also, newer versions of GCC (6 and higher) allow this in GNU-C++ code as an extension as well. But GCC 5.4.0 used by Arduino IDE doesn’t support this non-standard feature in C++ code.

If you flip through different GCC versions on Godbolt (https://godbolt.org/z/Iul7hD) you’ll see that support for this feature has always been present in C code, but for C++ code it first appeared in GCC 6.

This is why you were able to compile it with your standalone g++ compiler (which is apparently a much later version), but were unable to compile it in Arduino IDE.

It means that if you really want this non-standard code to compile in the current version of Arduino IDE, you have to place it into a .c file. Or just specify the array size explicitly.

answered May 9, 2019 at 19:56

AnT stands with Russia's user avatar

2

Maybe you’ve compiled it in g++ without any warnings enabled (or maybe it yeld warnings but was compiled). The arduino uses flags to consider all warnings as an error, so it won’t compile. It may wary for different platforms, I’ve got -fpermissive used (and I don’t like it at all).

That’s because size of struct must be known compile time and if you provide char variable[]; you’ll get zero sized array. Therefore anything biiger than nothing you’ll try to initialize for is too long.

Maybe you’re looking for something like this:

struct test {
  int a;  
  const char * ptr;
};

test paramx {1, "some string"};
test paramy {2, "another string"};

test array[] = {{3,"three"}, {4, "four"}, {5,"five"}};

answered May 9, 2019 at 19:52

KIIV's user avatar

KIIVKIIV

4,2321 gold badge11 silver badges21 bronze badges

7

Короткий ответ: потому что C и С++ — разные языки с разными правилами.

Длинный ответ: В обоих случаях причина заключается в том, что массив слишком мал для строкового литерала. Литерал состоит из пяти видимых символов с нулевым терминатором на конце, поэтому общий размер равен 6.

В C вы можете инициализировать массив со слишком длинной строкой; дополнительные символы просто игнорируются:

C99 6.7.8/14: массив типа символа может быть инициализирован литералом строковой буквы, необязательно заключенным в фигурные скобки. Последовательные символы символьного строкового литерала (включая завершающий нулевой символ, если есть место или массив неизвестного размера) инициализируют элементы массива.

Компилятор предупреждает, что строка слишком велика, поскольку она почти наверняка указывает на ошибку; но он не может отклонить код, если вы не сообщите ему, чтобы он рассматривал предупреждения как ошибки.

В С++ инициализатор не может быть больше, чем массив:

С++ 11 8.5.2/2: не должно быть больше инициализаторов, чем элементов массива.

поэтому для этого языка компилятор должен сообщить об ошибке.

В обоих языках, когда вы хотите, чтобы массив символов был правильным размером для инициализатора строкового литерала, вы можете оставить размер, и компилятор выполнит правильные действия.

char a[] = "hello";  // size deduced to be 6

Following program compiles fine in C with warnings but fails in compilation in C++. Why? What is the reason?

#include <stdio.h>
int main(void)
{
    char a[5]="Hello";
    a[0]='y';
    puts(a);
    for(int i=0;i<5;i++)
        printf("%c",a[i]);
    return 0;
}

The warning:

Warning:[Error] initializer-string for array of chars is too long [-fpermissive] enabled by default

But if the program is compiled as C++ program then C++ compiler gives following error:

[Error] initializer-string for array of chars is too long [-fpermissive]

I am using GCC 4.8.1 compiler.


Short answer: Because C and C++ are different languages with different rules.

Long answer: In both cases the reason is that the array is too small for the string literal. The literal consists of the five visible characters, with a zero terminator on the end, so the total size is 6.

In C, you’re allowed to initialise an array with a string that’s too long; extra characters are simply ignored:

C99 6.7.8/14: An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

The compiler helpfully warns that the string is too large, since it almost certainly indicates an error; but it can’t reject the code unless you tell it to treat warnings as errors.

In C++, the initialiser isn’t allowed to be larger than the array:

C++11 8.5.2/2: There shall not be more initializers than there are array elements.

so, for that language, the compiler should give an error.

In both languages, when you want a character array to be the right size for a string literal initialiser, you can leave the size out and the compiler will do the right thing.

char a[] = "hello";  // size deduced to be 6

  • Forum
  • Beginners
  • string logical question

string logical question

please see the following snippet. i get a garbage value as output.

void main()
{
char arr[7]=»network»;
printf(«%s»,arr);
}

I’m surprised it compiles. I get the following error.

error: initializer-string for array of chars is too long [-fpermissive]

"network" is 8 chars. 7 letters + a null character » to mark the end of the string. If you change arr to size 8 it will probably work as you expected.

@peter87, whch compiler do you use?? i use turbo c++. i m getting wierd results. when i change the array size to six and hardcode it to «networ»
i get proper output as networ. i m confused.

Last edited on

I use GCC.

I said you should change the size to 8. If you change the string to «networ» you should change the size to 7.

If you leave out the size the compiler will automatically make the array big enough to store the string.

What your compiler seems to be doing is that if the array is shorter than the string it just ignores the characters that doesn’t fit, so in your original code arr will contain all characters in «network» except for the last character, the null character. When you print the array it will go through the characters one by one and stop when it finds a null character. arr doesn’t contain a null character so it just continue printing the bytes after the array, which is why you got garbage output.

i don’t think you should get proper results.
a c-string must be 1 character longer than its content, this extra slot is used to contain the null terminator.
if your compiler doesn’t care about this initialization and still compiles the program, and if you send the string to the output stream, you should get the phrase «network» followed by multiple garbage characters.
why is this behavior:
the output function keeps printing characters until it reaches a null character, which tells it to stop printing.
if your string doesn’t contain such character, then you’re on a date with your luck, you might eventually get an access violation error.

try [] = «network»

Topic archived. No new replies allowed.

Понравилась статья? Поделить с друзьями:
  • Error initializer expression list treated as compound expression in initializer
  • Error initializer element is not a compile time constant
  • Error initialized or created transport for authentication
  • Error initialize specified but the data directory has files in it aborting
  • Error initialize scatter file failed