2
if(true/false){
     //if condition is true 
}else {
     // if condition is false
}

Everyone knows about the structure of if-else. But what is if actually? Is it a class method, static method or keyword? I'm little confused about this.

14
  • 1
    already seen not clear...! Feb 15, 2013 at 7:00
  • 2
    I think you guys are missing the point. He's not actually asking how it works, he's asking for definitions. Feb 15, 2013 at 8:11
  • 4
    Conditional constructs like if / then / else work in wildly differing ways across different programming languages, both syntactically and semantically. Hence, your definition will depend on the programming language.
    – tdammers
    Feb 15, 2013 at 11:10
  • 4
    Oh come on, I'm sorry, but if this is supposed to be a site for Professional Programmers as per the FAQ then this is clearly a bad question.
    – user7007
    Feb 16, 2013 at 13:42
  • 2
    @tdammers A branch is a branch.
    – user7007
    Feb 16, 2013 at 14:23

8 Answers 8

37

It seems to me that you are asking two different questions:

  1. How if else works internally?
  2. What if is in terms of high level programming?

This answer is for question 1. For question 2 see other answers. Gustav Bertram's answer seems very clear.

Before your code gets executed, it must be translated into machine code. The translation is done by either a compiler (like a C-compiler) or an interpreter (like Ruby interpreter) or a virtual machine (like with Java).

Control structures like if-else are translated into a pattern of machine code instructions. The actual pattern depends on the target machine and the compiler/interpreter/virtual machine. An if-else-structure like

if (x >= y) {
    // main branch
} else {
    // else branch
}

could be translated into code (here some kind of pseudo-assembly) like

cmp (r1),(r2)    ;compare words at memory addresses pointed by registers r1 and r2
blt else         ;jump to else-part if (r1) is less than (r2)
   ...           ;insert the main branch code here
bra end_if       ;jump to end_if
else:
   ...           ;insert the else branch code here
end_if:

The actual machine code consists of just binary data but it is structurally similar with assembly code.

4
  • 4
    +1. What better way to define terms than to write the assembly equivalent.
    – Neil
    Feb 15, 2013 at 8:51
  • 5
    If I may add something: you'll find that the assembly equivalents of all flow commands ultimately use the same two assembly lines - Comparison and jump. At the assembly level, there would have been no difference if rather than use if-else, you had chosen to use if(condition) goto ifcode; <else code>; goto end; ifcode: <if code>; end:
    – Neil
    Feb 15, 2013 at 8:57
  • @Neil, depends on the processor's instruction set. ARM has some interesting stuff with conditional instructions. Feb 16, 2013 at 16:22
  • @PeterTaylor I suppose it depends on if you're compiling for that specific processor or not. Otherwise, despite being able to do other instructions, it would behave normally.
    – Neil
    Feb 19, 2013 at 8:17
17

This answer is about languages like C, C++, Java, PHP and Javascript. There are other programming languages that work differently.

if is a keyword, and else is a keyword. When they are used in code, if and else together form a control flow statement.

Class methods, or static methods are always functions or procedures that are attached to a class. "Method" means the same thing as "function" or "procedure", but on a class.

if else is not a function, but it can appear inside a function.

# This part is a function, and *could* be a class method or static method
function hello($name)
{

  # This part is a control flow statement, and can be *inside* a function
  if($name=='Peter')
  {
    #The next line is one statement
    echo 'Hello Pete!";
  } else {
    echo 'Hello $name!";
  }

}

These are examples of keywords: if, else, while, for, case, continue, function, return, class, public, private, protected, static, new.

Each programming language has different keywords. What your keywords are, and how they work are different in every language.

Keywords (if, else), operators (==, <, !=), variables ($name), string literals ('Peter'), functions (echo, hello) all work together to make statements. Statements do all most of the work, and are grouped into functions or methods (usually).

I think you should try Code Academy. It teaches basic programming, and it might help you understand the parts of programming statements.

You should also try to find a book that teaches your programming language. Such books should explain the parts of statements too. If one book is not clear, try another one.

