0

I need to specify an argument short option (e.g. -F) both as char and char[] constant in c code. In order to maximize code reusage I want to declare a variable which allows me to change the value in one place (a "literal" - not stringly speaking a string or char literal, but in the sense of the abstract concept). I would prefer a solution which solves this exclusively in preprocessor constants and functions/macros or exclusively in c code to a good explanation why this has to be solved in a mixture of both.

I tried/checked out

  • to #define FOREGROUND_OPTION_VALUE 'F' which causes me trouble to transform it to a char[] (as preprocessor constant) (writing a macro which stringifies with # causes the ' quotes to be stringified as well
  • to omit the ' quotes which leaves me with the problem of creating the ' quotes or create a char another way.
  • @PedroWitzel's answer to declare a char[] and use the 0th char for another constant. That's fine, but I'd prefer a way to create the char[] from the char because that enforces both to be equal (otherwise I'd have to add a compile time assertion that char[] isn't longer than 1).

The only thing that matters for me is code maintenance, nothing else (like cost in processing the code (during compilation or runtime - have not reflected intensively if there could be any and don't care)).

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177

2 Answers2

3

Over and above the discussion in comments to Pedro Witzel's answer, there's another option:

#define FOREGROUND_OPTION_VALUE 'F'

static const char fg_opt_str[] = { FOREGROUND_OPTION_VALUE, '\0' };

It's not a commonly used way of initializing a string, but it is a valid one and seems appropriate for your scenario. Now you can use FOREGROUND_OPTION_VALUE where you need a constant char (or int) value, and fg_opt_str where you need a one-character string. If you change the value defined (to f, say), then you only have to change one place for the code to continue to work, assuming you weren't using f before, which meets your maintainability requirement.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks. As mentioned in my question a statement on whether this mixture of preprocessor definition and c source code is _necessary_ (besides the fact it's absolutely valid) would be appreciated. – Kalle Richter Apr 25 '15 at 19:11
  • It depends on what you want to do. It might not be necessary if your code deals only with strings, or only with character constants. But if you need both and they need to be kept in sync automatically, then you'll need some technique along the lines outline here and by Pedro Witzel to do the job. Which works best for you depends on your requirements. We can't see enough of your code to be able to advise on that. – Jonathan Leffler Apr 25 '15 at 19:28
  • I need a constant and didn't point that out in the initial question which was not very smart. It's clear if I need a constant, only, though?! – Kalle Richter Apr 25 '15 at 19:35
  • If you need something that's a string literal — for string concatenation, etc. — as well as a character constant, then I don't know that there's a way to get that; we're back to where we started. Some things aren't worth fighting over. You could arrange to generate the code that has to be kept in sync: for example, given a specification `FOREGROUND_OPTION F`, your code generator might generate `#define FOREGROUND_OPTION_VALUE 'F'` and `#define FOREGROUND_OPTION_STRING "F"` — the code generator could be as simple a `sed` script. – Jonathan Leffler Apr 25 '15 at 19:43
2

A static constant variable would work for you?

static const char FOREGROUND_OPTION_VALUE[] = "F";
Community
  • 1
  • 1
Pedro Witzel
  • 368
  • 3
  • 14
  • How does that reuse the specification of `F` for a `char` and a `char[]` at one place? – Kalle Richter Apr 25 '15 at 17:36
  • @KarlRichter: when you need the string you use `FOREGROUND_OPTION_VALUE`, when you need the `char` you use `*FOREGROUND_OPTION_VALUE`. – Matteo Italia Apr 25 '15 at 17:39
  • 3
    @KarlRichter: You use `FOREGROUND_OPTION_VALUE` when you want a string and `FOREGROUND_OPTION_VALUE[0]` or `*FOREGROUND_OPTION_VALUE`when you want a single character. This is as good as it gets. You won't be able to use this as a `case` label in a `switch` statement, but other than that, it should be workable. You can also use `#define FOREGROUND_OPTION_VALUE "F"` as in the question, and either of the expressions I suggested to access the character. – Jonathan Leffler Apr 25 '15 at 17:39
  • I don't think you'll be able to use the same variable for two different types, witch are essentially char and char*. I'd say the best way to go is to cast properly, as suggested by @JonathanLeffler. It would improve readability and code maintenance as you'd be certain that you use the right type. – Pedro Witzel Apr 25 '15 at 18:31