Different types to ?:

  • Thread starter Nils Petter Vaskinn
  • Start date
N

Nils Petter Vaskinn

Why is it that if I have an overloaded function like:

void foo(int i);
void foo(char *c);

I can't do:

void bar() {
foo( condition ? 5 : "NULL");
}


As you might guess I'm building a query and my compiler (g++) complaines
about different operands to ?:

While I can easily replace the ?: with an if I was surprised that the
statement wasn't allowed. So I wondered if this really is specified in the
standard (or a quirk of g++) and there is any good reason for it to be
that way.

Anyone care to enlighten me?


regards
NPV
 
J

John Harrison

Nils Petter Vaskinn said:
Why is it that if I have an overloaded function like:

void foo(int i);
void foo(char *c);

I can't do:

void bar() {
foo( condition ? 5 : "NULL");
}


As you might guess I'm building a query and my compiler (g++) complaines
about different operands to ?:

While I can easily replace the ?: with an if I was surprised that the
statement wasn't allowed. So I wondered if this really is specified in the
standard (or a quirk of g++) and there is any good reason for it to be
that way.

Anyone care to enlighten me?


regards
NPV

Its not allowed. Any expression has a single type, which can be deduced at
compile time by the compiler. Your suggestion would mean that an expressions
type could not be determined until a program runs. Sounds like a nightmare
to me (and not only for compiler writers).

john
 
N

Nils Petter Vaskinn

Its not allowed. Any expression has a single type, which can be deduced at
compile time by the compiler. Your suggestion would mean that an expressions
type could not be determined until a program runs. Sounds like a nightmare
to me (and not only for compiler writers).

And how would that be harder than compiling

class Base;
class Child1;
class Child2;

foo(Base b);
foo(Child1 c);
foo(Child2 c);

bar(Base arg) {
foo(arg);
}

where you don't know the type of arg at compiletime?

Just because it may be hard for compiler writers is no reason that it
shouldn't be used, I expect the compiler writers have solved problems much
harder than that one.

Is there any reason that ?: with different types is impossible and/or a
bad idea, except for compiler writers having to deal with it? Does the
standard state WHY it isn't allowed.


regards
NPV
 
N

Nils Petter Vaskinn

Yes, it is. Your example can be decided at *compile* time.

But not which foo() to call.
Impossible.

Now that is plain unbelievable. If you said incredibly hard I would
believe you. If you said Impossible without rewriting the internals of the
compiler completely, I would believe you. But impossible is very rarely
the case.
I am not going to look up the standard now. In C++ (well, why cannot
people read a decent C++ introductory book such as Accelerated C++
before starting to be critics? - sorry) expressions have a type. A
Type. One Type. And expression cannot have two types => be two things.

I did look ?: up in The C++ Programming Language and it provided very
little explanation. I also looked up the behaviour of ?: in K&R which
provided a little more detail and explained that the operands would have
to be the same type (unless one could be cast automatically to the other).

What I never found was any reason why this limitation exists in C++ (which
is much more dynamic than C), except for the "It's hard" explanation.

I didn't criticise anything that I'm aware of, I was asking "why is it
this way". (So that later I might descide to criticise if the explanation
doesn't make sense to me)

Now you have explained that it violates a principle (an expression has one
and only one type) I accept that. There never really was a problem since I
know how to do without ?: (if) I just wanted to know why the limitation
existed in the first place. (Though that principle might just be there to
make it easier for compiler writers)

regards
NPV
 
N

Nils Petter Vaskinn

Nils Petter Vaskinn wrote:

You did not criticize? "Just because it may be hard for compiler writers
is no reason that it shouldn't be used, I expect the compiler writers
have solved problems much harder than that one." What was that then???

Which was my explanation why I didn't accept the "it's hard" explanation,
and expected there to be another reason. If you parsed that as "There is
something wrong with the C++ language" we have a bigger problem than me
wanting to know the reason behind one decision in the design of C++.

regards
NPV
 
A

Agent Mulder

NPV> If you parsed that as "There is something wrong with
NPV> the C++ language" we have a bigger problem than me
NPV> wanting to know the reason behind one decision in the
NPV> design of C++.

There might be something wrong with the C++ community. See
all those weird a-symmetrical beards around you? That's the
C++ crew.

You can use ?: this way (pragmatic, I cannot answer your question
why ?: is implemented the way it is)

void f(int a){}
void f(char a){}
true?f(1):f('1');

-X
 
R

Ron Natalie

Nils Petter Vaskinn said:
Undefined, possibly a compiler warning. Or possibly really complex rules
for when ?: is allowed with different types. I guess this may be one of
the problems that made them decide against it (if they ever considered
it).

Disagree. The values of x and y are immaterial. The rules say that
the result of both the ?: expressions above is unambiguously char*.
 
N

Nils Petter Vaskinn

Disagree. The values of x and y are immaterial. The rules say that
the result of both the ?: expressions above is unambiguously char*.

Well yes, when I think about it, but I guess that was only meant to
illustrate the problem, replace the zeros with something else like 1.23
and you get the problem we're talking about.

NPV
 
R

Ron Natalie

Nils Petter Vaskinn said:
Well yes, when I think about it, but I guess that was only meant to
illustrate the problem, replace the zeros with something else like 1.23
and you get the problem we're talking about.
In that case the program is ill-formed. There must be an unambiguous
type to that expression that does not depend on what the test argument
is.
 
S

stelios xanthakis

Nils Petter Vaskinn said:
Why is it that if I have an overloaded function like:

void foo(int i);
void foo(char *c);

I can't do:

void bar() {
foo( condition ? 5 : "NULL");
}


As you might guess I'm building a query and my compiler (g++) complaines
about different operands to ?:

While I can easily replace the ?: with an if I was surprised that the
statement wasn't allowed. So I wondered if this really is specified in the
standard (or a quirk of g++) and there is any good reason for it to be
that way.

Yes. ?: is tricky.

In E0 ? E1 : E2, the expressions E1 and E2 must be converted to a common type.
The whole thing as an expression is supposed to have ONE type.
Imagine this code:

(condition ? A : B)->x;

The part "(condition ? A : B)" must have a single type known at compile time.

Generally, I guess this has to do with the parser: You expect the
unary expression (in the parentheses) to have a type. Otherwise
you could imagine that in nested such constructs a subexpression could
possibly have 16, 256 or even 65536 possible types!
 
N

Nils Petter Vaskinn

In that case the program is ill-formed. There must be an unambiguous
type to that expression that does not depend on what the test argument
is.

Yes, and if you had followed the discussion the original question was WHY
this was the case, and it couldn't be determined dynamically at runtime.
The most convincing argument (IMHO) beeing that it would be too expensive
(runtime performance wise) compared to the benefit (me using one less if
statement).

regards
NPV
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top