4

I tried to initialize a char array in a struct declaration by the following way. But it failed to compile with an error message. Please let me know why it cannot be compiled.

#include <iostream>

struct A {
    const char value_in_struct[] = "a";  // this line gives me a error message.
};

void t(void) {
    const char value[] = "a";  // this line was ok at compiling
    std::cout << "value = " << value << std::endl;
}

I got the following error message from gcc.

../static_constexpr_array.hpp:16:33: error: initializer-string for array of chars is too long [-fpermissive]
  const char value_in_struct[] = "a";
                                 ^

Thank you using time for me.

16
  • 1
    Because this syntax is only supported for const char[]. Commented Jan 30, 2016 at 14:46
  • 1
    In-class brace-or-equal initializer needs C++11 and onward. Commented Jan 30, 2016 at 14:48
  • Thank you, Violet Giraffe. I tried const char. However the result was same. I update the previous code with const char. Commented Jan 30, 2016 at 14:51
  • @Lingxi Is this not considered copy initialisation? Commented Jan 30, 2016 at 14:52
  • 1
    As far as I was aware in-class initializers must be inside curly braces and/or follow an = sign. I am guessing this is down to not specifying the array size, since the compiler will need to know how much space to reserve for an A object, but, if the such code were possible, the size of value_in_struct could change depending on how it was initialised (e.g. copy or default initialisation). Hopefully someone else can elaborate with a quote from the standard. Commented Jan 30, 2016 at 14:57

4 Answers 4

4

The problem is that array extent cannot be deduced automatically from an in-class initializer. The error message produced by clang is quite clear (see here):

prog.cc:4:34: error: array bound cannot be deduced from an in-class initializer
    const char value_in_struct[] = "a"; 
                                 ^

So why is this? In-class initializer can be overridden by a member initializer list of a constructor. So, what if a constructor chooses to initialize the array with something else? In your case, the initializer can be overridden with a brace-enclosed initializer list as follows (aggregate initialization, actually) (see here):

A a = {"abc"};

Since the ultimate initializer cannot be determined at compile time, the compiler cannot deduce the array extent.

Giving the array an explicit extent makes the code compile (see here).

#include <iostream>

struct A {
    const char value_in_struct[2] = "a";  
};

void t(void) {
    char value[] = "a";
    std::cout << "value = " << value << std::endl;
}
Sign up to request clarification or add additional context in comments.

3 Comments

@Silversonic It's true for C++11, but not since C++14. See here.
@Silversonic Note the statement no default member initializers (since C++11) (until C++14).
Thank you Lingxi. It was beautiful and clear answer for me.
1
struct A {
    const char value_in_struct[] = "a";.
};

This is wrong. Is this array class member, or object member? If it's class member, you must write so:

static constexpr char value_in_struct[] = "a";

Static, because it's class member. Constexpr, because you initialize it in class definition.

If it's object member, then you can't initialize it within class definition.

1 Comment

This is in-class brace-or-equal initializer introduced in C++11.
1

Thanks for asking question, when you state const char var[] = "something"; it means , you are declaring variable var of array of char type with length same as its assigned with string at initialization. eg. for above case its 10.

The statement will go valid when you can initialize variable, ie when you declare it in main or any other function.

Now your struct part of code is declaring a struct A in which you are declaring variable or const char [] in it, here you cannot initialize it, hence error. Also if you declare struct with such member variable and try to create instance it will give compilation error since its const type and we need to initialize it at creation of instance which is not possible.

Work around for it is in struct have member variable as type char * and assign it accordingly , this way you will be able to achieve what you looking for.

I tried some code on same lines and commented with lines it will give compilation error.. please see , hope it helps.

#include <iostream>
using namespace std;

struct B{
    const char mem_var[];
};

struct A {
    const char * value_in_struct ;  // this line gives me a error message.
    A(char *s):value_in_struct(s){}
    A() { value_in_struct = NULL;}
};

void t(void) {
    const char value[] = "att";  // this line was ok at compiling
    std::cout << "value = " << value << std::endl;
    //value[2] = 's';  // gives error
}

int main(){
    A a(const_cast< char *>("abc"));
    A b ;
    b.value_in_struct = "bbc";
    cout <<"a: "<<a.value_in_struct << endl;
    cout <<"b: "<<b.value_in_struct << endl;
    t();
    //B bb; gives error for not initizaling mem_var
    return 0;
}

1 Comment

Thank you rocky_mfe for giving me an alternative way.
0

Its been a while since I've used c++ but may I recommend trying:

const char[] value_in_strict = {'a'};

1 Comment

This should rather be a comment. But I understand you can't because you don't have enough rep for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.