8
  • thanks for clarify @Gustav can you please tell me how keyword works Feb 15, 2013 at 8:07
  • I have updated my answer. Feb 15, 2013 at 8:35
  • +1 This is a fine answer to the question "what if is" in terms of high level programming. My answer is about how if is implemented or how "it works internally" like the title of the question seems to ask.
    – COME FROM
    Feb 15, 2013 at 9:58
  • 1
    -1 for statement-centric views like statements do all the work, sorry, with all due respect, this is BS. There are even languages that do not have statements, yet the workis done nevertheless.
    – Ingo
    Feb 15, 2013 at 16:22
  • 2
    Please understand that I simplified my answer as much as possible for a person who does not understand programming very well, and who does not understand English well either. I thought that an explanation of compilers, or any mention of functional languages, would be too hard to follow. Given the braces in the original question, I assumed C-like languages, which I think is a reasonable simplification. Feb 16, 2013 at 6:47
7

It can actually be several things. In imperative languages like C++ or Java, it is a statement type. In pure object-oriented languages like Smalltalk it is an instance method of boolean. In pure functional languages it is a function.

But in all languages it is a primitive. Some form of conditional must be built into the language. It may be slightly different type of conditional (e.g. cond in Lisp), but one must be built in.

6
  • 2
    Not necessarily a primitive. In the pure lambda calculus you don't need any conditional execution primitives, see en.wikipedia.org/wiki/Church_encoding
    – SK-logic
    Feb 15, 2013 at 9:41
  • 6
    Your statements contradict each other: in your first paragraph you say that in Smalltalk, conditionals are implemented as instance methods on Booleans. That is correct. However, then in your second paragraph you claim that conditionals are always primitive, but that is not true, because, as you already explained, in Smalltalk they are not, they are just instance methods. Smalltalk uses the Church Encoding of Booleans to encode conditionals, the same way you do in Lambda Calculus. Feb 15, 2013 at 10:12
  • Is Smalltalk not an imperative language? Feb 16, 2013 at 20:20
  • @JörgWMittag: So you are saying that boolean in Smalltalk can be defined in the language itself? Because unless it can, it's methods are still primitives.
    – Jan Hudec
    Feb 18, 2013 at 6:54
  • @TomHawtin-tackline: Yes, Smalltalk is imperative language too. If somebody knows how to call non-object-oriented procedural languages, it would be better, but I couldn't think of anything.
    – Jan Hudec
    Feb 18, 2013 at 6:57
2

As the others have already explained, control flow is usually implemented with branching instructions.

But, jumps are not always necessary. In some ISAs there is a so called "conditional execution": instructions will be bypassed if they're marked as conditional and a flag after a previous comparison operation is not set. Jumps can be mispredicted and may thrash pipeline, whereas a short sequence of conditional instructions might be much cheaper.

Another interesting form of low level control flow is a so called "zero-overhead looping", common in many modern DSP processors (e.g., in Hexagon).

2

Internally on x86/64 architecture if/else/then is generated with internal CMP mnemonic.

It compares the results and sets the EFLAGS register with appropriate flags(zero, overflow, etc.).

Internally if the arguments are equal their minus product is zero. For example if (a == b) where a = 10, b = 10. Processor does 10-10=0. Once the result is zero - ZF(Zero Flag) is set.

So:

cmp a, b
jz equal
jnz notEqual

JZ - Jump if Zero is equal to JE as well as JNZ(Not Zero) is equal to JNE(Not Equal). They are equal and JE and JNE exist just because of readability.

  • JL stands for - Jump if Less
  • JG stands for - Jump if Greater
2

It really depends on the language, of course. Since you're giving a pseudo-C example, I'll stick to how it works in most C-like languages.

A program has to be translated to machine-code in the end, so we have to talk about machine code first.

Let's start with an (imaginary, but that's the idea) very old computer who is able to perform these operations only :

  • 1 : put the value punched in by the operator into register A
  • 2 : put the value punched in by the operator into register B
  • 3 : put the following value into register C
  • 4 : put the content of C into A
  • 5 : put the content of A into C
  • 6 : add A and B and put the result into register A
  • 7 : subtract A and B and...
  • 8 : multiply A and B...
  • 9 : divide A and B and put the quotient into register A
  • 10 : print the value that is in register A on a little piece of paper

So, the following "program" saved on, say, a punched card :

  • instruction 1 : 1
  • instruction 2 : 2
  • instruction 3 : 6
  • instruction 4 : 10

