176

I was surprised by this code:

if (a =! b) { // let it be on false
    ...
}

But a is never assigned by a value. What's this operator about?

m0nhawk
  • 22,980
  • 9
  • 45
  • 73
  • 3
    `"But a is never assigned by a value"` - what are you trying to say by this? – AnT stands with Russia Jan 09 '14 at 19:20
  • 1
    Pre-ANSI C apparently had a few things like that (`=+` instead of `+=`). But I doubt this code is that old. Assuming the comment's correct, the code needs to be fixed. – Max Lybbert Jan 09 '14 at 19:23
  • 1
    @MaxLybbert B seem to have had `=|`, `=&`, `=+`, `=-`, `=%`, `=*`, and `=/` (see http://cm.bell-labs.com/cm/cs/who/dmr/kbman.html), but probably not `=!` – leo Jan 09 '14 at 21:13
  • 43
    [lol, here's the Java version of the same question.](http://stackoverflow.com/questions/8825840/what-is-the-difference-between-and-in-java) – Mysticial Jan 09 '14 at 21:34
  • 59
    It's *almost* Yoda's `!=` operator. "a equals not b". Better would be "a, b, equals not". But `a b =!` or `a,b =!` doesn't compile. – allquixotic Jan 09 '14 at 22:34
  • 3
    you can omit spaces in a lot of C. you can write a program like this: `#include ` `int main(){int a=0;int b=1;if(a=!b){printf("hello");}else{printf("bye");}};` hope my C isn't so rusty that I made a syntax error... anyway here are some examples of how evil you can be: the [IOCCC](http://www.ioccc.org/). – 2rs2ts Jan 10 '14 at 03:18
  • 6
    This bears remarkable similarity to the "goes to" operator `-->` as used in `while(i --> 10)`. See http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-operator – Jens Jan 10 '14 at 08:03
  • 1
    Note that Visual C++ will emit *warning C4706: assignment within conditional expression* for this. Not sure about GCC. – sharptooth Jan 10 '14 at 09:12
  • I think more likely a typo of someone trying to type `if (a == !b)` – Matt Wilko Jan 10 '14 at 14:50
  • 5
    You marked this question with the C++ tag.. So, it can really be anything, depending on the type of a, because of operator overloading. In this case, the overloaded operator is the `=`. Unless you're using a variation of C or C++ with has a special meaning for that – Javier Jan 10 '14 at 15:50
  • 1
    Put `if (a =! b)` into Visual Studio and press `Ctrl+k,d` and you will see it miraculously turn into `if (a = !b)` – Matt Wilko Jan 10 '14 at 16:02
  • @llquixotic `a,b =! -- yoda;` compiles if `b` is an integral type and `yoda` is an `int`. – Yakk - Adam Nevraumont Jan 10 '14 at 16:24
  • 2
    When you say *`"But a is never assigned by a value."`*, do you mean that 1) prior to the **`if (a =! b) {`** statement, a was undefined, or 2) after the **`if ... {`** statement, a was unchanged? – Kevin Fegan Jan 10 '14 at 17:03
  • 2
    If you like that one, you might be interested in the NAND operator, which is written `&~` as in `a = b &~ c`. – tchrist Jan 11 '14 at 15:05
  • @ThomasW. Doesn't always work. See http://stackoverflow.com/questions/14228060/what-does-the-operator-do?lq=1 – Charity Leschinski Jan 12 '14 at 15:04

13 Answers13

391

That's two operators, = and !, not one. It might be an obfuscated way of writing

a = !b;
if (a) {
    // whatever
}

setting a to the logical inverse of b, and testing whether the result is true (or, equivalently, whether b was false).

