Objects

F

fctk

ok, i'm trying to understand the concept of "object" in C.

i know that an object is a region of memory that can represent values.

first: what is meant with "memory"? RAM only? for example, is a register
variable an object (it is in the CPU)? and a file (it is on the HD)?

what about strings such as "hello"? i think they are two distinct
objects: an array of chars, and a pointer to its first element.

so, summarizing, all of the following things are objects:

* arithmetic variables (int a = 0; double pi = 3.1415; ...)
* pointers (char *sPtr; ...)
* arrays (int array[10]; ...)
* array elements (array[0], ...)
* structs
* structs members
* dynamically allocated things (malloc)
* arithmetic constants (2.71, 50000UL, 'A', ...)
* const things (const int x; ...)

would you add some other relevant things in the previous list (or remove
some)?
 
J

Joe Wright

fctk said:
ok, i'm trying to understand the concept of "object" in C.

i know that an object is a region of memory that can represent values.
"An object is a named region of storage; an lvalue is an expression
referring to an object." From K&R2 A5 pp197.
first: what is meant with "memory"? RAM only? for example, is a register
variable an object (it is in the CPU)? and a file (it is on the HD)?
For the sake of argument let's take 'memory' and 'storage' as
synonymous. I suppose 'register' does not qualify because we can't
determine its address in memory (it doesn't have one).

register int reg = 1;

This is not guaranteed to use a register. It's the compiler's call. It
does preclude 'int *rp = ®' because the address of a register is
un-defined.
what about strings such as "hello"? i think they are two distinct
objects: an array of chars, and a pointer to its first element.
Expressing "hello" will create an array [6] of char and yield the
address of the 'h' as type (char *).
so, summarizing, all of the following things are objects:

* arithmetic variables (int a = 0; double pi = 3.1415; ...)
* pointers (char *sPtr; ...)
* arrays (int array[10]; ...)
* array elements (array[0], ...)
* structs
* structs members

A struct is a user defined type. As such it is a declaration rather than
a definition. The struct becomes an object once it's defined. Observe..

struct demo {
int a;
int b;
int c;
};

This is a declaration of a structure. It is not an object. A subsequent ..

struct demo stru;

defines stru an object of type 'struct demo'.

* dynamically allocated things (malloc)

Yes. Allocated memory consists at least of byte-sized objects named
after the pointer to which its address was assigned.
* arithmetic constants (2.71, 50000UL, 'A', ...)

Arithmetic constants are not objects.
 
K

Keith Thompson

Joe Wright said:
"An object is a named region of storage; an lvalue is an expression
referring to an object." From K&R2 A5 pp197.

In my opinion, the word "named" doesn't belong in that definition.
The standard's definition is "region of data storage in the execution
environment, the contents of which can represent values". For
example, a region of memory allocated by malloc() is an object, even
though it doesn't have a name. (You could stretch the definition of
"named" by saying that its name is *ptr, but I think that's
misleading.)

I mentioned this in an e-mail message to Dennis Ritchie the other day;
he acknowledged that it's worth a note.

[...]
A struct is a user defined type. As such it is a declaration rather than
a definition. The struct becomes an object once it's defined.

That depends on what you mean by "a struct". Without qualification,
the phrase "a struct" commonly refers to an object of struct type,
just as "an integer" or "an array" commonly refers to an object of
integer or array type, respectively. To avoid confusion, it's
probably best to refer to a "struct type" or a "struct object".

[...]
Yes. Allocated memory consists at least of byte-sized objects named
after the pointer to which its address was assigned.

By "pointer" you mean "pointer object", right? Note that if you
clobber the pointer (a memory leak), the allocated chunk of memory
doesn't cease to be an object, even though it doesn't have a name.
(If you like, you can break down the pointer value into bytes and save
them separately, and reconstruct the pointer value later.)
 
J

Joe Wright

Keith said:
In my opinion, the word "named" doesn't belong in that definition.
The standard's definition is "region of data storage in the execution
environment, the contents of which can represent values". For
example, a region of memory allocated by malloc() is an object, even
though it doesn't have a name. (You could stretch the definition of
"named" by saying that its name is *ptr, but I think that's
misleading.)
I didn't know your opinion on the point. Sorry.
I mentioned this in an e-mail message to Dennis Ritchie the other day;
he acknowledged that it's worth a note.
And Dennis didn't know your opinion on the point either.
[...]
A struct is a user defined type. As such it is a declaration rather than
a definition. The struct becomes an object once it's defined.

