Programming Puzzle

J

Julie

Irrwahn said:
Then, pray tell, how is the term "variable" defined, WRT to the C
language? Those who were using it were actually talking about named
objects, *technically*. However, except for C++, the term variable
isn't officially defined to mean "named object".


It's indeed highly unrealistic to expect everyone to avoid those
terms. However, a quick look in the archives shows that the use of
correct, well-defined terms, instead of sloppy jargon, serves well to
reduce the risk of confusion. What's wrong with object, external
linkage, file scope, etc.pp., after all?

I'm all for using correct terms. What would you call 'a' here:

int main()
{
int a = 1;
return 0;
}
 
I

Irrwahn Grausewitz

I'm all for using correct terms. What would you call 'a' here:

int main()
{
int a = 1;
return 0;
}

Technically correct:
'a' is an identifier designating an object of type int.

Jargon (and in this case I think there's no place for confusion):
'a' is a variable of type int.

That was easy ;-). Now for the next round, you first:
What would you call p and *p, respectively?

int main(void)
{
int a = 1;
int *p = &a;
*p = 2;
return 0;
}

Regards
 
I

Ioannis Vranos

Irrwahn said:
Technically correct:
'a' is an identifier designating an object of type int.

Jargon (and in this case I think there's no place for confusion):
'a' is a variable of type int.

That was easy ;-). Now for the next round, you first:
What would you call p and *p, respectively?

int main(void)
{
int a = 1;
int *p = &a;
*p = 2;
return 0;
}


To help all people involved in this really boring discussion, here are
some definitions of the C++98 standard:


"A variable is introduced by the declaration of an object. The
variable’s name denotes the object."


"The constructs in a C++ program create, destroy, refer to, access, and
manipulate objects. An object is a region of storage. [Note: A function
is not an object, regardless of whether or not it occupies storage in
the way that objects do. ] An object is created by a definition (3.1),
by a new-expression (5.3.4) or by the implementation (12.2) when needed.
The properties of an object are determined when the object is created.
An object can have a name (clause 3). An object has a storage duration
(3.7) which influences its lifetime (3.8). An object has a type (3.9).
The term object type refers to the type with which the object is created.

Some objects are polymorphic (10.3); the implementation generates
information associated with each such object that makes it possible to
determine that object’s type during program execution. For other
objects, the interpretation of the values found therein is determined by
the type of the expressions (clause 5) used to access them.

Objects can contain other objects, called sub-objects. A sub-object
can be a member sub-object (9.2), a base class sub-object
(clause 10), or an array element. An object that is not a sub-object
of any other object is called a complete object.

For every object x, there is some object called the complete object of
x, determined as follows:

— If x is a complete object, then x is the complete object of x.
— Otherwise, the complete object of x is the complete object of the
(unique) object that contains x.

If a complete object, a data member (9.2), or an array element is of
class type, its type is considered the most derived class, to
distinguish it from the class type of any base class sub-object; an
object of a most derived class type is called a most derived object.

Unless it is a bit-field (9.6), a most derived object shall have a
non-zero size and shall occupy one or more bytes of storage. Base class
sub-objects may have zero size. An object of POD4) type (3.9) shall
occupy contiguous bytes of storage.

[Note: C++ provides a variety of built-in types and several ways of
composing new types from existing types (3.9). ]"






Regards,

Ioannis Vranos
 
J

Julie

Irrwahn said:
Technically correct:
'a' is an identifier designating an object of type int.

Jargon (and in this case I think there's no place for confusion):
'a' is a variable of type int.

That was easy ;-). Now for the next round, you first:
What would you call p and *p, respectively?

int main(void)
{
int a = 1;
int *p = &a;
*p = 2;
return 0;
}

I call 'p' a "pointer [to an int]" and '*p' "p dereferenced" or "a pointer [to
an int] dereferenced".
 
K

Keith Thompson

Irrwahn Grausewitz said:
Then, pray tell, how is the term "variable" defined, WRT to the C
language? Those who were using it were actually talking about named
objects, *technically*. However, except for C++, the term variable
isn't officially defined to mean "named object".

If the C standard itself uses the word "variable" in its common,
somewhat informal sense, then I think we can get away with using it
here in the newsgroup(s).

