[net.lang.c] Pointer Trouble Right Here in Unix City

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.