Weird bit of code-- legal???

P

pete

[/QUOTE]

C code, is on topic.
The question of whether or not expressions of function type
can be used as the second and third expressions
of the conditional operator,
is on topic.


"Correct code" is on topic.

You remember nothing.

Kenny can't remember anything.
If he could, then he would remember that he's always wrong
when he tries to be topical on this newgroup,
and that that's why he decided to become a troll.
 
K

Kenneth Brody

Old said:
The functions don't have to have prototypes; this is accepted
by my compiler:

int foo();
int bar(int x) { return 0; }

int main()
{
return (0 ? foo : bar)(1);
}

int foo() { }

AFAIK, the above invokes UB, because you're calling a function
without a prototype in scope (foo) with the wrong parameters.

However, given that your compiler _probably_ uses the "caller
cleans up the stack" convention, the odds are that it will, in
fact, "work" on many platforms. (By "work", I mean "give the
expected results".)
In fact, this is also accepted and runs correctly, although I'm not
sure how well-defined it is:

#include <stdio.h>

int foo();

int bar(char *x) {
printf("bar: %p\n", x);
return 0;
}

int main()
{
return (getchar() == 'x' ? foo : bar)(0);
}

int foo(int x) {
printf("foo: %d\n", x);
return 0;
}

I will probably fail miserably on platforms with:

all-bits-zero being a trap representation for a pointer
or
sizeof(char *) != sizeof(int)

And, I assume that if you place the actual definition of foo()
above main, rather than the "function that takes an unknown
set of arguments" type, that the compiler complains about a
mismatch between foo() and bar()?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
S

Skarmander

jaysome said:
This is equivalent to:

if ( Mode == 2 )
{
Result = TwoWayFunc(Param1, Param2, Param3);
}
else
{
Result = FourWayFunc(Param1, Param2, Param3);
}
Hey, that looks like a good job for a conditional expression!

result = Mode == 2 ? TwoWayFunc(Param1, Param2, Param3) :
FourWayFunc(Param1, Param2, Param3);

I presume nobody's scratching their head here. Whether you do that with an
if-statement or a conditional depends on how comfortable you are with
stuffing things on one line. We're assuming, of course, that "Param1" and
friends really are called that, and are not placeholders for two mile long
expressions with side effects.

But hold on, is "2" a magic value here? Wouldn't a variable called "Mode"
hold some sort of state parameter? Well then

switch (Mode) {
case 2: TwoWayFunc(Param1, Param2, Param3); break;
default: FourWayFunc(Param1, Param2, Param3); break;
}

is a nice way of emphasizing this. Now, "2" shouldn't be a magic value, so
toss in a #define or make Mode of enum type, but that's changing around
semantics.
The original "really good programmer" bit off more than he could chew,
from the standpont if understandability and maintainability, as the
equivalent code should not cause your head to scratch at all.

In the world of safety critical software, which I deal with on a
regular basis, we have no tolerance for such code as that written by
the "really good programmer". He or she either changes it or he or she
is out the door. No if, ands, or but about it.
Must be nice to be able to cull the herd like that. I have to take the
occasional clue-by-four to my colleagues when I get called in to fix a
problem that's ultimately the result of bozotic code... admittedly not in C,
I don't think they're ready for that. ("What's wrong with an empty exception
handler? I really want to ignore errors here!")

S.
 
G

gbostock

jaysome said:
This is equivalent to:

if ( Mode == 2 )
{
Result = TwoWayFunc(Param1, Param2, Param3);
}
else
{
Result = FourWayFunc(Param1, Param2, Param3);
}

The original "really good programmer" bit off more than he could chew,
from the standpont if understandability and maintainability, as the
equivalent code should not cause your head to scratch at all.

The original code shouldn't have caused anyone to do any head
scratching either, unlesss they are a junior level programmer who needs
to get up to speed in a hurry.
In the world of safety critical software, which I deal with on a
regular basis, we have no tolerance for such code as that written by
the "really good programmer". He or she either changes it or he or she
is out the door. No if, ands, or but about it.

So the world in which you deal is loaded with junior programmers who
have no business being anywhere near safety critical software. Dumbing
down the coders is not the solution. You need better programmers.
 
J

jmcgill

jaysome said:
This is equivalent to:

if ( Mode == 2 )
{
Result = TwoWayFunc(Param1, Param2, Param3);
}
else
{
Result = FourWayFunc(Param1, Param2, Param3);
}

It isn't exactly equivalent. In your version of the conditional
expression, you can put functions prototyped with any parameters, not
only functions which take three parameters of the types of Param1,
Param2, Param3.

The original example in the compact syntax actually puts a compile-time
constraint on this, and your "equivalent" syntax does not.
 
J

jmcgill

jaysome said:
In the world of safety critical software, which I deal with on a
regular basis, we have no tolerance for such code as that written by
the "really good programmer". He or she either changes it or he or she
is out the door. No if, ands, or but about it.

If I told you that the compact syntax made it possible for us to
continue using a code generator, or if I told you it helped
significantly in debugging, or something of that nature, you'd still
show me the door? After I'd been working for you for 12 years?

Please think before you go off about how low your standards are for
firing someone. Nobody who had a choice, would want to work for you if
you really had a policy like that.

In another post, I gave you a reason why your "equivalent" code isn't
exactly. Of course, the difference between code you got from me, and
the code in the example, is that my code would have comments.

Forgive me, I haven't had my coffee today, and as it turns out, I'm
rewriting someone else's bad code this morning.



James
 
K

Keith Thompson

pete said:
Kenny can't remember anything.
If he could, then he would remember that he's always wrong
when he tries to be topical on this newgroup,
and that that's why he decided to become a troll.

And that's why *he should be ignored*. Please stop feeding the troll.
And please ignore whatever idiocy he posts in response to this.

I recommend killfiling him. You won't miss anything useful or
interesting.
 
O

Old Wolf

Kenneth said:
AFAIK, the above invokes UB, because you're calling a function
without a prototype in scope (foo) with the wrong parameters.

Well, foo is never called in the above example.
I will probably fail miserably on platforms with:

all-bits-zero being a trap representation for a pointer
or
sizeof(char *) != sizeof(int)

Why does the compiler decide that 0 is a pointer and
not an integer, in the case of calling foo?
And, I assume that if you place the actual definition of foo()
above main, rather than the "function that takes an unknown
set of arguments" type, that the compiler complains about a
mismatch between foo() and bar()?

Yes, because the definition of foo serves as a prototype.
 
J

jaysome

It isn't exactly equivalent. In your version of the conditional
expression, you can put functions prototyped with any parameters, not
only functions which take three parameters of the types of Param1,
Param2, Param3.

The original example in the compact syntax actually puts a compile-time
constraint on this, and your "equivalent" syntax does not.

If function prototypes are required, I don't see how your argument
holds. This is valid C:

int TwoWayFunc(int,int,int);
int FourWayFunc(int,int,int);
int TwoWayFunc_v(int, ...);
int FourWayFunc_v(int, ...);
int Mode;
int Result;
int main(void)
{
int Param1 = 0;
int Param2 = 0;
int Param3 = 0;
Result = (Mode == 2 ? TwoWayFunc : FourWayFunc ) (Param1,
Param2, Param3 );
Result = (Mode == 2 ? TwoWayFunc_v : FourWayFunc_v) (Param1,
Param2, Param3 );
return 0;
}

Best regards
 
J

jaysome

If I told you that the compact syntax made it possible for us to
continue using a code generator, or if I told you it helped
significantly in debugging, or something of that nature, you'd still
show me the door? After I'd been working for you for 12 years?

When I referred to that "really good programmer", I assumed it was
clear that I was talking about a real person, not some robotic code
generator. Nevertheless, even a code generator has to be programmed by
some real person. And the nature of the code that said code generator
generates says a lot about the person programming the code generator.

In this case, I cannot think of any good reason why such a code
generator would generate code like this, let alone how such code could
"significantly" help in debugging. In the world of safety critical
software, tools like code generators may need to be verified as if a
real person wrote the code.
Please think before you go off about how low your standards are for
firing someone. Nobody who had a choice, would want to work for you if
you really had a policy like that.

Of course.
In another post, I gave you a reason why your "equivalent" code isn't
exactly. Of course, the difference between code you got from me, and
the code in the example, is that my code would have comments.

I'm skeptical that you did. But comments are, of course, good.
Forgive me, I haven't had my coffee today, and as it turns out, I'm
rewriting someone else's bad code this morning.

Forgive me too. I may not have had my coffee today either :^)

Best regards
 

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

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top