Would put a number in A, then another in B, add them and put the result in A then print it on a piece of paper. The point is, very old computers did not have any possibility of conditional execution or loops. A program was nothing more than perform this calculation, then this one, then this one, and so one. They were little more than a calculator to which you gave a list of calculations to perform.

That soon became a problem : very often, we want a calculation not to be performed in some situations ; for example, if the current value is 0, I don't want to divide another number by it ! Computers had to be enhanced, and that was a big and (somewhat) complicated improvement : now, your computer has to be aware of where it is in the current program flow and act on it ; just reading the current instruction and going to the next one is not enough.

That means you have to add the following instructions to go forward :

  • 11 : go to instruction #n, n being the value in the next "instruction"

Very good, now you can skip instructions if needed ; for example, you can skip the division instruction if you do not want to perform it. Well, actually, we will always jump, so that's a rather useless statement. Let's rewrite it this way :

  • 11 : go to instruction #n, only if the value in A is 0

Yep, an "if statement", that's where it is actually implemented : in a machine instruction. It's very low level and limited, but that's actually not a problem because you can do anything you want with it. It's hard to use, but high-level languages will deal with that for you. Note that it is really very powerful : you can implement loops with it, too (loops are a jump backward rather than forward).

Let's write the following program : read two numbers, subtract them. If the result is not 0, read a third number, divide it by the result and print the overall result.

  • instruction 1 : 1
  • instruction 2 : 2
  • instruction 3 : 7
  • instruction 4 : 11
  • instruction 5 : 7
  • instruction 6 : 2
  • instruction 7 : 10

Well, that's rather boring to write programs this way, so assembly languages were invented :

  • READ-A
  • READ-B
  • SUB
  • JMP-IF-ZERO .endif
  • DIVIDE .endif:
  • PRINT

And, since assembly is dull and error-prone too, we invented high-level languages such as C. The following pseudo-C program is the equivalent as above :

a = read();
b = read();
a = a - b;

if (a != 0) {
   b = read();
   a = a / b;
}

print(a);

The way if is translated by your compiler in machine instructions : the condition after the if keyword is transformed as a test whose result is stored in A, and the number of the instruction where to jump is determined based on where your bracket closes.

1

Once you get down to the metal, it is a jump/branch statement -- basically a fancy goto. Higher level languages have control structures that let you implement common low level activities in a clear and understandable manner. But when you get down to it, it's a bunch of registers, jumps and poking things in and out of memory.

2
  • I think that many programmers would be scared if they looked at how assembly language works :-)
    – Konamiman
    Feb 15, 2013 at 11:44
  • No. Real programmers wouldn't :) Feb 18, 2013 at 10:15
0

This in fact depends on the language you are talking about.

There are excellent answers here on how if and else are keywords and form control flow statements because when compiled to a sequence of instructions, these statements control the execution flow of the instruction sequence - which of course is sequential by default, but can have jumps in order to allow execution to depend on the current state. And this is certainly true for a whole set of languages.

But there are a couple of languages, such as Smalltalk and Lisp (probably the most prominent examples), that actually implement their equivalent of control flow statements as methods or macros respectively, over a very basic mechanism for conditional execution/jumps.

4
  • All the major Lisps actually provide a conditional primitive.
    – SK-logic
    Feb 16, 2013 at 17:46
  • @SK-logic: How is that different from what I said? Of course you need some primitives, but if it's a conditional one, you also need jumps to construct some kind of loop (unless you wish to build loops through recursion, which is impractical even with today's hardware). So yes, cond, tagbody and go do the trick. A tagbody and goif would be enough to construct cond. Or you can also compose branching from loops and sequences alone. But all that is an implementation detail.
    – back2dos
    Feb 16, 2013 at 22:20
  • you just need to clarify that macros per se are not an underlying implementation mechanism. There is usually a set of simple primitives and a number of higher level macros expanding into such primitives.
    – SK-logic
    Feb 17, 2013 at 20:38
  • Last part says: implement their equivalent of control flow statements as methods or macros respectively, over a very basic mechanism for conditional execution/jumps. whether that "basic mechanism" as I called it is in fact a set of first class primitives (as in most Lisp implementations) or somehow hacked into the language (as in many Smalltalk implementations) tends to vary.
    – back2dos
    Feb 18, 2013 at 9:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.