What is this operator?

?:

  • (2 Pages)
  • +
  • 1
  • 2

17 Replies - 1100 Views - Last Post: 16 June 2009 - 06:54 AM Rate Topic: -----

#1 IngeniousHax  Icon User is offline

  • |>|20-514<|{3|2

Reputation: 78
  • View blog
  • Posts: 1,358
  • Joined: 28-March 09

What is this operator?

Posted 27 May 2009 - 08:09 PM

What does the two of those when placed together signify? Does that basically mean to select the higher of two values or...?
Is This A Good Question/Topic? 0
  • +

Replies To: What is this operator?

#2 BlakeJustBlake  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 26
  • View blog
  • Posts: 441
  • Joined: 15-February 09

Re: What is this operator?

Posted 27 May 2009 - 08:13 PM

It's a ternary if operator. It works like this:

This:
cout<< n > 5 ? "greater than five" : "not greater than five";

is the same as:

if(n > 5) {
cout<<"greater than five";
}

else {
cout<<"not greater than five";
}


Was This Post Helpful? 1
  • +
  • -

#3 Mowgef  Icon User is offline

  • D.I.C Head

Reputation: 11
  • View blog
  • Posts: 245
  • Joined: 01-May 09

Re: What is this operator?

Posted 27 May 2009 - 08:14 PM

Pretty sure its like

if(bool)?trueDoThis:falseDoThis;
Was This Post Helpful? 0
  • +
  • -

#4 IngeniousHax  Icon User is offline

  • |>|20-514<|{3|2

Reputation: 78
  • View blog
  • Posts: 1,358
  • Joined: 28-March 09

Re: What is this operator?

Posted 27 May 2009 - 08:15 PM

Alright, thanks blake, I was curious cause I had seen it in programs and had no idea what it did, I googled and couldnt find anything,.
Was This Post Helpful? 0
  • +
  • -

#5 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: What is this operator?

Posted 27 May 2009 - 08:29 PM

The conditional or tertiary operator -- it is much like an if-else structure except that it forms a "conditional expression" -- so the result of a conditional expression can be used in other expressions.

the syntax is: condition ? true-expression : false-expression

Note that true-expression and false-expression must be an expression of the same type.
i.e you can't have ( a > b ) ? "Hello" : false -- since "Hello" is a string (or const char *) and false is a bool. So they are not of the same type and therefore this is not a valid use.
Was This Post Helpful? 0
  • +
  • -

#6 Mowgef  Icon User is offline

  • D.I.C Head

Reputation: 11
  • View blog
  • Posts: 245
  • Joined: 01-May 09

Re: What is this operator?

Posted 27 May 2009 - 08:54 PM

Do you know if you can nest them?
Was This Post Helpful? 0
  • +
  • -

#7 BlakeJustBlake  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 26
  • View blog
  • Posts: 441
  • Joined: 15-February 09

Re: What is this operator?

Posted 27 May 2009 - 08:58 PM

Try it out, I'm pretty sure you can't though.
Was This Post Helpful? 0
  • +
  • -

#8 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: What is this operator?

Posted 27 May 2009 - 09:08 PM

Yes you can next them... so long as in each the true-expression and the false-expression evaluate to the same type...

Note that nesting them DOES tend to get a little tricky with the operator presidence and so I recommend using the following syntax:

((condition) ? (true-expression) : (false-expression))

This will make it much easier to keep track of what is what. Also note that both the true and false expressions are evaluated!!! so using ++ and -- inside of these expressions can be very complicated.

I ran some tests and actually found the increment and decrement operators to be working as expected. It didn't make sense that both expressions are evaluated (defeats the whole purpose). The compiler does check to ensure that the types match but the expressions are not both evaluated -- that's just dumb of me to have written.
Was This Post Helpful? 0
  • +
  • -

#9 Mowgef  Icon User is offline

  • D.I.C Head

Reputation: 11
  • View blog
  • Posts: 245
  • Joined: 01-May 09

Re: What is this operator?

Posted 27 May 2009 - 09:15 PM

Lol, how crazy.
Was This Post Helpful? 0
  • +
  • -

#10 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: What is this operator?

Posted 28 May 2009 - 06:01 AM

I did some tests:
#include <iostream>

using std::cout;
using std::endl;

int main() {
	int a = 2;
	int b = 1;
	
	cout << ((a == b) ? a++ : b++ ) << " - ";
	cout << "A = " << a << " B = " << b << endl;

	cout << ((a == b) ? a++ : b++ ) << " - ";
	cout << "A = " << a << " B = " << b << endl;
	
	return 0;
}
Gives the correct output
Was This Post Helpful? 0
  • +
  • -

#11 Jubb  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 88
  • Joined: 06-May 09

Re: What is this operator?

Posted 28 May 2009 - 06:54 AM

Ternary operator is mostly used for assignments, to simplify assigning one value if the condition is true, and another if it is not.

If you want to use it, use it sparingly and make sure you comment what you are doing if anyone else is going to see your code later.

It is notorious for making things harder to understand, especially for people who haven't seen it before. That's why it is used in most obfuscated C programs.
Was This Post Helpful? 0
  • +
  • -

#12 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: What is this operator?

Posted 15 June 2009 - 06:43 AM

So I re-learned some things over this last weekend that I thought I would add to this thread.

First of all lets revisit this statement

Quote

Also note that both the true and false expressions are evaluated!!!
The COMPILER will evaluate both expressions (as far as the compiler can during compile time). This is actually really important to note.

The conditional operator constant expressions can be evaluated during compile time (just as any constant expression can). So for example if I were to compile the following bit of code:
#include <cstdio>

#define ODD_OR_EVEN(num) (num % 2 ? "Odd": "Even")
#define DISPLAY_RESULT(num) std::printf("%d is a %s Number!\n", num, ODD_OR_EVEN(num));

int main() {
	DISPLAY_RESULT(5);
	DISPLAY_RESULT(10);
	return 0;
}
The compiler generates
_TEXT	segment dword public use32 'CODE'
_main	segment virtual
@_main	proc	near
;	
;	int main() {
;	
	push	  ebp
	mov	   ebp,esp
;	
;		DISPLAY_RESULT(5);
;	
	push	  offset s@+20
	push	  5
	push	  offset s@
	call	  @_printf
	add	   esp,12
;	
;		DISPLAY_RESULT(10);
;	
	push	  offset s@+53
	push	  10
	push	  offset s@+29
	call	  @_printf
	add	   esp,12
;	
;		return 0;
;	
	xor	   eax,eax
;	
;	}
;	
	pop	   ebp
	ret 
@_main	endp
_main	ends
_TEXT	ends

_DATA	segment dword public use32 'DATA'
s@	label	byte
;	s@+0:
	db	"%d is a %s Number!",10,0
;	s@+20:
	db	"Odd",0
;	s@+24:
	db	"Even",0
;	s@+29:
	db	"%d is a %s Number!",10,0
;	s@+49:
	db	"Odd",0
;	s@+53:
	db	"Even",0
	align	4
_DATA	ends


The thing to note here is that the compiler did not produce ANY conditional code. Rather it inserted pointers to the static strings (s@+20 and s@+53). So the compiler evaluated the conditional rather than generating code to do the evaluation. This happened because it was a constant expression (like inserting int a = 1 + 1; into you code, the compiler simplifies this to int a = 2; since it is a constant expression).

This is very valuable for meta-programming. In meta-programming we can turn complicated constant expressions into simple constants in the final program. (Template Meta-Programming is considered Turing complete - so it can do just about any computation that you would like it to). The conditional operator allows us to create conditions expressions within meta-programs -- with one caveat -- The compiler WILL evaluate both the true and false expression -- which means that care must be taken when using the conditional expression within recursive or looping structures.

So I state again -- the conditional operator is NOT simply a replacement for if-else, it is an operator and forms conditional expressions which has a deeper significance. There are things that you can do with conditional expressions that you can not do with if-else statements -- Since the if-else statements must be evaluated at run time, but the compiler can evaluate constant conditional expressions at compile time.
Was This Post Helpful? 0
  • +
  • -

#13 mikeblas  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 43
  • View blog
  • Posts: 390
  • Joined: 08-February 08

Re: What is this operator?

Posted 15 June 2009 - 06:59 AM

View PostNickDMax, on 15 Jun, 2009 - 05:43 AM, said:

There are things that you can do with conditional expressions that you can not do with if-else statements -- Since the if-else statements must be evaluated at run time, but the compiler can evaluate constant conditional expressions at compile time.

if/else can be evaluated at compile time and thrown away, too. If I modify your code to use if/else like this:

#include <cstdio>

// #define ODD_OR_EVEN(num) (num % 2 ? "Odd": "Even")

const char *ODD_OR_EVEN( int num )
{
	if ( num % 2 )
		return "Odd";
	else
		return "Even";
}

#define DISPLAY_RESULT(num) std::printf("%d is a %s Number!\n", num, ODD_OR_EVEN(num));

int main() {
	DISPLAY_RESULT(5);
	DISPLAY_RESULT(10);
	return 0;
}




and then build it, I get code that shows the compiler inlined the function, then resolved the constant expression argument, since it was known at compile time, found the return result from the inlined code, and use that directly as a non-variant argument to the printf() call.

PUBLIC	_main
EXTRN	_printf:PROC
; Function compile flags: /Ogtpy
_TEXT	SEGMENT
_main	PROC

; 16   :	 DISPLAY_RESULT(5);

  00020	68 00 00 00 00	 push	 OFFSET $SG3741
  00025	6a 05		 push	 5
  00027	68 00 00 00 00	 push	 OFFSET $SG3746
  0002c	e8 00 00 00 00	 call	 _printf

; 17   :	 DISPLAY_RESULT(10);

  00031	68 00 00 00 00	 push	 OFFSET $SG3743
  00036	6a 0a		 push	 10		; 0000000aH
  00038	68 00 00 00 00	 push	 OFFSET $SG3747
  0003d	e8 00 00 00 00	 call	 _printf
  00042	83 c4 18	 add	 esp, 24		; 00000018H

; 18   :	 return 0;

  00045	33 c0		 xor	 eax, eax

; 19   : }

  00047	c3		 ret	 0
_main	ENDP
_TEXT	ENDS
END



My compiler does a bit better than yours in optimizing the stack cleanup; this code does it only once, but the code you showed does the cleanup after each call, which isn't necessary--it saves a bit of stack space, but adjusts the ESP register when it isn't consequential. Otherwise, the code is completely identical.

The reason that the tertiary operator is useful for your meta-programming tricks is that it conveniently evaluates to an expression, while if/else isn't an expression--it's a sequence point and a statement.
Was This Post Helpful? 0
  • +
  • -

#14 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: What is this operator?

Posted 15 June 2009 - 07:30 AM

lol -- I was just thinking about this! I was thinking "the compiler can actually determine the outcome of simple-if-else constant expressions" Since I have run into that before. So I was thinking that perhaps an inline function would be equivalent.

As for the clean up I left the options to not clean up the constants so that it demonstrated that both expressions were evaluated by the compiler.

But my point is to demonstrate that the ?: is an expression and not just an if-else replacement. Which I am finding harder and harder to demonstrate effectively.
Was This Post Helpful? 0
  • +
  • -

#15 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: What is this operator?

Posted 15 June 2009 - 07:38 AM

BTW -- Mike's example compiled to the exact same assembly language program (all of the code was the same, some of the symbols were different) on my compiler as my example.


So at least in this context the examples are exactly the same... foiled again!
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2