jeff@gatech.CSNET (Jeff Lee) (05/28/85)
I was in the process of writing a section of code that parsed arguments (how many times have you re-invented the wheel) and came across a problem that I think is bug in the C compiler, but before I become so bold to call it that, I want to get other peoples opinions. The problem is to allow either "-parg" or "-p arg". After fooling with it a few minutes, I came up with this (just the relevent section is enclosed) if (**argv != '-') usage(); switch (*(*argv + 1)) { case 'd': *(*argv + 2) ? *argv += 2 : argv++; /* other processing goes here */ break; case 'b': *(*argv + 2) ? *argv += 2 : argv++; /* other processing goes here */ . . . The problem is that I get the error messages warning: illegal pointer combination illegal types in : when I compile it. I am turning it into if/else combinations, but it sort of ruins the nice looking single line phrase that doesn't get in your way. What is wrong with this ?? It happens under BRL's Berkeley 4.2 and under their system V emulation. Tell me, is it me, or is it Memorex ?? -- Jeff Lee CSNet: Jeff @ GATech ARPA: Jeff%GATech.CSNet @ CSNet-Relay.ARPA uucp: ...!{akgua,allegra,hplabs,ihnp4,linus,seismo,ulysses}!gatech!jeff
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (05/28/85)
> *(*argv + 2) ? *argv += 2 : argv++;
cond ? expr1 : expr2
If expr1 and expr2 are both pointers, they must have the same type.
(Section C.3.15 of ANSI X3J11/85-008)
You could write
*(*argv + 2) ? (*argv += 2) : *(argv++);
but this is hardly the most readable code in any case.
P.S. Consider using the public-domain getopt() that I posted
a while back. (You can easily disable the checks that preclude
-xargument style options in favor of -x argument. I think those
restrictions in the spec are pretty silly anyway.)
chris@umcp-cs.UUCP (Chris Torek) (05/29/85)
?: expressions should have compatible types on both sides of the : part. For example, g(x ? 1.0 : 0) is legal, with the result of the ?: expression being of type double. Mixing a pointer to a character and a pointer to a pointer to a character ``ain't strickly kosher''. The relevant quote from the ANSI draft is: C.3.15 Conditional operator Syntax conditional-expression: logical-OR-expression logical-OR-expression ? logical-OR-expression : conditional-expression Constraints: The first operand must have scalar type. The second and third operands may each have arithmetic type, or may each have void type, or may be structure objects, union objects, or pointers that have the same type. In addition, one may be a pointer and the other an integral constant expression with the value 0. [I left out the semantics description; ``constraints'' covers the original problem. The compiler is correct to complain.] -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
ron@brl-tgr.ARPA (Ron Natalie <ron>) (05/29/85)
> case 'b': > *(*argv + 2) ? *argv += 2 : argv++; > It's upset because the "true" expression and the "false" expression are of different. Turn to page 191 in K&R and read along with me: "If both are pointers of the same type, the result has the common type, otherwise, one must be a pointer and the other the constant 0" A disgusting fix is to make the false expression "*argv++" I don't know why people have an aversion to readable code. First what is wrong with an IF/ELSE combination here? It's what you are doing. You are not selecting one of two expressions, but choosing to do one evaluation or the other. It's up to you, but it seems muddle- some to me. My bigger complaint is *(*argv + 2) Give me a brake they put the brackets in C so you wouldn't have to do every- thing with *. How about argv[0][2] ???
jeff@gatech.CSNET (Jeff Lee) (05/31/85)
Yes, indeed. I thank everyone who has sent me mail. After the first individual sent the answer it all became perfectly clear what the problem was. I also realize that there are public domain getopt's (I have one in my 'src' directory) but since it doesn't exist everywhere I haven't used it. I'll probably include it in the future if for no other reason the number of mail messages that I have received that said, "Hey! Why don't you use the stupid public domain getopt that exists?" As my dad might say, "Ain't the net a corker?". -- Jeff Lee CSNet: Jeff @ GATech ARPA: Jeff%GATech.CSNet @ CSNet-Relay.ARPA uucp: ...!{akgua,allegra,hplabs,ihnp4,linus,seismo,ulysses}!gatech!jeff
sml@luke.UUCP (Steven List) (06/01/85)
> > *(*argv + 2) ? *argv += 2 : argv++; > > cond ? expr1 : expr2 > > P.S. Consider using the public-domain getopt() that I posted > a while back. (You can easily disable the checks that preclude > -xargument style options in favor of -x argument. I think those > restrictions in the spec are pretty silly anyway.) Could you send this or tell me where to get it? I am considering posting some software to the net, and generally use the standard getopt on my system. This would allow me to avoid changing all that code. Thanks.