In addition to a number of examples and footnotes, and ignoring
numerous uses as an adjective, the C99 standard uses the word
"variable" as a noun in normative text in 6.8.5.3p1, 7.6, and F.8.1p1.
(In my opinion, this usage is mildly sloppy, but not sloppy enough to
justify a DR.)

I think we can safely refer to a non-const-qualified object as a
"variable". Whether const-qualified objects are variables is a
question I won't try to answer.
 
M

Mabden

Dan Pop said:
In <[email protected]> "Mabden"

The OP question was generic! He didn't ask "what will happen if *you*
compile and run this program?", did he? You can't provide an equally
generic answer based on the behaviour of your compiler. Such an answer
must be based on the C language definition.

But, Dan, don't we want to teach these newcomers to code properly? Shouldn't
one point out that a function declared as returning an int, that does not
return an int, may have a flaw?
Ask yourself if my short post (one line) helped to show this general error
that may have deep implications if ignored in large, industrial
applications.
I think my post was consise, and germain, without being overbearing; and
therefore unheard.
Furthermore, the specific behaviour of one compiler or another is usually
considered off topic in this newsgroup, you need a *good* reason for
invoking your compiler's behaviour.

"Brevity is the soul of wit". One can teach without a stick in hand, Dan.
Stop behaving like an idiot and I'll lighten up ;-)

Well then, there is no hope... :p
 
I

Irrwahn Grausewitz

Julie said:
Irrwahn said:
Technically correct:
'a' is an identifier designating an object of type int.

Jargon (and in this case I think there's no place for confusion):
'a' is a variable of type int.

That was easy ;-). Now for the next round, you first:
What would you call p and *p, respectively?

int main(void)
{
int a = 1;
int *p = &a;
*p = 2;
return 0;
}

I call 'p' a "pointer [to an int]" and '*p' "p dereferenced" or "a pointer [to
an int] dereferenced".

So you think the term "variable" is applicable to neither p nor *p?

Here's my proposal:

Technically correct:
'p' is an identifier designating an object of type pointer to int.
'*p' is an expression [dereferencing a pointer value] yielding an
lvalue of type int.

Jargon:
'p' is a pointer variable.
'*p' is a dereferenced address.

However, I'd never call '*p' a variable of type int, though others
mileage may (and obviously does) vary.

BTW: the term "pointer" on itself seems to be ambiguous; it's better
to distinguish "pointer object" or "pointer variable", and "pointer
value" or simply "address".

Regards
 
K

Kieran Elby

Julie said:
Wha?! Forth? I don't see anything that even remotely describes how to set up
two variables that share the same memory location (_in_C_or_C++_, please).

When posting links, it is _most_ helpful if you first quote the relevant
portion(s), then post the referencing link...

Try again?

OK, I will. A C implementation of a doubly-linked list that uses the same
memory location for both forward and backward pointers follows at the end of
this post.

I suspect you won't be happy with it, but it does store two "conceptual
variables" in one memory location, at least. And it is a moderately
interesting technique, if not (I suspect) hugely useful.

Note that, by it's nature, it isn't portable, relying on being able to convert
a pointer to an unsigned int and back again.

I'm not really a C programmer, so apologies for any hideous blunders and
malapropisms. Additionally, I've left removing nodes as an exercise for the
reader (ahem).

Regards,
Kieran Elby


#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

/*
Some platforms will need an unsigned long here.
Some platforms won't be able to use this technique at all.
*/
typedef unsigned int link;

typedef struct {
char *data;
/* This holds the XOR of the addresses of the
next and previous nodes */
link link;
} node;

/*
Add node after nodes n1 and n2.
n2 must be adjacent to n1.
*/
node* add_node(node *n1, node *n2) {

node *n, *n3, *n4;

n = malloc(sizeof(node));
n->data = 0;

if (!n2) {
n3 = 0;
} else {
n3 = (node *) (n2->link ^ (link) n1);
}

n->link = (link) n2 ^ (link) n3;

if (n2) {
n2->link = (link) n1 ^ (link) n;
}

if (n3) {
n4 = (node *) (n3->link ^ (link) n2);
n3->link = (link) n ^ (link) n4;
}

return n;
}

