Why "Initializer-String for Array of Chars Is Too Long" Compiles Fine in C & Not in C++

Why initializer-string for array of chars is too long compiles fine in C & not in C++?

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

Macro uses as string cause initializer-string for array of chars is too long

Your string size 9 doesn't allow room for all the escape sequences and other wrapper characters. INFO_STR needs 30 bytes, UNKNOWN_TYPE_STR needs 39 bytes.

You should be able to do it with the array of pointers to string literals. You just got the syntax a little wrong. Get rid of the parentheses.

static const char *LOG_TYPE_STR[] = {NULL_STR, INFO_STR, WARN_STR, UNKNOWN_TYPE_STR, ERROR_STR, UNKNOWN_TYPE_STR, UNKNOWN_TYPE_STR, UNKNOWN_TYPE_STR, DEBUG_STR};

Expected to see initializer-string for array of chars is too long warning

Section 6.7.9 of the C standard reads:


  1. An array of character type may be initialized by a character string
    literal or UTF −8 string literal, optionally enclosed in braces.
    Successive bytes of the 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.

...


  1. EXAMPLE 8

    The declaration

    char s[] = "abc", t[3] = "abc";

    defines ‘‘plain’’ char array objects s and t whose elements are initialized with character string literals. This declaration is identical to

    char s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };

(Emphasis mine).

That is, the terminating null character is not added if it does not fit into the fixed known size array.

Initializer-string for array of chars is too long for char[]

The auto-sizing of the last element is not standard c++. The standard allows you to declare that zero-length array, and it is for the obvious use-case, but does not say how to get it allocated the size you want.

Some compilers do support it in some ways as an extension.

To do it cleanly in pre-template days required a custom allocator operator new. These days you might for example wrap it in a derived template instance class which actually does the sizing as a template argument - you could return that from a template function that deduces the array size. The base array is then legal to use.

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

It's because the initializer-string for your array of chars is too long

This

".fft"

is 5 characters long (including the NUL)

You've only allocated 4:

char fftc[4];     // .fft

If you really want those four characters and no NUL, try

struct ffthdr fhdr =  {{'.','f','f','t'},1024,512,256,0,0,1};

initializer-string for array of array of chars is too long

char patches2[][64]

This is an array of arrays. The first dimension is determined automatically from the number of elements in the initializer. The second dimension is specified as being 64 chars.

Some of the string literals with which you initialize patches2 are longer than 64 characters in length. You need to increase the size to some value large enough to hold the largest C string in the initializer.

initializer-string for array of chars is too long error

The string "Diamonds" has 9 characters including the null terminating character. Therefore, name must have at least 9 elements.

However, it looks like your name member should be called suit and vice versa.

C Program - warning: initializer-string for array of chars is too long

This:

char name[0] = "/tmp/crt/client.conf";

means "make name be an array of 0 characters, initialized this string of 20 characters". And so on, which is why the compiler is warning.

You meant:

const char *names[] = { "/tmp/crt/client.conf", ... };

Which means "make names be an array of pointers to non-changing character data, initialized to point at these 0-terminated strings". This latter array can be iterated over like you wanted:

for(size_t i = 0; i < sizeof names / sizeof *names; ++i)
{
printf("name %zu is '%s'\n", i, names[i]);
}

Even better, though, would be to store the names and the sizes together:

const struct {
const char *name;
size_t def_size;
} files[] = {
{ "/tmp/crt/client.conf", 5874 },
{ "/tmp/crt/haha", 1 },
... and so on ...
};

That would make the stat()-loop easier to write:

for(size_t i = 0; i < sizeof files / sizeof *files; ++i) {
struct stat st;
if(stat(files[i].name, &st) == 0) {
printf("VERIFYING: %s DEF_SIZE: %zu NOW: %zu\n", files[i].name, files[i].def_size, (size_t) st.st_size);
if (st.st_size != files[i].def_size)
printf("(%s) has a different file size from the default one.\n", files[i].name);
}
}

initializer-string for array of chars is too long C

You need one more [28] for the trailing '\0' to be a valid string.

Take a look to C Programming Notes: Chapter 8: Strings:

Strings in C are represented by arrays of characters. The end of the
string is marked with a special character, the null character, which
is simply the character with the value 0. (The null character has no
relation except in name to the null pointer. In the ASCII character
set, the null character is named NUL.) The null or string-terminating
character is represented by another character escape sequence, \0.

And as pointed out by Jim Balter and Jayesh, when you provide initial values, you can omit the array size (the compiler uses the number of initializers as the array size).

char greek[] = "ABGDE#ZYHIKLMNXOPQRSTUFC$W3";

Initializer-string for char array is too long using deduction of size

When you specify an initialiser in the class, remember that that's still only the default field initialiser. A constructor could override it. That's why the initialiser cannot have any effect on the array's length, and why this cannot work.

clang produces a better diagnostic:

error: array bound cannot be deduced from an in-class initializer

The reason GCC's diagnostic is so confusing is because it conflicts with a GCC extension. If you pass GCC the -pedantic option, you get an additional warning (and again somewhat misleading):

warning: ISO C++ forbids zero-size array 'filebase'

GCC is accepting your field definition of type char[], and gives it length 0. It then does not accept your initialiser, since it doesn't fit in a zero-length array.

To make it work, specify the array's size explicitly.



Related Topics



Leave a reply



Submit