Wise Owl Wise Owl - 4 months ago 18
C Question

What is the reason for the double negation -(-n)?

I'm going through some legacy code and I've seen something like

char n = 65;
char str[1024];
sprintf(str, "%d", -(-n));

Why has the author (no longer present) written
rather than just
? Wouldn't


The first thing to note that --n actually decreases n by 1 and evaluates to the new value, with the type char, so it does something very different to -(-n). Don't change the code to that!

-n performs a unary negation of n and is also an expresion of type int due to the type promotion rules in C. The further negation sets it back to the original value but with type int.

So -(-n) is actually a verbose way of writing +n, which is often though to be a no-op but in this case it converts the type of n to an int.

I suspect the author is guarding themselves against errant refactoring and they were worried about mismatching the type of the argument with the format specifier %d.

But in this particular case it does not matter: sprintf will automatically promote the char type to an int, so it's perfectly safe to write

sprintf(str, "%d", n);

Do also consider reducing the size of the str buffer if that's "real" code, and consider using the safer snprintf variant.

(As a final remark note that a double negation can yield signed integral type overflow, so do use with caution.)