returning (char **) values

J

John Galt

I am writing a rudimentary shell. The (idealized) code is like this:

/* read_cmd returns argv */
char **read_cmd();

shell()
{
char **cmd;

while {
cmd = read_cmd();
if (cmd == (char **)0) /* user just hit '\n' */
continue;
else if (cmd == (char **)-1) /* EOF */
break;
else {
... processing
}
}
}

My questions are:
1. Is it OK to return (char **)1 and (char **)-1 in a function?
OK as in, is it legal, is it acceptable, is it portable. Are there
better ways to do this?
2. Can a pointer have a value of -1 in C? What is the official or
definitive word(s) on this?

I have found that it works OK on Solaris, Linux & zSeries.

TIA for any advice,
John Galt.
 
B

Ben Pfaff

1. Is it OK to return (char **)1 and (char **)-1 in a function?
OK as in, is it legal, is it acceptable, is it portable. Are there
better ways to do this?

It is not portable. A better way is to declare an object of type
char * and take its address, e.g.
char *myEOF;
...
return &myEOF;
...
if (cmd == &myEOF)
Portable, clean, easy-to-read.
2. Can a pointer have a value of -1 in C? What is the official or
definitive word(s) on this?

It depends on the implementation.
 
J

Joona I Palaste

John Galt <[email protected]> scribbled the following
I am writing a rudimentary shell. The (idealized) code is like this:
/* read_cmd returns argv */
char **read_cmd();
shell()
{
char **cmd;
while {
cmd = read_cmd();
if (cmd == (char **)0) /* user just hit '\n' */
continue;
else if (cmd == (char **)-1) /* EOF */
break;
else {
... processing
}
}
}
My questions are:
1. Is it OK to return (char **)1 and (char **)-1 in a function?
OK as in, is it legal, is it acceptable, is it portable. Are there
better ways to do this?

No, it's not legal. 1 and/or -1 might be "trap values" for the type
char **. Merely forming these values causes undefined behaviour.
Couldn't you pass the address of a variable in shell() to read_cmd(),
and read_cmd() could then set this to a status code?
2. Can a pointer have a value of -1 in C? What is the official or
definitive word(s) on this?

No, it can't, not in standard C.
I have found that it works OK on Solaris, Linux & zSeries.

Irrelevant. It might not work on every machine there is.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"How can we possibly use sex to get what we want? Sex IS what we want."
- Dr. Frasier Crane
 
B

Barry Margolin

John Galt <[email protected]> scribbled the following


No, it can't, not in standard C.


Irrelevant. It might not work on every machine there is.

Note, however, that any C implementation used on Unix must support it
because a few functions in the Unix API use -1 cast to various pointer
types as a way of indicating that an error occurred. Since the OP
cross-post to comp.unix.programmer, this may be enough for him.
 
R

Ralf Fassel

* (e-mail address removed) (John Galt)
| cmd = read_cmd();
--<snip-snip>--
| else if (cmd == (char **)-1) /* EOF */
--<snip-snip>--
| Are there better ways to do this?

Make `read_cmd' set a flag on EOF instead of overloading the return
value:

char **read_cmd(int *);

int eof = 0;
while (1) {
cmd = read_cmd(&eof);
if (eof) break;
...
}

R'
 
M

Micah Cowan

I am writing a rudimentary shell. The (idealized) code is like this:

/* read_cmd returns argv */
char **read_cmd();

shell()

Implicit return type is disallowed in C99, and empty parentheses
in a function declaration is deprecated. Use:

int shell(void)
{
char **cmd;

while {
cmd = read_cmd();
if (cmd == (char **)0) /* user just hit '\n' */
continue;
else if (cmd == (char **)-1) /* EOF */
break;
else {
... processing
}
}
}

My questions are:
1. Is it OK to return (char **)1 and (char **)-1 in a function?
OK as in, is it legal, is it acceptable, is it portable. Are there
better ways to do this?

No. It is legal, but the result is implementation-defined, and if
1 and -1 aren't representable as char**s, then the result will be
undefined behavior. You don't want this.
2. Can a pointer have a value of -1 in C? What is the official or
definitive word(s) on this?

It is *possible* that a pointer can be converted from -1 and
back, but not guaranteed. Don't do it.

Really, you should use different "return values" for values which
have different meanings. Do something like:

int shell(char **cmd);

And set *cmd to point to your string (don't forget to manage
deallocation), and return an error code in shell().

-Micah
 
P

Pascal Bourguignon

I am writing a rudimentary shell. The (idealized) code is like this:

/* read_cmd returns argv */
char **read_cmd();

shell()
{
char **cmd;

while {
cmd = read_cmd();
if (cmd == (char **)0) /* user just hit '\n' */
continue;
else if (cmd == (char **)-1) /* EOF */
break;
else {
... processing
}
}
}

Why don't you write just what you mean:

typdef struct {
enum { eof, empty_line, command } status;
char* line;
} read_cmd_result_t;

read_cmd_result_t* read_cmd(void);

int shell(void)
{
;

while {
read_cmd_result_t* result = read_cmd();
switch(result->status){
case empty_line: /* user just hit '\n' */
continue;
case eof: /* EOF */
break;
case command:
// ... processing result->line
break;
default:
// error
break;
}
release_read_cmd_result(result);
}
}
 

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,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top