That depends on what you mean by "a struct". Without qualification,
the phrase "a struct" commonly refers to an object of struct type,
just as "an integer" or "an array" commonly refers to an object of
integer or array type, respectively. To avoid confusion, it's
probably best to refer to a "struct type" or a "struct object".
If you read my post you will find that I have described struct type and
struct object and differentiated between them correctly.
[...]
Yes. Allocated memory consists at least of byte-sized objects named
after the pointer to which its address was assigned.

By "pointer" you mean "pointer object", right? Note that if you
clobber the pointer (a memory leak), the allocated chunk of memory
doesn't cease to be an object, even though it doesn't have a name.
(If you like, you can break down the pointer value into bytes and save
them separately, and reconstruct the pointer value later.)
I always mean pointer object, remember? The above paragraph doesn't make
a lot of sense to me. Why would I 'clobber' a pointer? I never do that.

The idea of breaking down a pointer value to constituent bytes so that I
might reconstruct a pointer with the original value has never occurred
to me. How would that be useful in the general sense? If you want a copy
of a pointer value, save it in another pointer.
 
B

Barry Schwarz

"An object is a named region of storage; an lvalue is an expression
referring to an object." From K&R2 A5 pp197.

For the sake of argument let's take 'memory' and 'storage' as
synonymous. I suppose 'register' does not qualify because we can't
determine its address in memory (it doesn't have one).

register int reg = 1;

This is not guaranteed to use a register. It's the compiler's call. It
does preclude 'int *rp = ®' because the address of a register is
un-defined.

But reg is still an object.
what about strings such as "hello"? i think they are two distinct
objects: an array of chars, and a pointer to its first element.
Expressing "hello" will create an array [6] of char and yield the
address of the 'h' as type (char *).
so, summarizing, all of the following things are objects:

* arithmetic variables (int a = 0; double pi = 3.1415; ...)
* pointers (char *sPtr; ...)
* arrays (int array[10]; ...)
* array elements (array[0], ...)
* structs
* structs members

A struct is a user defined type. As such it is a declaration rather than
a definition. The struct becomes an object once it's defined. Observe..

struct demo {
int a;
int b;
int c;
};

This is a declaration of a structure. It is not an object. A subsequent ..

struct demo stru;

defines stru an object of type 'struct demo'.

* dynamically allocated things (malloc)

Yes. Allocated memory consists at least of byte-sized objects named
after the pointer to which its address was assigned.
* arithmetic constants (2.71, 50000UL, 'A', ...)

Arithmetic constants are not objects.
* const things (const int x; ...)

would you add some other relevant things in the previous list (or remove
some)?


Remove del for email
 
B

Barry Schwarz

ok, i'm trying to understand the concept of "object" in C.

i know that an object is a region of memory that can represent values.

first: what is meant with "memory"? RAM only? for example, is a register
variable an object (it is in the CPU)? and a file (it is on the HD)?

what about strings such as "hello"? i think they are two distinct
objects: an array of chars, and a pointer to its first element.

An array is an aggregate object. It is not a pointer. In certain
expressions, an array name EVALUATES to the address of the first
element with type pointer to element type.
so, summarizing, all of the following things are objects:

* arithmetic variables (int a = 0; double pi = 3.1415; ...)
* pointers (char *sPtr; ...)
* arrays (int array[10]; ...)
* array elements (array[0], ...)
* structs
* structs members
* dynamically allocated things (malloc)
* arithmetic constants (2.71, 50000UL, 'A', ...)
* const things (const int x; ...)

would you add some other relevant things in the previous list (or remove
some)?

Unions, enums, maybe others.


Remove del for email
 
K

Keith Thompson

Joe Wright said:
I didn't know your opinion on the point. Sorry.

I don't understand; what are you sorry for?

[snip]
If you read my post you will find that I have described struct type
and struct object and differentiated between them correctly.

The previous poster used the term "struct"; you seemed to assume that
it meant "struct type". Or maybe I misunderstood. Not a big deal.
[...]
Yes. Allocated memory consists at least of byte-sized objects named
after the pointer to which its address was assigned.
By "pointer" you mean "pointer object", right? Note that if you
clobber the pointer (a memory leak), the allocated chunk of memory
doesn't cease to be an object, even though it doesn't have a name.
(If you like, you can break down the pointer value into bytes and save
them separately, and reconstruct the pointer value later.)
I always mean pointer object, remember?

No, I don't, but ok.
The above paragraph doesn't
make a lot of sense to me. Why would I 'clobber' a pointer? I never do
that.

The idea of breaking down a pointer value to constituent bytes so that
I might reconstruct a pointer with the original value has never
occurred to me. How would that be useful in the general sense? If you
want a copy of a pointer value, save it in another pointer.

I'm not saying there would be any good reason to do so, just
clarifying why an object needn't be named. Given:

int *ptr = malloc(sizeof *ptr);

(and assuming ptr!=NULL), one could argue that the allocated block of
memory does have a name, specifically *ptr. But if you follow the
above with

ptr = NULL;

then the object still exists, but it doesn't have a "name" in any
reasonable sense.

One could further argue that, since the object is no longer
accessible, it effectively no longer exists, and the implementation
can legally free() it or otherwise deallocate it. Disassembling the
value of ptr into bytes and storing them separately (so they can
potentially be reassembled) was merely intended to demonstrate a case
where the object is not "named", but it still exists and is still an
object. (Aside: it's also a case where garbage collection can break C
semantics.)

Definitions have to apply even in the presence of unreasonable code.
 
R

Richard G. Riley

"An object is a named region of storage; an lvalue is an expression
referring to an object." From K&R2 A5 pp197.

Why would an object need to be named? "tagged" or "referenced" or "
pointed to" yes: but named? I dont see the need for a specific
name. So long as the object metadata is available then the memory can
be correctly deciphered as the object it stores.
 
J

Joe Wright

Richard said:
Why would an object need to be named? "tagged" or "referenced" or "
pointed to" yes: but named? I dont see the need for a specific
name. So long as the object metadata is available then the memory can
be correctly deciphered as the object it stores.

I generally quote K&R without critical comment. I can't readily imagine
what an un-named object would be except for a literal string. In the
case of..

int *ptr = malloc(N * sizeof *ptr);

...it seems clear to me that the name of the resulting allocated object
is ptr (not *ptr suggested elsethread). It is effectively (not actually)
an array of int. ptr[0] through ptr[N-1] will yield the value of the
individual ints in the array.

It seems the Standard defines object without requiring a name. Again,
except for the literal string, I can't imagine one.
 
B

Ben C

[...]
I generally quote K&R without critical comment. I can't readily
imagine what an un-named object would be except for a literal string.
In the case of..
int *ptr = malloc(N * sizeof *ptr);
..it seems clear to me that the name of the resulting allocated object
is ptr (not *ptr suggested elsethread). It is effectively (not
actually) an array of int. ptr[0] through ptr[N-1] will yield the
value of the individual ints in the array.
It seems the Standard defines object without requiring a name. Again,
except for the literal string, I can't imagine one.

A structure instance returned from a function is an unnamed object?

#include <stdio.h>

struct object
{
int x;
int y;
};

static struct object f(void)
{
struct object ret = {1, 2}; /* it has a name here */
return ret;
}

int main(void)
{
/* But here it is unnamed. It exists though-- we can read its value */
int a = f().x;

printf("%d\n", a);
return 0;
}
 
K

Keith Thompson

Joe Wright said:
Richard said:
Why would an object need to be named? "tagged" or "referenced" or "
pointed to" yes: but named? I dont see the need for a specific
name. So long as the object metadata is available then the memory can
be correctly deciphered as the object it stores.

I generally quote K&R without critical comment. I can't readily
imagine what an un-named object would be except for a literal
string. In the case of..

int *ptr = malloc(N * sizeof *ptr);

..it seems clear to me that the name of the resulting allocated object
is ptr (not *ptr suggested elsethread). It is effectively (not
actually) an array of int. ptr[0] through ptr[N-1] will yield the
value of the individual ints in the array.

No, ptr is not the name of the allocated array, it's the name of an
object of type int*.

If ptr is the name of the array object, what's the name of the pointer
object?
It seems the Standard defines object without requiring a name. Again,
except for the literal string, I can't imagine one.

How about the 42nd node of a linked list?
 
J

Joe Wright

Ben said:
[...]
I generally quote K&R without critical comment. I can't readily
imagine what an un-named object would be except for a literal string.
In the case of..
int *ptr = malloc(N * sizeof *ptr);
..it seems clear to me that the name of the resulting allocated object
is ptr (not *ptr suggested elsethread). It is effectively (not
actually) an array of int. ptr[0] through ptr[N-1] will yield the
value of the individual ints in the array.
It seems the Standard defines object without requiring a name. Again,
except for the literal string, I can't imagine one.

A structure instance returned from a function is an unnamed object?

#include <stdio.h>

struct object
{
int x;
int y;
};

static struct object f(void)
{
struct object ret = {1, 2}; /* it has a name here */
return ret;
}

int main(void)
{
/* But here it is unnamed. It exists though-- we can read its value */
int a = f().x;

printf("%d\n", a);
return 0;
}

The function f() returns a value of type 'struct object'. It is not an
object. The object ret has ceased to exist upon f()'s return.
 
J

Joe Wright

Keith said:
Joe Wright said:
Richard said:
"An object is a named region of storage; an lvalue is an expression
referring to an object." From K&R2 A5 pp197.
Why would an object need to be named? "tagged" or "referenced" or "
pointed to" yes: but named? I dont see the need for a specific
name. So long as the object metadata is available then the memory can
be correctly deciphered as the object it stores.
I generally quote K&R without critical comment. I can't readily
imagine what an un-named object would be except for a literal
string. In the case of..

int *ptr = malloc(N * sizeof *ptr);

..it seems clear to me that the name of the resulting allocated object
is ptr (not *ptr suggested elsethread). It is effectively (not
actually) an array of int. ptr[0] through ptr[N-1] will yield the
value of the individual ints in the array.

No, ptr is not the name of the allocated array, it's the name of an
object of type int*.

If ptr is the name of the array object, what's the name of the pointer
object?
One step back, they are ambiguous. You can't tell the difference between
an array and a pointer to 'type'. 'int arr1[10];' is indistinguishable
from 'int *arr2;'. If 'arr2 = malloc(10 * sizeof *arr2);' was sucessfull
then arr1[4] and arr2[4] are identical semantically. At this level arr1
and arr2 are equivalently the names of their respective (array) objects.
How about the 42nd node of a linked list?
Start at 'root' and trip through the list 42 times setting 'this' each
time. Now 'this->member' is the name of an object in the list, and an
lvalue as well.
 
K

Keith Thompson

Joe Wright said:
Keith said:
Joe Wright said:
Richard G. Riley wrote:
"An object is a named region of storage; an lvalue is an expression
referring to an object." From K&R2 A5 pp197.
Why would an object need to be named? "tagged" or "referenced" or "
pointed to" yes: but named? I dont see the need for a specific
name. So long as the object metadata is available then the memory can
be correctly deciphered as the object it stores.
I generally quote K&R without critical comment. I can't readily
imagine what an un-named object would be except for a literal
string. In the case of..

int *ptr = malloc(N * sizeof *ptr);

..it seems clear to me that the name of the resulting allocated object
is ptr (not *ptr suggested elsethread). It is effectively (not
actually) an array of int. ptr[0] through ptr[N-1] will yield the
value of the individual ints in the array.
No, ptr is not the name of the allocated array, it's the name of an
object of type int*.
If ptr is the name of the array object, what's the name of the
pointer
object?
One step back, they are ambiguous. You can't tell the difference
between an array and a pointer to 'type'. 'int arr1[10];' is
indistinguishable from 'int *arr2;'. If 'arr2 = malloc(10 * sizeof
*arr2);' was sucessfull then arr1[4] and arr2[4] are identical
semantically. At this level arr1 and arr2 are equivalently the names
of their respective (array) objects.

