function call in conditional operator?

K

kal

Case said:
BTW what other seemingly strange standard C construction
do you know? I mentioned 5["fsdssdfssf"] which looks
very strange to most people even very experienced C
programmers. It would be fun to discuss this kind of
constructs.

Why is the resultant deferenced type (char) and not some other
scalar type?
 
R

Richard Bos

Case said:
BTW what other seemingly strange standard C construction
do you know? I mentioned 5["fsdssdfssf"] which looks
very strange to most people even very experienced C
programmers. It would be fun to discuss this kind of
constructs.

Why is the resultant deferenced type (char) and not some other
scalar type?

Because that's how the Standard defines it. Besides, what other type
would you have it be?

Richard
 
R

Richard Bos

Malcolm said:
Case said:
BTW what other seemingly strange standard C construction
do you know? I mentioned 5["fsdssdfssf"] which looks
very strange to most people even very experienced C
programmers. It would be fun to discuss this kind of
constructs.

C allows a lot of this sort of thing in order to make the compiler's grammar
easier to specify.

Oddly enough, in this case the grammar wouldn't have been much easier if
this were disallowed. "The first expression shall have type 'pointer to
object type', the second expression shall have integral type" wouldn't
have been any simpler than the actual C89 sentence "One of the
expressions shall have type 'pointer to object type', the other
expression shall have integral type". It probably even would've made
compilers (very) slightly smaller.

Richard
 
I

Irrwahn Grausewitz

Joona I Palaste said:
Mitchell said:
Yes, of course! Never thought of stretching the meaning
of a function 'pointer' this far. Things like 5["Hello world"]
(as you know I'm sure) are entertaining too.
I'm a bit stumped here, how does 5("Hello world"); works?
#define 5(_a) printf("%s",_a) ?

5("Hello world"); doesn't work. It's 5["Hello world"] with square
brackets instead of normal ones. It works because [] is actually a
commutative operator - a is the exact same thing as b[a].


Or, to put it another way, the array subscript operator [] is
essentially "syntactic sugar" and a is semantically equivalent
to (*((a)+(b))), which in turn obviously equals (*((b)+(a))),
because of the commutative nature of the binary + operator.

Regards
 
D

Dan Pop

In said:
Case said:
BTW what other seemingly strange standard C construction
do you know? I mentioned 5["fsdssdfssf"] which looks
very strange to most people even very experienced C
programmers. It would be fun to discuss this kind of
constructs.

Why is the resultant deferenced type (char) and not some other
scalar type?

Engage your brain and tell us what type can be expected from
"fsdssdfssf"[5]. Then explain why would you expect another type from
5["fsdssdfssf"]. I assume you have already read the FAQ...

Dan
 
M

Mabden

Case said:
Keith said:
Case said:
Kevin Bracey wrote:

Yes. And even more entertainingly, you can do this:
x = (a > b ? fun1 : fun2) (c, d, e);


BTW what other seemingly strange standard C construction
do you know? I mentioned 5["fsdssdfssf"] which looks
very strange to most people even very experienced C
programmers. It would be fun to discuss this kind of
constructs.


Google "Duff's Device".

This one is really amazing! Thanks.

send(to, from, count)
register short *to, *from;
register count;
{
register n=(count+7)/8;
switch(count%8){
case 0: do{ *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
}while(--n>0);
}
}



So basically at some count != 8 you end up with:

} while (--n>0);

And this is legal? What about the } with no opening {?
 
K

kal

Then explain why would you expect another type from 5["fsdssdfssf"].

Now it seems clear. I got muddled about 'left' and 'right' operands.
But when you phrase it as "one is a pointer type and the other an
integral type" it clarifies itself.
I assume you have already read the FAQ...

Haven't read it. In fact I wasn't planning to read it till I
came across references to it in a few posts. Those references
were direct and pertinent (references to 16.5 etc.) I think one
was yours (Dan Pop) and the names of the posters of the other
two I can't recall at the moment (one was about "if (2 == x) ..."
form.)

When I went and looked at it I was surprised to see how well
done it is. So, I have read SOME of it and am still reading
parts of it almost everday. Thanks for directing me there.
 
D

Dan Pop

In said:
send(to, from, count)
register short *to, *from;
register count;
{
register n=(count+7)/8;
switch(count%8){
case 0: do{ *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
}while(--n>0);
}
}

So basically at some count != 8 you end up with:

} while (--n>0);

And this is legal? What about the } with no opening {?

Good question. A strict reading of the standard makes it undefined
behaviour. This is not the intent of the authors, but they couldn't be
bothered to get it right.

Dan
 
K

Kevin Bracey

Good question. A strict reading of the standard makes it undefined
behaviour. This is not the intent of the authors, but they couldn't be
bothered to get it right.

Of course, they're still some way ahead of those who couldn't be bothered to
get involved in authoring it.
 
P

Peter Shaggy Haywood

Groovy hepcat Mitchell was jivin' on Wed, 19 May 2004 11:07:08 +0800
in comp.lang.c.
Re: function call in conditional operator?'s a cool scene! Dig it!
Yes, of course! Never thought of stretching the meaning
of a function 'pointer' this far. Things like 5["Hello world"]
(as you know I'm sure) are entertaining too.

I'm a bit stumped here, how does 5("Hello world"); works?

It doesn't. But 5["Hello world"] does. It works like this:

1) "Hello world" is somewhat equivalent to

char somestring[] = {'H', 'e', 'l', 'l', 'o', ' ',
'w', 'o', 'r', 'l', 'd'};

2) In an expression, "Hello world"[5] is therefore somewhat equivalent
to somestring[5].

3) This is equivalent to *(somestring + 5).

4) That is equivalent to *(5 + somestring).

6) And that is equivalent to 5[somestring].

7) So, that is somewhat equivalent to 5["Hello world"].

Understand?

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
R

Ralmin

glen herrmannsfeldt said:
Well, in Java you can do it with Object reference variables.

x=(a>b?string1:string2).equals("hi");

The concept works on C too, except that it's messy to include a reference to
the object as part of the method's arguments.

#include <string.h>

struct string {
int (*equals)(struct string *, const char *);
char *data;
};

int str_equals(struct string *this, const char *other)
{
return !strcmp(this->data, other);
}

int main(void)
{
struct string string1 = {str_equals, "Hello"};
struct string string2 = {str_equals, "World"};
int x, a = 1, b = 2;
x = ((a > b) ? string1 : string2).equals(((a > b) ? &string1 : &string2),
"hi");
return 0;
}
 

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,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top