/*
Get node after nodes n1 and n2.
n2 must be adjacent to n1.
*/
node* next_node(node *n1, node *n2) {
if (n1) {
return (node *) (n2->link ^ (link) n1);
} else {
return (node *) n2->link;
}
}

void print_nodes(node *n1, node *n2) {

node *n;

while (1) {
printf(n2->data);
n = next_node(n1, n2);
n1 = n2;
n2 = n;
if (!n) {
break;
}
}
}

int main(void) {

node *nA, *nB, *nC, *nX;

/* Won't work without this */
assert(sizeof(link) >= sizeof(node *));

/* Create list of nodes A, B, C */

nA = add_node(0,0);
nA->data = "A";

nB = add_node(0,nA);
nB->data = "B";

nC = add_node(nA,nB);
nC->data = "C";

/* Add X between B and C */

nX = add_node(nA,nB);
nX->data = "X";

/* Traverse nodes forwards */

printf("Forwards: ");
print_nodes(0, nA);
printf("\n");

/* Traverse nodes backwards */

printf("Backwards: ");
print_nodes(0, nC);
printf("\n");

return 0;
}
 
D

Dan Pop

In said:
But, Dan, don't we want to teach these newcomers to code properly? Shouldn't
one point out that a function declared as returning an int, that does not
return an int, may have a flaw?

Yup, most definitely, but not by making patently false statements.
Ask yourself if my short post (one line) helped to show this general error
that may have deep implications if ignored in large, industrial
applications.
I think my post was consise, and germain, without being overbearing; and
therefore unheard.

Your post was technically incorrect and therefore, unsuitable for
technical newsgroups, period.
"Brevity is the soul of wit". One can teach without a stick in hand, Dan.

Blatantly false statements are the worst way of teaching. Imagine that
the OP doesn't get any warning, which is quite likely (e.g. gcc doesn't
warn by default). What is he supposed to understand from your post?
Are you helping *or* confusing the OP?

Dan
 
D

Dan Pop

In said:
Then, pray tell, how is the term "variable" defined, WRT to the C
language? Those who were using it were actually talking about named
objects, *technically*. However, except for C++, the term variable
isn't officially defined to mean "named object".


It's indeed highly unrealistic to expect everyone to avoid those
terms. However, a quick look in the archives shows that the use of
correct, well-defined terms, instead of sloppy jargon, serves well to
reduce the risk of confusion. What's wrong with object, external
linkage, file scope, etc.pp., after all?

Nothing, except that answering a newbie question in a jargon that is
completely unknown to him is not going to *really* help him. Neither is
pointing him to the standard, so that he learns the "proper" terminology.

If you really want to help a newbie, you *must* use the terminology he
understands. It's as simple as that, hence my reference to the perfect
ivory tower.

Dan
 
J

Julie

Irrwahn said:
Julie said:
Irrwahn said:
<much snippage>

I'm all for using correct terms. What would you call 'a' here:

int main()
{
int a = 1;
return 0;
}

Technically correct:
'a' is an identifier designating an object of type int.

Jargon (and in this case I think there's no place for confusion):
'a' is a variable of type int.

That was easy ;-). Now for the next round, you first:
What would you call p and *p, respectively?

int main(void)
{
int a = 1;
int *p = &a;
*p = 2;
return 0;
}

I call 'p' a "pointer [to an int]" and '*p' "p dereferenced" or "a pointer [to
an int] dereferenced".

So you think the term "variable" is applicable to neither p nor *p?

I'd call p a variable, but not *p. I'd say that *p might /point/ to a
variable, but that is it.
 
M

Mabden

Dan Pop said:
Are you helping *or* confusing the OP?

<sigh> Yes Dan, you are surely right, as always. I will try to refrain for
posting, as we all should. Only Dan Pop has the right answers. When will we
all learn to shut up and let You speak Your word to enlighten us all. I'm
not worthy, I'm not worthy...
 
R

Randy Howard

<sigh> Yes Dan, you are surely right, as always. I will try to refrain for
posting, as we all should. Only Dan Pop has the right answers. When will we
all learn to shut up and let You speak Your word to enlighten us all. I'm
not worthy, I'm not worthy...

At last the grasshopper finally understands Dan.

:)
 
