Is this kosher?

K

Keith Thompson

William Hughes said:
Yes, but all you are saying is that a function of the form

do_something_to_object(object)

should not return an object (in C an object is a pointer).
[...]

In C, an object is a "region of data storage in the execution
environment, the contents of which can represent values" (C99 3.14).
A pointer variable, or a variable of any type, is an object; a pointer
value is not. I'm not sure what you meant by "object", but you might
consider choosing a different term.

<OT>BTW, C++ uses a very similar definition of "object", one that's
not related to "object-oriented" programming.</OT>
 
M

Malcolm

Keith Thompson said:
William Hughes said:
Yes, but all you are saying is that a function of the form

do_something_to_object(object)

should not return an object (in C an object is a pointer).
[...]

In C, an object is a "region of data storage in the execution
environment, the contents of which can represent values" (C99 3.14).
A pointer variable, or a variable of any type, is an object; a pointer
value is not. I'm not sure what you meant by "object", but you might
consider choosing a different term.

<OT>BTW, C++ uses a very similar definition of "object", one that's
not related to "object-oriented" programming.</OT>
What is meant is the C idiom

typedef struct
{
char *ascii;
char **somepointers;
int moredata;
} ROPE;

We keep this as an opaque pointer, and only code in rope.c is allowed to
access the data directly.

Now
/* reverses a rope */
void reverserope(ROPE *rope);
is OK
so too is
/* returns reversed rope, input unchanged */
ROPE *reverserope(ROPE *rope)

but

/* reverses the rope, returns pointer to reversed object */
ROPE *reverserope(ROPE *rope)

is asking for trouble.
 
W

William Hughes

Malcolm said:
Keith Thompson said:
William Hughes said:
Yes, but all you are saying is that a function of the form

do_something_to_object(object)

should not return an object (in C an object is a pointer).
[...]

In C, an object is a "region of data storage in the execution
environment, the contents of which can represent values" (C99 3.14).
A pointer variable, or a variable of any type, is an object; a pointer
value is not. I'm not sure what you meant by "object", but you might
consider choosing a different term.

<OT>BTW, C++ uses a very similar definition of "object", one that's
not related to "object-oriented" programming.</OT>
What is meant is the C idiom

typedef struct
{
char *ascii;
char **somepointers;
int moredata;
} ROPE;

We keep this as an opaque pointer, and only code in rope.c is allowed to
access the data directly.

Now
/* reverses a rope */
void reverserope(ROPE *rope);
is OK
so too is
/* returns reversed rope, input unchanged */
ROPE *reverserope(ROPE *rope)

but

/* reverses the rope, returns pointer to reversed object */
ROPE *reverserope(ROPE *rope)

is asking for trouble.

Hardly. It is required if you want to do things like

skip_with(reverserope(rope))

without forcing a copy operation.


[In C you could do something like

void reverserope(ROPE *rope);
void skip_wth(ROPE *rope);


skip_with((reverserope(rope),rope))

(I think), but even if the compiler can keep the comma expression
and the arguments straight, the programmer can't.]

You have to live with the fact that a function that is passed
an ADT might do something with that ADT. (Though it
may make sense to put some restrictions on which functions
are allowed do this). Given this, restricting the return types
of the functions buys you very little.

- William Hughes
 
S

Simon Biber

Malcolm said:
What is meant is the C idiom

typedef struct
{
char *ascii;
char **somepointers;
int moredata;
} ROPE;

We keep this as an opaque pointer, and only code in rope.c is allowed to
access the data directly.

Now
/* reverses a rope */
void reverserope(ROPE *rope);
is OK
so too is
/* returns reversed rope, input unchanged */
ROPE *reverserope(ROPE *rope)

It's not really OK. The parameter ought to be a pointer to const ROPE.
That would make it clear to the function's user that the function does
not modify its argument. The returned value should be a separate ROPE
(either a pointer to a static object or a newly malloced one). The
function's documentation should specify which, and also specify if there
are any error cases that could cause it to return NULL.
but

/* reverses the rope, returns pointer to reversed object */
ROPE *reverserope(ROPE *rope)

is asking for trouble.

It provides some syntactic convenience but can also cause some
confusion. Is it necessary to check the return value of this function?
If the function succeeds, it will return the same pointer value as that
passed in. If the function fails, it may return NULL. I would prefer to
simply return a bool or an int containing a status code.
 
S

Simon Biber

Malcolm said:
char q[1024];

gets(q); /* troll alert *

Your comment is missing a slash. I won't comment on the gets for fear of
being called a troll.
if(q[0] = '*')
{
char *p = q;

myasteriskroutine(p);
}

This is legitimate code, if p has some meaning for an asterisk-started
string.

The code replaces the first character of q with an asterisk. Since the
value of an asterisk character is never zero, it will always call
myasteriskroutine. I think you meant to use the == operator.
It makes the code easier to read.

How does it make the code easier to read? I would find it easier to read
had you simply written:

if(q[0] == '*')
{
myasteriskroutine(q);
}
However a decent compiler will say q, p - same value. Therefore we just
store them in the same location in memory.

Indeed.
 

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,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top