1

Please help me to rewrite the below condition in a better way

This is a c code

 if(a == MACRO1)
 strcpy(x,"S")
else if (a == MACRO2)
 strcpy(x,"K");
kiran Biradar
  • 12,700
  • 3
  • 19
  • 44
thamu
  • 29
  • 6

6 Answers6

4
if(a == MACRO1)
 strcpy(x,"S")
else 
 strcpy(x,"K");

can be :

strcpy(x, (a == MACRO1) ? "S" : "K");

but

if(a == MACRO1)
 strcpy(x,"S")
else if (a == MACRO2)
 strcpy(x,"K");

has a missing else and to do

strcpy(x, (a == MACRO1) ? "S" : ((a == MACRO2) ? "K" : x));

is not correct because the argument of strcpy must not overlap but in that specific case not sure it is a true problem (even undefined behavior) , but also x is may be not yet initialized, and what about the performances ...

bruno
  • 32,421
  • 7
  • 25
  • 37
  • With `char *strcpy(char * restrict s1, const char * restrict s2);`, arguments referenced data of `strcpy` must not overlap is true, else technical UB per 6.7.3.1 4, although I agree: doubtful true problem with `strcpy(x, x);` – chux - Reinstate Monica Jan 30 '19 at 19:27
4

Formally, it can be rewritten as equivalent

a == MACRO1 ? strcpy(x, "S") : 
a == MACRO2 ? strcpy(x, "K") : 0;

but there's no meaningful reason to do so, unless it is just a puzzle (or unless there's a credible reason to maintain expression semantics).

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
3

Setting aside this beautiful answer, this cannot be written as a two "nested" ternary conditional operators since there is nothing to do for any value of a other than MACRO1 and MACRO2, and it's not possible to trick strcpy into a no-op. (The behaviour of copying x to itself is undefined.)

So you are best off leaving the code as it is. Note that in terms of programming history, the ternary conditional operator was invented before the if else control block due perhaps to the deficiencies in the former, as epitomised in the case you present.

You could submit

strnpcy(x, a == MACRO1 ? "S" : "K", 2 * (a == MACRO1 + a == MACRO2));

to the next obfuscation contest though.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1
strcpy( x, (a == MACRO1)? "S" :
           (a == MACRO2)? "K" : "error" );

Like your original code, this will copy either "S" or "K" to variable x.

If a is neither MACRO1 nor MACRO2, it will copy "error" to buffer x with an assumption that x is large enough to hold "error" string.
(You should figure out a better way to handle the case where a is neither of the two macros)

H.S.
  • 11,654
  • 2
  • 15
  • 32
abelenky
  • 63,815
  • 23
  • 109
  • 159
-1

it can be also

{
    char *dummy;

    dummy = a == MACRO1 ? strcpy(x, "TextA") : a == MACRO2 ? strcpy(x, "TextB") : strcpy(x, "error");
}
0___________
  • 60,014
  • 4
  • 34
  • 74
-1

Simplest way, behaving like original, appending nothing if a doesn't match either MACRO1 or MACRO2:

strcpy(x, (a == MACRO1)?"S":(a == MACRO2)?"K":x);
  • This isn't like the original; it overwrites `x` with the empty string if neither comparison succeeds. You could replace `""` with `x`, which would at least make it an expense no-op (or actually undefined, as pointed out in https://stackoverflow.com/a/54443256/1126841). – chepner Jan 30 '19 at 16:56
  • (If `strcat` were used instead of `strcpy`, then `""` could be used as the identity element for an expensive no-op.) – chepner Jan 30 '19 at 16:57
  • Fixed! Thanks, I have overlooked it and at first I thought it was strcat, not strcpy :D –  Jan 30 '19 at 17:46