Thread: Initializing a pointer to an array of pointers with compound literals

  1. #1
    Registered User
    Join Date
    Nov 2017
    Posts
    5

    Initializing a pointer to an array of pointers with compound literals

    I'm trying to get the following code to compile with Visual Studio 2015. Unfortunately, the code generates a compilation error: C2099 - initializer is not a constant.


    Code:
    static const int *const list[] = {(const int *const[]){1, 2}, (const int *const[]){1, 2, 3, 4}};
    Is there any way to get the code to compile correctly (without using temporary variables) while using a Visual Studio compiler?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Perhaps you wanted:
    Code:
    static const int list[][4] = {{1, 2}, {1, 2, 3, 4}};
    ? After all, list[i] would be an array of 4 const int, which would then decay to be a pointer to const int in most contexts.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2017
    Posts
    5
    Yes, you are right. The declaration of list is incorrect and not what I initially intended to do. I think the following is a better example which faces the same problem:

    Code:
    static const char *const *const list = (const char *const[]){"abc", "def", "xyz"}; // C2099: initializer is not a constant
    When removing the static keyword, making list non-static, the issue is solved and the code compiles fine without any warnings or errors. But I would really like to be able to compile the code while keeping list static.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    If it's any consolation, making the list variable a static array of pointers (as the cast suggests you should) wouldn't be a problem. It's a very small sized array of memory addresses, and the elements would still have the level of read only protection you want.

  5. #5
    Registered User
    Join Date
    Nov 2017
    Posts
    5
    Maybe the compile error has something to do with the following?

    As a GNU extension, GCC allows initialization of objects with static storage duration by compound literals (which is not possible in ISO C99, because the initializer is not a constant). It is handled as if the object was initialized only with the bracket enclosed list if compound literal's and object types match. The initializer list of the compound literal must be constant. If the object being initialized has array type of unknown size, the size is determined by compound literal size.
    Using the GNU Compiler Collection (GCC)

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Probably, I'm just saying that making an array is a standard solution.
    Code:
    C:\Users\jk>gcc -std=c99 -c test.c
    
    C:\Users\jk>more test.c
    static const char *const list[] = { "abc", "def", "xyz" } ;
    This compiles, so unless you really can't do this for reasons unknown, it is the recommended path.

  7. #7
    Registered User
    Join Date
    Nov 2017
    Posts
    5
    The problem is that I'm trying to make list a structure member. When changing list to a pointer to a flexible array, a variable of that structure can no longer be declared as an array of structures. list could also be defined as a pointer to a fixed size array of pointers but that would require the structure to be defined with a list member that is large enough to hold the largest list. Which isn't ideal when there are lots of small lists and a single large list.

  8. #8
    Registered User
    Join Date
    Nov 2017
    Posts
    5
    After some further testing it seems that the errror C2099: initializer is not constant only occurs when list is initialized within a scope/block of code. This also seems to be the case with GCC. When list is initialized as a glocal static variable, the error no longer occurs and the code will compile fine without any warning or errors. I'm curious to know why list cannot be initialized within a scope/block of code.

    Edit: Stargateur seems to have found the answer:
    "The unnamed object to which the compound literal evaluates has static storage duration if the compound literal occurs at file scope and automatic storage duration if the compound literal occurs at block scope (in which case the object's lifetime ends at the end of the enclosing block)."
    So this means that there is a restriction in effect that applies to compound literals: local variables with a static storage duration cannot be initialized with a compound literal.
    Last edited by treintje; 11-13-2017 at 04:06 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Initializing an array of char pointers directly
    By -Adrian in forum C++ Programming
    Replies: 2
    Last Post: 11-25-2014, 11:12 AM
  2. Compound literals
    By Mr.Lnx in forum C Programming
    Replies: 11
    Last Post: 05-24-2013, 06:49 AM
  3. initializing a array of pointers
    By ueg1990 in forum C Programming
    Replies: 9
    Last Post: 03-16-2012, 06:56 AM
  4. trouble initializing a dynamic array of pointers to NULL
    By supernater in forum C++ Programming
    Replies: 8
    Last Post: 09-13-2009, 04:47 PM
  5. Replies: 2
    Last Post: 04-01-2009, 12:06 AM

Tags for this Thread