-2

I want to initialize all members of an array of char arrays with one default string "default".

What I have so far is either:

char a[10][8];

for(int i = 0; i < 10; i++)
{ 
    strcpy(&a[i][0],"default"); 
}

or alternatively:

char a[10][8] = { 
                  {"default"}, {"default"}, {"default"}, {"default"}, {"default"}, 
                  {"default"}, {"default"}, {"default"}, {"default"}, {"default"}
                };

Is there a way in the C syntax to abbreviate this in a simpler way?


I know that there is the similar question How to initialize all members of an array to the same value? but the answers there focus on how to initialize an one-dimensional int array with int values, not a two-dimensional char array with strings.

  • It's the same for strings. If it's not the default `0` value speified by the language, you either have to list them all or write a loop. – Barmar Feb 29 '20 at 17:44
  • What does “shortest” way possible mean? Shortest source code? Shortest machine code? Shortest execution time when program is starting? Why is that the criterion? Generally, simplifying source code is beneficial because it often provides clarity and is somewhat correlated with optimization, but that goal should be a tendency toward shorter while balancing other factors, not a goal of shortest possible. The proper answer for this question depends on what the real goal is and how much effort it is worth putting into. – Eric Postpischil Feb 29 '20 at 17:52
  • @EricPostpischil Shortest source code, if it would be possible. I´m asking for is there any shortcut or technique which does that without repeating 10 times `"default`" in one statement. This would be the goal. – RobertS supports Monica Cellio Feb 29 '20 at 17:55
  • Sorry, that is not a useful goal and is not one that should be encouraged. Trying to make the shortest source code is a game, not engineering. – Eric Postpischil Feb 29 '20 at 17:56
  • @user3121023: You need an `=` in there. – Eric Postpischil Feb 29 '20 at 17:58
  • 2
    @user3121023: `char a[10][8] = { [ 0 ... 9] = "default"};`. Hmm, GCC accepts it without the `=` though. I do not know what it thinks it is doing. It is not shown in [the documentation](https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html). – Eric Postpischil Feb 29 '20 at 18:01
  • @EricPostpischil Ok, Just asking for simplification while of course do not lose efficiency. Thank you for your information. – RobertS supports Monica Cellio Feb 29 '20 at 18:01
  • `#define d {"default"} char arr[10][9] = {d,d,d,d,d,d,d,d,d,d};` – 0___________ Feb 29 '20 at 18:03
  • Why is the question down-voted? What did I do wrong? – RobertS supports Monica Cellio Feb 29 '20 at 18:04
  • @RobertSsupportsMonicaCellio: As I wrote, the question is not useful. It is for playing games, not for doing serious programming. I generally encourage people play as a part of learning, because it helps learning, but I do not judge setting this as a question to be useful. – Eric Postpischil Feb 29 '20 at 18:06
  • @user3121023 I think this is what I am looking for. – RobertS supports Monica Cellio Feb 29 '20 at 18:07
  • @EricPostpischil I´m just looking for a way to abbreviate, like the linked question does. Why is it wrong when I´m asking but correct if someone else does? – RobertS supports Monica Cellio Feb 29 '20 at 18:08
  • @RobertSsupportsMonicaCellio: (a) I did not vote on the other question, and you have no indication that any individual voted differently on the two questions, so you have no evidence of inconsistency. (b) The other question does not ask for the shortest source code. It asks for a “simple” way to do it, which is a useful goal, and whether there is a way to do it built into the C syntax (properly grammar), which is also a useful goal. Asking for the shortest source code, neglecting balance with other goals as I asked, is not a useful goal. Brevity can impair clarity and correctness. – Eric Postpischil Feb 29 '20 at 18:11
  • @P__J__ This is an approach in the right direction. Thank you for it. – RobertS supports Monica Cellio Feb 29 '20 at 18:11
  • @EricPostpischil "*It asks for a “simple” way to do it, which is a useful goal, and whether there is a way to do it built into the C syntax (properly grammar), which is also a useful goal.*" - But this is the same as I do. You asked for what I mean with "shortest", that is my interpretation of "shortest". I don´t know how to spell it else. The other question did also not specified exactly what they meant with "simple". – RobertS supports Monica Cellio Feb 29 '20 at 18:16
  • @RobertSsupportsMonicaCellio: Shortest source code means fewest characters, or perhaps fewest preprocessor tokens. “Simple” means “easily understood or done, presenting no difficulty” or “plain, basic or uncomplicated in form, nature, or design.” They are different things, and the Obfuscated C Contest gives us ample evidence of that. – Eric Postpischil Feb 29 '20 at 18:58
  • @EricPostpischil I´ve edited the question. Is it better now or should I add/change something? – RobertS supports Monica Cellio Feb 29 '20 at 19:04