Sorry, but that's nonsense. Of *course* you can tell the difference
between an array and a pointer. An array name is implicitly converted
to a pointer value only in some contexts. The expression &ptr still
yields the address of the pointer object, not of the array or of any
of its elements.

Arrays are not pointers. Pointers are not arrays. And we're talking
about the definition of the word "object", not about how some
particular code behaves.

Given the above declaration, ptr is the name of a pointer object,
nothing else. It can be used indirectly to access an int object, just
as an integer value can be used indirectly to access an array element;
that doesn't mean that 42 is the name of the 42nd element of an array.
Start at 'root' and trip through the list 42 times setting 'this' each
time. Now 'this->member' is the name of an object in the list, and an
lvalue as well.

The standard doesn't define the term "name", but it does define
"external name" and "internal name", and both refer only to
identifiers.

You can justify K&R2's definition of "object" *only* by stretching the
meaning of the word "name" beyond reason. The language is defined by
the standard, not by K&R2, and the standard's definition of "object"
just isn't consistent with K&R2's definition of "object".
 
J

Joe Wright

Keith said:
Joe Wright said:
Keith said:
Richard G. Riley wrote:
[...]
"An object is a named region of storage; an lvalue is an expression
referring to an object." From K&R2 A5 pp197.
Why would an object need to be named? "tagged" or "referenced" or "
pointed to" yes: but named? I dont see the need for a specific
name. So long as the object metadata is available then the memory can
be correctly deciphered as the object it stores.
I generally quote K&R without critical comment. I can't readily
imagine what an un-named object would be except for a literal
string. In the case of..