Or it might be a mistyping of a != b.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 42
    I wonder if it was a typo of someone trying to type != especially since it is in an if statement – Cory Kramer Jan 09 '14 at 19:21
  • @Cyber: Good point, worth mentioning in the answer. Thanks. – Mike Seymour Jan 09 '14 at 19:22
  • 35
    Sadly it may be the case that somebody just considers this "their style". – Radiodef Jan 09 '14 at 20:47
  • 184
    Whoever writes obsfuscated code by making up their own operators can `-->` hell. Wait, nooooooooooo! – corsiKa Jan 09 '14 at 23:12
  • 3
    @Cyber almost certainly not a mistyping, as the comment that follows it makes a vague kind of logical sense given what it actually does. I wouldn't be able to interpret that comment without the code, but it definitely seems to be in agreement. – Jules Jan 10 '14 at 05:42
  • 2
    For major obfuscation points, if the = operator was overriden to return something OTHER than the LHS, you could have some REAL fun. – Aron Jan 10 '14 at 06:06
  • 1
    @corsiKa You're safe! Someone beat you to it: http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-operator?lq=1 – Ken Jan 10 '14 at 09:22
  • 1
    @corsiKa Damn, this probably means that there’s a special place in hell [reserved just for me](https://github.com/klmr/named-operator) … – Konrad Rudolph Jan 10 '14 at 15:06
  • @Jules I would still say it's a mistype. Surely the original author didn't mean to type `a =! b` instead of `a = !b`. – Caltor Jan 10 '14 at 15:37
  • 1
    @Caltor I think you overestimate the ability of developers to do incredibly stupid things on purpose. – corsiKa Jan 10 '14 at 21:32
  • 1
    Can anyone provide an example of what reason this code might be used, or the concept of assigning `NOT var` to something? I haven't experienced it myself and can't create an example. – HC_ Jan 10 '14 at 23:04
  • @Cyber The OP said *"a is never assigned by a value"* implying this couldn't be a mistype of `!=` because `a` is not assigned anywhere else. (Since the OP originally did not know this *was* an assignment.) Though what the OP meant by *"assigned by a value"* is grammatically vague. – Radiodef Jan 10 '14 at 23:57
  • @HC_ It's all going to be obscure-seeming. Maybe `b` is actually a method call or non-boolean. – Radiodef Jan 11 '14 at 00:12
  • We had a programmer that liked to write =! instead of !=. He's no longer with us, so I can't ask him why. Perhaps there's a lesson there somewhere... – R Hughes Jan 12 '14 at 07:37
280

Long ago, when dinosaurs roamed the earth and C ran on 5th edition UNIX on PDP-11s, =! was the 'not equals' operator. This usage was deprecated by the creation of Standard C, so now it means 'assign the logical inverse', as in a = !b. This is a good argument for always surrounding binary operators with spaces, just to make it clear to the humans reading the code what the compiler is thinking.

I'm a bit surprised nobody else mentioned this, but then again I may be the only SO user to have ever touched a C compiler that old.

Wexxor
  • 1,919
  • 1
  • 15
  • 17
  • 68
    **+1**: I ruled out any sort of ancient syntax the second I saw the `//` single-line comment. This code ***has*** to be C++ or some newer version of C for it not to have a `/* ... */` comment. Nice bit of trivia nonetheless. – Andon M. Coleman Jan 10 '14 at 04:03
  • 6
    s/dinosaurs/[compusaurs](http://alumnus.caltech.edu/~lschmidt/compusaurus.html) :) – Ray Toal Jan 10 '14 at 07:35
  • 7
    This is actually the only good answer to 'What's this operator about?'. All the others seem to try to ignore the existence of the operator. – Kevin Jan 10 '14 at 08:24
  • 24
    So, were dinosaurs as cool as we imagine? – bolov Jan 10 '14 at 09:24
  • 1
    Its also a good argument for designing languages to not use assignment as a boolean operator with a return value. – T.E.D. Jan 10 '14 at 19:44
  • 16
    In elder days before the fall of mighty kings in Gondolin the ancient scribes would also invert the order of assignment operators, writing `a =+ b` to mean what we now render as `a += b`. Digraphic operators have a nasty way of mixing up with monographic ones when whitespace doesn’t matter but order does: consider `a =- b`,`a = -b`, vs `a -= b`. Here of old be dragons, but none so great as before after Eärendil slew Ancalagon the Black and broke Thangoradrim beneath his fall. I was there when we thought evil vanquished forever, but ever it returns from the darkest of codes to trouble us anew. – tchrist Jan 11 '14 at 15:13
  • 1
    @tchrist: s/Thangoradrim/Thangorodrim/ – ninjalj Mar 10 '14 at 14:12
54

a is assigned the boolean negation of b in that line. It is just a misformatted

if( a = !b ) {

... and an evil hidden assignment inside a condition.

Timbo
  • 27,472
  • 11
  • 50
  • 75
  • 4
    Assignments inside a condition are not evil... though in this case the use of whitespace is confusing. – Thomas Jan 11 '14 at 01:52
  • 3
    Assignments in a condition are indeed evil. It's important when you're coding to produce something that can be read and understood with a minimum of effort. Readability is an important part of maintainability. So if you're writing a condition - make it look like a condition. If you're doing an assignment - make it look like an assignment. Never try to disguise one as the other, or bury one within the other. – Dawood ibn Kareem Jan 11 '14 at 18:04
  • `while (--t) { ... }` is common, but it's not exactly the assignment operator. – Vortico Jan 12 '14 at 08:03
  • @Vortico but it is not so easily readable, and may cause headache if someone writes `--t+y`, for example – Display Name Jan 12 '14 at 08:22
46
a =! b 

is just a funny way of putting

a = !b

i.e. the assignment of not b to a.

The value of the expression is a after the assignment.

With the code below you can see that the value of the expression a = !b is !false (i.e. true), and you can then see the assignment has taken place by checking the value of a, which is also true.

#include <iostream>

int main() 
{ 
    bool a = false;
    bool b = false;

    if(a)
        printf("a is true!\n");
    else
        printf("a is false!\n");

    if(a = !b)
        printf("expression is true!\n");
    else
        printf("expression is false!\n");

    if(a)
        printf("a is true!\n");
    else
        printf("a is false!\n");

}

Result:

a is false!
expression is true!
a is true!
splrs
  • 2,424
  • 2
  • 19
  • 29
35

Operators in C++

According to C/C++ operators list there is no operator such as =!. However, there is an operator != (Not equal to, Comparison operators/relational operator)

There are two possibilities.

  1. It could be typo mistake as I've noticed that =! operators is in if statement and someone is trying to type != instead of =! because != is the comparison operator which returns true or false.
  2. Possibly, the developer was trying to assign the boolean negation of b to a and he/she has done a typo mistake and forgot to put a space after equal sign. This is how the compiler interprets it, anyways. According to Operator precedence in c++:
    • Operator Logical NOT (!) precedence is 3 and Associativity is Right-to-left
    • Operator Direct assignment (=) precedence is 16 and Associativity is Right-to-left
Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
SK.
  • 4,174
  • 4
  • 30
  • 48
  • 2
    thanks for the link to the operator precedences, that's really important to keep in mind in general. – 2rs2ts Jan 10 '14 at 03:22
  • Please explain why operator precedence and associativity are important for parsing `a =! b`... – Matthias Jan 11 '14 at 13:35
  • 1
    =! is not single operator, they are two. So compiler use precedences and associativity to execute these two operator. Which one has to execute first and second. May this help u – SK. Jan 11 '14 at 14:59
21

They are two different operators: the = (assignment) operator together with the ! operator. It can basically be translated to an assignment of a to the negated value of b.

if (a = !b)

But, what the user, probably, meant to write was the != operator:

if (a != b)
Shoe
  • 74,840
  • 36
  • 166
  • 272
20

That is not a single operator, it is however, a great way to obfuscate code.

If it were written a=!b instead, the white space might not lead you to believe that it was a single operator.

Compilers have warnings for assignment in a conditional expression unless you wrap the entire statement in a set of parenthesis, and this is a perfect example of when this warning would be useful.

Both of these statements are functionally identical, but one generates a warning and the other does not:

if (a =! b)   // Generates a warning with `-Wparentheses` (gcc)

if ((a =! b)) // No such warning

-Wparentheses

Warn if parentheses are omitted in certain contexts, such as when there is an assignment in a context where a truth value is expected, or when operators are nested whose precedence people often get confused about.

This, of course, assumes that you are a responsible programmer and actually read the warnings your compiler spits out.


Using white space in a more reasonable way, the statement is actually:

if (a = !b) // Assign A the value of (logical) NOT B and then test the truth

The compiler warning mentioned above is actually useful in the case where the person who wrote this code accidentally transposed ! and =. However, from the cryptic inline comments in your original question, a = !b is probably the author's intention.

Community
  • 1
  • 1
Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
18

C++ does not have an =! operator, which immediately means that this is an = operator followed by a ! operator. So, you simply have a = !b in the if condition.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
12

This is all about clarity of code:

It should be written as: if (a = !b)

if (a = !b) is the same as saying if a is assigned to !b. So there are technically 2 separate operators being used, = which is an assignment operation, and ! which is a logical expression.

Just put a space between = and ! it solves this confusion.

Ryman Holmes
  • 746
  • 3
  • 22
  • 40
11

There could be three reasons for this:

  1. It could be a mistyping of the != operator, meaning not equal to. Example:

    if (a != b) {
        // a is not equal to b
    }
    
  2. It could be a mistyping a == !b, meaning a is equal to not b, which would most commonly be used with booleans. Example:

    if (a == !b) {
        // The boolean a is equal to not b (a is not equal to b)
    }
    
  3. It could be trying to assign a to the inverse of b. Example:

    bool a = !b; // Sets a to the opposite of b
    
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jojodmo
  • 23,357
  • 13
  • 65
  • 107
  • 1
    2) Not weird, downright wrong; 3) Why not in an if statement? Did someone remove the return value from assignments while no one was looking? – blgt Jan 10 '14 at 09:22
10

I think this is one of the writing or printing mistake. Because if we can not compile this code as it holds a compiletime error. And here this is inside if clause, the return type must be boolean. So how can it possible. The answer is simply a mistake or as Mike said obfuscated way of writing.

And only possible if both variables a and b are boolean which will be compiled as a is equal to (not)b i.e (a = !b) .

Ranjit
  • 5,130
  • 3
  • 30
  • 66
6

This can be taken as a is assigned to !b.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nitin Misra
  • 4,472
  • 3
  • 34
  • 52
4

I am trying to answer your question and, in agreement with Mike's answer, I am just adding up.

You can also understand it by a=!!b.
The code a=!b returns 0 to a and a=!!b returns 1 to a.

The =! is not a single operator but the mix of these two. These types of question are asked to misguide students to check their coding skills.

Community
  • 1
  • 1
  • To link to an answer just click on the **Share** button at the end of the post, copy the link and enter it like this: `[answer](http://link)`. –  Jan 10 '14 at 18:18