1 Answers1

2

One of the answers to your linked question shows the only (compiler-specific) way I know of to shorten the initialization:

char a[10][8] = { [0 ... 9] = {"default"} };

That is a GCC extension documented under designated initializers.

Note that the space before the ... notation is mandatory; otherwise, you have a floating-point literal 0. (due to the 'maximal munch' rule) which can't be used as a subscript. The space afterwards is symmetric, though not strictly necessary. (I'm surprised they didn't choose something like a colon : to separate the numbers — there'd be no danger of confusion as the only other points that colons appear is after labels or in the ternary ?: operator, which are clearly not relevant here. I'm also disappointed something like this was not added to C99 — or later — as part of the designated initializers feature. After all, Fortran 66 (aka Fortran IV) had a mechanism for repeating 'initializers'!)

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Any clue why [GCC does not require the `=`](https://godbolt.org/z/nMbBUL)? – Eric Postpischil Feb 29 '20 at 18:08
  • 2
    The designated initializers documentation linked to in the answer says: _An alternative syntax for this that has been obsolete since GCC 2.5 but GCC still accepts is to write ‘[index]’ before the element value, with no ‘=’._ (It's obsolescent, but still accepted for reasons of backwards compatibility.) – Jonathan Leffler Feb 29 '20 at 18:09
  • You guys are giving non portable solutions? Otherwise criticizing not portable advices even if tagged stm32 or avr. Hell is freezing over... – 0___________ Feb 29 '20 at 18:16
  • 1
    @P__J__ — yes, but I explicitly call it out as GCC-specific (though Clang also supports it for GCC-compatibility). And GCC is fairly portable, so … If there was a portable alternative, I'd use it. There isn't — unless you count preprocessor hacks like the `#define d "default"` trick (`#define d1 "default"`, `#define d2 d1, d1`, `#define d4 d2, d2`, `#define d8 d4, d4`, …, `char a[15][8] = { d8, d4, d2, d1 };` etc. This extends to big array sizes. It is preprocessor 'magic' (or 'grunge'), so it isn't entirely desirable, but if the size of the array was 1024 instead of just 10, it would work! – Jonathan Leffler Feb 29 '20 at 18:24
  • Function-like macros might be more general: `#define d1(x) x`, `#define d2(x) d1(x), d1(x)`, `#define d4(x) d2(x), d2(x)`, …, `#define d1024(x) d512(x), d512(x)`; now you can choose your size (10) and create `#define d10(x) d8(x), d2(x)` and then use `char a[10][8] = { d10("default") };` — and similarly for other simple initializers. If the initializers need commas, you have to work (a lot) harder — or use a macro like `#define COMMA ,` and reference COMMA where you need a comma. – Jonathan Leffler Feb 29 '20 at 18:29
  • @JonathanLeffler `And GCC is fairly portable` I am shocked. What about Unisys 1.complement mainframes? – 0___________ Feb 29 '20 at 18:31
  • @P__J__: I'll worry about that when I have to work on one — most probably by switching jobs. And 'fairly' includes some cases where it isn't portable — I don't expect to see GCC on a Sinclair ZX80, for example. Using 'fairly' also isn't as enthusiastic as 'very' portable, for example. – Jonathan Leffler Feb 29 '20 at 18:31
  • I seem to have forgotten what I thought of in the past. My [comment](https://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value#comment71634084_1565469) to answer to the linked question shows how to manage structures, etc, without COMMA (but does run along the lines of the `d1`, `d2`, `d4`, …, `d1024` mechanism). – Jonathan Leffler Feb 29 '20 at 19:04
  • @EricPostpischil With the `-pedantic-errors` or `-Werror -Wpedantic` options, It won´t get compiled. – RobertS supports Monica Cellio Feb 29 '20 at 19:11