int *ptr = malloc(N * sizeof *ptr);

..it seems clear to me that the name of the resulting allocated object
is ptr (not *ptr suggested elsethread). It is effectively (not
actually) an array of int. ptr[0] through ptr[N-1] will yield the
value of the individual ints in the array.
No, ptr is not the name of the allocated array, it's the name of an
object of type int*.
If ptr is the name of the array object, what's the name of the
pointer
object?
One step back, they are ambiguous. You can't tell the difference
between an array and a pointer to 'type'. 'int arr1[10];' is
indistinguishable from 'int *arr2;'. If 'arr2 = malloc(10 * sizeof
*arr2);' was sucessfull then arr1[4] and arr2[4] are identical
semantically. At this level arr1 and arr2 are equivalently the names
of their respective (array) objects.

Sorry, but that's nonsense. Of *course* you can tell the difference
between an array and a pointer. An array name is implicitly converted
to a pointer value only in some contexts. The expression &ptr still
yields the address of the pointer object, not of the array or of any
of its elements.
Work with me here. You really can't tell the difference between arr1[4]
and arr2[4]. That's the whole point of 'mallocation', to make allocated
arrays behave like defined ones.
Arrays are not pointers. Pointers are not arrays. And we're talking
about the definition of the word "object", not about how some
particular code behaves.
And you know that I know that arrays are not pointers.
Given the above declaration, ptr is the name of a pointer object,
nothing else. It can be used indirectly to access an int object, just
as an integer value can be used indirectly to access an array element;
that doesn't mean that 42 is the name of the 42nd element of an array.
Again, one step back, ptr in an expression will yield the address of the
first element of the array and with the appropriate type. At this level
you can't tell whether ptr is a pointer or an array. That's the point!