I

Irrwahn Grausewitz

Julie said:
Irrwahn said:
Julie said:
Irrwahn Grausewitz wrote:
What would you call p and *p, respectively?

int main(void)
{
int a = 1;
int *p = &a;
*p = 2;
return 0;
}

I call 'p' a "pointer [to an int]" and '*p' "p dereferenced" or "a pointer [to
an int] dereferenced".

So you think the term "variable" is applicable to neither p nor *p?

I'd call p a variable, but not *p.

I agree with you here.
I'd say that *p might /point/ to a
variable, but that is it.

I beg to differ, I'd rather say that p points to a variable.

Regards
 
I

Irrwahn Grausewitz

Nothing, except that answering a newbie question in a jargon that is
completely unknown to him is not going to *really* help him.

Agreed, but it's IMHO likely to confuse newbies, if e.g. someone calls
a dereferenced pointer a variable, as happened up-thread.
Neither is
pointing him to the standard, so that he learns the "proper" terminology.

Definitly; it's much better to explain the "proper" terminology in
context. I consider this to be one (albeit not main) purpose of this
news-group.
If you really want to help a newbie, you *must* use the terminology he
understands. It's as simple as that, hence my reference to the perfect
ivory tower.

Fortunately, c.l.c will never become a perfect ivory tower, or at
the very least as long as I continue to post here... ;-)

Regards
 
P

pete

Julie said:
Try again.

No *variable* is sharing the same address. Node, head, and tail all have
different addresses, unless you can say that any of the following is true:

&node == &head == &tail

It doesn't matter what node _points_ to, it matters where node _is_.

Under your logic, the following two variables:

int a = 1;
int b = 2;

become the _same_ same variable with the following:

b = 1;

Surely you don't now consider a and b the same _variable_, do you?

No, I don't, and don't call me Shurly.

For
int *pointer = &b;

*pointer has the same address as b.
*pointer is a variable.
Remember, we are talking about _addresses_ of variables,
not the _value_ of variables.

*node is a variable.
In the code example, *node has the same address as either
*tail or *head.
 
D

Dan Pop

In said:
<sigh> Yes Dan, you are surely right, as always.

I am right when I am right and wrong when I am wrong. I am neither
always right nor always wrong.
I will try to refrain for posting, as we all should.

When not having the correct answer.
Only Dan Pop has the right answers. When will we
all learn to shut up and let You speak Your word to enlighten us all. I'm
not worthy, I'm not worthy...

Cut the crap!

Dan
 
D

Dan Pop

In said:
Julie said:
Irrwahn said:
Irrwahn Grausewitz wrote:
What would you call p and *p, respectively?

int main(void)
{
int a = 1;
int *p = &a;
*p = 2;
return 0;
}

I call 'p' a "pointer [to an int]" and '*p' "p dereferenced" or "a pointer [to
an int] dereferenced".

So you think the term "variable" is applicable to neither p nor *p?

I'd call p a variable, but not *p.

I agree with you here.

How would you call *p, though? It has the semantics of a variable,
doesn't it?
I beg to differ, I'd rather say that p points to a variable.

That's something too subtle for Julie to understand. She seems to be
blind to the semantic difference between p (that can point to a variable)
and *p (that *is* the variable pointed to by p).

Dan
 
P

pete

*node is a variable.
In the code example, *node has the same address as either
*tail or *head.

I meant:

"In the code example, *node has the same address as either
tail or head."
 
J

Julie

Irrwahn said:
Julie said:
Irrwahn said:
Irrwahn Grausewitz wrote:
What would you call p and *p, respectively?

int main(void)
{
int a = 1;
int *p = &a;
*p = 2;
return 0;
}

I call 'p' a "pointer [to an int]" and '*p' "p dereferenced" or "a pointer [to
an int] dereferenced".

So you think the term "variable" is applicable to neither p nor *p?

I'd call p a variable, but not *p.

I agree with you here.
I'd say that *p might /point/ to a
variable, but that is it.

I beg to differ, I'd rather say that p points to a variable.

In context specific conditions (such as the code above), this is true where p
points to a.

However (and it wasn't clear in my response), generally speaking: an arbitrary
point x *may* point to a variable, but not necessarily.
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top