Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > ternary operator error

Reply
Thread Tools

ternary operator error

 
 
Jacob
Guest
Posts: n/a
 
      06-30-2003
The following produce a compilation error:

int a = 0;
String s = "b" + (a == 0 ? "c" : a);

I can sort of understand why, but on the
other hand it is pretty apparent what I
try to acheive.

Why is the compiler so strict?

Thanks!

 
Reply With Quote
 
 
 
 
Jon Skeet
Guest
Posts: n/a
 
      06-30-2003
Jacob <(E-Mail Removed)> wrote:
> The following produce a compilation error:
>
> int a = 0;
> String s = "b" + (a == 0 ? "c" : a);
>
> I can sort of understand why, but on the
> other hand it is pretty apparent what I
> try to acheive.
>
> Why is the compiler so strict?


You're suggesting that the type of an expression should be different
depending on runtime evaluation - that sounds like a pretty strange bit
of specification. It makes everything simpler if the type of an
expression will always be the same, and it *very* rarely impacts on
real life code, IME.

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
 
Reply With Quote
 
 
 
 
Gordon Beaton
Guest
Posts: n/a
 
      06-30-2003
On Mon, 30 Jun 2003 10:57:32 +0200, Jacob wrote:
> The following produce a compilation error:
>
> int a = 0;
> String s = "b" + (a == 0 ? "c" : a);
>
> I can sort of understand why, but on the
> other hand it is pretty apparent what I
> try to acheive.
>
> Why is the compiler so strict?


Every expression must have a type that is unambiguous and can be
evaluated at compile time. That means that both branches of the
conditional operator must evaluate to the same type, so that the
expression itself can be assigned a type that can be used when the
surrounding expression is evaluated.

The compiler sees something like this:

String <-- String + E

where E is

(boolean ? String : integer)

So what is the type of E?

An integer and a String are not the same type, and what you
*subsequently* do with the resulting value (i.e. in the enclosing
expression) does not change that fact. A type for E cannot be assigned
at compile time.

Consider that the compiler might need to emit different code depending
on the whether the conditional expression evaluates to an integer or a
String.

You can help it though:

String s = "b" + (a == 0 ? "c" : Integer.toString(a));

/gordon

--
[ do not send me private copies of your followups ]
g o r d o n . b e a t o n @ e r i c s s o n . c o m
 
Reply With Quote
 
Tomy
Guest
Posts: n/a
 
      06-30-2003
Jacob <(E-Mail Removed)> wrote:
> The following produce a compilation error:
>
> int a = 0;
> String s = "b" + (a == 0 ? "c" : a);
>
> I can sort of understand why, but on the
> other hand it is pretty apparent what I
> try to acheive.
>
> Why is the compiler so strict?
>
> Thanks!



Because java specification is strict in that way.
Type of the data must be known which is not
the case here since the result of your tenary
(in the way you want to use it) cannot be known
at compile time since it depends on value of a.

It is the same reason which prohibits you from
writing a method which can return either int
or String.

This might be solved in 1.5 with autoboxing-unboxing
feature. I'm just guessing here....

---
Tomy.
-----------------------
http://www.velocityreviews.com/forums/(E-Mail Removed)


 
Reply With Quote
 
Tomy
Guest
Posts: n/a
 
      06-30-2003
Marco Schmidt <(E-Mail Removed)> wrote:
> Tomy:
>
> [...]
>
>> This might be solved in 1.5 with autoboxing-unboxing
>> feature. I'm just guessing here....

>
> AFAIK that feature will only lead to easier handling of primitive
> types and their respective wrapper classes, e.g. int and Integer.
>
> Transparent conversion between int and String is a different thing.



Not really I think in this example....
"b" + (a == 0 ? "c" : a)
"c" is String
a is int, gets implicitely boxed in Integer....
Tenary expression has type of Object....
"b" + Object is legal so everything OK....

I'm not sure things will work this way, but they might
since ternary expression now has "a type that is unambiguous and can be
evaluated at compile time" Object type.... (Thank you Gordon on this phrase,
my english
is not so good ).....

Tomy.
-------------------------------------
(E-Mail Removed)






 
Reply With Quote
 
Joona I Palaste
Guest
Posts: n/a
 
      06-30-2003
Tomy <(E-Mail Removed)> scribbled the following:
> begin 666 smile.gif
> M1TE&.#EA#P`/`)$!`````+^_O___`````"'Y! $```$`+ `````/``\```(N
> MC V9QY$"X6(@6GGJO0!)+3RA$XDA:&Y6JGXMIX$K%G,8^2EE]G:4?&ID%+Y#
> #`0`[
> `
> end


> begin 666 frown.gif
> M1TE&.#EA#P`/`)$``````+V]O8RM_[V]O2'Y! $```,`+ `````/``\```(O
> MG V9QY,"X6) QBK P?A*E$5BI76/9*:7*K:K"Y^H,CK6^-GPM>U9(T,U-@H-
> $HP``.P``
> `
> end