[ snip ]
You can justify K&R2's definition of "object" *only* by stretching the
meaning of the word "name" beyond reason. The language is defined by
the standard, not by K&R2, and the standard's definition of "object"
just isn't consistent with K&R2's definition of "object".
The characteristics and qualities of objects in C have not changed since
Brian and Dennis described them, in 1978 and in 1989. The C standard is
a work in progress. K & R & I know what an object is. :)
 
P

pete

The standard uses this sentence as though memory and registers
are to be considered as two kinds of storage:

N869
5.1.2.3 Program execution
[#13]
"Values are independent of whether they are represented in a
register or in memory."

The standard also refers to objects with register storage class:

N869
6.3.2.1 Lvalues and function designators
[#3]
If the array object has register storage class,
the behavior is undefined.
In my opinion, the word "named" doesn't belong in that definition.
The standard's definition is "region of data storage in the execution
environment, the contents of which can represent values". For
example, a region of memory allocated by malloc() is an object, even
though it doesn't have a name. (You could stretch the definition of
"named" by saying that its name is *ptr, but I think that's
misleading.)

I think so too.
Functions, and automatic and static objects have names.

I think the word "name", is best applied to identifiers
which are also Primary expressions.

N869
6.5.1 Primary expressions
 
P

pete

Joe said:
Keith Thompson wrote:
The characteristics and qualities of objects
in C have not changed since
Brian and Dennis described them, in 1978 and in 1989.
The C standard is
a work in progress. K & R & I know what an object is. :)

The fact that there are such things
as objects with allocated duration,
is a feature of the language proper in C99, but not in C89.

In C89, there are only two kinds of duration,
and "allocated" isn't one of them.
Everything about the kinds of objects allocated by malloc,
is a feature of the library in C89.

The part of K&R2 which defines objects, is appendix A.
The part of K&R2 which describes the library and allocated objects
is appendix B.
 
K

Keith Thompson

pete said:
The fact that there are such things
as objects with allocated duration,
is a feature of the language proper in C99, but not in C89.

In C89, there are only two kinds of duration,
and "allocated" isn't one of them.
Everything about the kinds of objects allocated by malloc,
is a feature of the library in C89.

The part of K&R2 which defines objects, is appendix A.
The part of K&R2 which describes the library and allocated objects
is appendix B.

Interesting, I hadn't realized that.

But the C90 standard's definition of "object":

3.14 object. A region of data storage in the execution
environment, the contents of which can represent values. Except
for bit-fields, objects are composed of contiguous sequences of
one or more bytes, the number, order, and encoding of which are
either explicitly specified or implementation-defined when
referenced. An object may be interpreted as having a particular
type, see 6.2.2.1.

seems to me to be entirely consistent with a "region of data storage"
allocated by malloc(). (Any typos in the above are the fault of the
low-quality PDF I copy-and-pasted it from.)

In my opinion, this was an oversight in K&R and C90, corrected in C99.
 

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
474,183
Messages
2,570,965
Members
47,511
Latest member
svareza

Latest Threads

Top