Ferenc Deak
Ferenc Deak

Reputation: 35438

Revisiting the array of strings initialization in C

I want to initialize in plain C an array of strings with the following requirements:

(A) I need the strings in a header file, since some other modules are using them as plain strings, so I declared in the header file:

extern const char* const ERRMSG_VM_0001;
extern const char* const ERRMSG_VM_0002;
extern const char* const ERRMSG_VM_0003;
extern const char* const ERRMSG_VM_0004;

and in the source file:

const char* const ERRMSG_VM_0001 = "[VM-001] some text ";
const char* const ERRMSG_VM_0002 = "[VM-002] more text ";
const char* const ERRMSG_VM_0003 = "[VM-003] other text ";
const char* const ERRMSG_VM_0004 = "[VM-003] and even more";

(B) I need these strings also in an array, so I tried in the (same) source (as above):

static const char* error_table[4] =
{
    ERRMSG_VM_0001,
    ERRMSG_VM_0002,
    ERRMSG_VM_0003,
    ERRMSG_VM_0004
};

Obviously, the compiler complains error: initializer element is not constant ... so now I am wondering how can I achieve this in a pure C way, not C++ (this is similar to Tricky array Initialization but it's not the same).

Upvotes: 3

Views: 225

Answers (4)

Renat
Renat

Reputation: 8972

If it's acceptable to change type of the array elements from char* to char**, array can be inplace initialized:

static const char* const* const error_table[4] =
{
    &ERRMSG_VM_0001,
    &ERRMSG_VM_0002,
    &ERRMSG_VM_0003,
    &ERRMSG_VM_0004
};

Upvotes: 0

user1814023
user1814023

Reputation:

The ERRMSG_VM_0001 is a variable. But in C++ it will be a constant expression. That is why C++ allows the same but C wont allow it. You can't do this in C.

const int a = 10;
const int arr[] = { a };

You can do like this...

//Is in header.h
extern const char* const ERRMSG_VM_0001;
extern const char* const ERRMSG_VM_0002;
extern const char* const ERRMSG_VM_0003;
extern const char* const ERRMSG_VM_0004;

//This is in main.c
#include "header.h" 
static const char* error_table[4] =
{
    "[VM-001] some text ",
    "[VM-002] some text ",
    "[VM-003] some text ",
    "[VM-004] some text ",
};

int main(void)
{
    const char* const ERRMSG_VM_0001 = error_table[0]; // Works fine
    return 0;
}

Upvotes: 0

V-X
V-X

Reputation: 3029

Compilers are able to find matching string literals and optimize the binary. (it may be an option)

I'd suggest to declare defines only and create a const

#define ERRMSG_VM_0001 "[VM-001] some text "
...

and

static const char* error_table[4] =
{
    ERRMSG_VM_0001,
    ERRMSG_VM_0002,
    ERRMSG_VM_0003,
    ERRMSG_VM_0004
};

would be now OK. and the resulting binary code will be the one you want.

Upvotes: 3

Keith Nicholas
Keith Nicholas

Reputation: 44298

static const char* error_table[4] =
{
    "[VM-001] some text ",
    "[VM-002] some text ",
    "[VM-003] some text ",
    "[VM-004] some text ",
};

then

ERRMSG_VM_0001 = error_table[0];

Upvotes: 1

Related Questions