Could you please stop with this MIME stuff, thanks?

--
/-- Joona Palaste ((E-Mail Removed)) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"Hasta la Vista, Abie!"
- Bart Simpson
 
Reply With Quote
 
pete kirkham
Guest
Posts: n/a
 
      06-30-2003
Jon A. Cruz wrote:

> Gordon Beaton wrote:
>
>>
>> You can help it though:
>>
>> String s = "b" + (a == 0 ? "c" : Integer.toString(a));

>
>
> A better way is
> String s = "b" + (a == 0 ? "c" : String.valueOf(a));
>


the source code for String.valueOf is:

public static String valueOf(int i) {
return Integer.toString(i, 10);
}

so you only end up making an extra method call, so for code where you've
decided that a is an integer the integer version is more efficient.

In this particular situation the compiler doesn't have to know the type
as the + operator is expanded to calls to StringBuffer, so:

String s = "s" + ( test ? X : Y);

gets expanded to something like:
StringBuffer _temp = new StringBuffer();

_temp.append("s");

String _temp2;

if (test) goto :1
_temp2 = Y;
goto :2
:1
_temp2 = X;
:2

_temp.append(_temp2);

String s = _temp.toString();

(_temp<x> being either a virtual local variable or a stack value)

but it /could/ be expanded to:
StringBuffer _temp = new StringBuffer();

_temp.append("s");

if (test) goto :1
_temp.append(Y);
goto :2
:1
_temp.append(X);
:2

String s = _temp.toString();

with the types of X and Y only being used to determine which append call
to make, which loosens the constraint that X and Y be the same type.

this wouldn't break anything, and the + operator for strings is
different from other operators anyway.

(though since StringBuffer.append(int) calls String.valueOf(int) which
calls Integer.toString(int, int) it saves one indirection to use
StringBuffer.append(Integer.toString(int)) rather than
StringBuffer.append(int))


Pete

 
Reply With Quote
 
Dale King
Guest
Posts: n/a
 
      06-30-2003
"Jon A. Cruz" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Gordon Beaton wrote:
> >
> > You can help it though:
> >
> > String s = "b" + (a == 0 ? "c" : Integer.toString(a));

>
> A better way is
> String s = "b" + (a == 0 ? "c" : String.valueOf(a));



The best way is:

String s;

if( a == 0 )
{
s = "bc";
}
else
{
s = "b" + a;
}
--
Dale King


 
Reply With Quote
 
Marshall Spight
Guest
Posts: n/a
 
      07-01-2003
"Gordon Beaton" <(E-Mail Removed)> wrote in message news:bdovnq$b7p$(E-Mail Removed)...
>
> The compiler sees something like this:
>
> String <-- String + E
>
> where E is
>
> (boolean ? String : integer)
>
> So what is the type of E?


In a different language, the answer might be "String or int" which
actually doesn't seem like all that unreasonable of an answer.


Marshall



 
Reply With Quote
 
Jon A. Cruz
Guest
Posts: n/a
 
      07-01-2003
pete kirkham wrote:
> the source code for String.valueOf is:


No. Not "the" source. "A source"

Other JVM's (including many of IBM's, which are often top performers)
use the fact that the String class can access the internals of the
String class (while the Integer class can not) to optimize if needed.

Remember, the language spec only said it behaves "as if"
Integer.toString() is called, not that it must call it.

>
> so you only end up making an extra method call,


Myabe, or maybe not. A lot depends on the specific VM's implementation.


> so for code where you've
> decided that a is an integer the integer version is more efficient.
>


Ahh.. But also...

If you happen to change the declaration of the variable ('a' in this
case) to some other type (long for example), then Integer.toString() is
broken. However, String.valueOf() will work for boolean, for char, for
char[], for double, for float, for int, for long and for Object.

That also makes the code more OO friendly.




> (though since StringBuffer.append(int) calls String.valueOf(int) which
> calls Integer.toString(int, int) it saves one indirection to use


Or String.valueOf() uses an optimized version that deals with the
internals of the String class directly and gets much better performance.
Again, that detail all depends on the VM being used.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Function call selection using ternary operator marco_segurini C++ 4 09-21-2004 01:37 PM
Need for the ternary operator glongword C Programming 6 05-17-2004 01:33 PM
ternary operator and ostreams Roger Leigh C++ 6 01-19-2004 07:02 PM
Union, ternary operator, Macro, printf don't cooperate for me. Help? Paul E Johnson C Programming 2 10-17-2003 06:41 AM
union, ternary operator, and C. What a mess! Paul E Johnson C Programming 3 10-17-2003 03:44 AM



Advertisments