Reference counting

C

Chris M. Thomasson

Shao Miller said:
Nope; you've lost me.

[...]

Yikes! Let me try to clarify: I was thinking in terms of an array of `struct
object' in which the beginning of said array is aligned on a boundary that
is greater than `sizeof(struct object)'. Imagine an array of N 128-byte
objects that simply has to be aligned on a 4096-byte boundary. Please excuse
any confusions I have caused!

;^(...
 
K

Keith Thompson

io_x said:
// macro for types
#define u64 uint64_t
#define u32 uint32_t
#define u16 uint16_t
#define u8 uint8_t
#define uns unsigned
#define dbl double

// macro for function
#define P printf

// macro for keyWords
#define G goto
#define R return
#define W while
#define F for

No.
 
T

Tim Rentsch

Keith Thompson said:
Tim Rentsch said:
Keith Thompson said:
For hashing, is the object representation of a 'void *' guaranteed to be
the same any time a 'void *' points to the same object? Is it likely?
(I think so.) :)

The standard only says pointers are represented in an
implementation-defined manner. But as long as the pointer value doesn't
change, I doubt the representation will. On most implementations, a
pointer is really just a 32- or 64-bit unsigned number, indicating a
certain spot in virtual memory.

Quibble: Pointer representation is unspecified, not
implementation-defined. [snip]

How do you reconcile this assertion with 6.2.6.1p2? Certainly
it looks like the representation of any pointer value stored in
an object would be (at least) implementation-defined.

Quite easily: by failing to read it carefully enough. :cool:}

But now that I have, I'm confused. Here's what it says:

1 The representations of all types are unspecified except as
stated in this subclause.

2 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.

3 Values stored in unsigned bit-fields and objects of type unsigned
char shall be represented using a pure binary notation.

As far as I can tell, *all* types have implementation-defined
representations; the section says so for non bit-fields and for
unsigned bit-fields, and I don't think there's enough wiggle room
to say that signed bit-fields have unspecified representations.

So why does paragraph 1 say "unspecified" rather than
"implementation-defined"? [snip]

Here's a possible idea: maybe paragraph 1 is talking about
representations generally (including, eg, registers), but
paragraph 2 is talking about representations specifically
only in objects. So values of a type can be represented
outside of being stored in an object, but what those
representations might be is all "under the hood", with no
documentation required. What do you think? Does that make
sense?

My impression is that the idea of representation applies only to
objects. The representation of a value not stored in an object is
irrelevant until and unless it's stored in an object.

Let me offer a counter-example, which is floating-point values.
In several places the Standard talks about floating-point operands
being represented with a greater range or precision than that of
the type (of the expression that would produce the operand value).
Certainly these operand values exist and have some representation
in an actual computer, but those representations aren't the same as
the operand's expression's type's object representation -- indeed,
the representation of a floating-point operand value may be different
than the object representation of any C floating-point type.

A similar description could hold for a (hypothetical) machine that
had only one kind of signed integer register, let's say 128 bits,
with all signed arithmetic being done using these big registers
(and with some way of storing part of a big register into a narrower
non-register memory location). The register representation could
easily be different than the object representation of any C
signed integer type. The representation of signed integer values
would be unspecified, only the representations of signed integers
stored in objects would be implementation-defined.

I think your idea makes some sense, but I don't think it's what
6.2.6.1 is referring to.

I don't mean to advocate that it is, only that it might be (and
that I can't yet think of any better possibility).

I have no particular support for this.

The word representation (in various forms) is used in quite
a few places in the Standard, applying to lots of different
circumstances. If 6.2.6.1p1 isn't referring to things like
floating-point operands (ie, representations other than those
in objects), what is it talking about?
 
S

Shao Miller

io_x said:
io_x said:
"io_x"<[email protected]> ha scritto nel messaggio

what about my try?

someone think there are too many cast?
what about consider for align
union tipidiarray{
double a;
size_t v;
u8* m;
};
and think are possible array of each element of that union?
so if "a" is aligned to double, size_t, u8*
"a"+sizeof(double), "a"+sizeof(size_t)
"a"+sizeof(u8*) has to be aligned to each rispettive type
and so if "a" is a return address of malloc
"a"+sizeof(tipidiarray)
is ok for double, size_t, u8*
[if "a" point to sufficient memory]
[...code...]


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

uint32_t ele(void)
{
long double ldbt[2];
double dbt[2];
size_t szt[2];
uint8_t *art[2], *a, *b;
long unsigned lut[2];
uint32_t r, v;

r = 0;
a = &ldbt[0];
b = &ldbt[1];
v = b - a;
#if 0
100b-1b=11
#endif
if (((v - 1) & v) == 0 && v > r)
r = v;

a = &dbt[0];
b = &dbt[1];
v = b - a;
#if 0
100b-1b=11
#endif
if (((v - 1) & v) == 0 && v > r)
r = v;

a = &szt[0];
b = &szt[1];
v = b - a;
if (((v - 1) & v) == 0 && v > r)
r = v;

a = &art[0];
b = &art[1];
v = b - a;
if (((v - 1) & v) == 0 && v > r)
r = v;

a = &lut[0];
b = &lut[1];
v = b - a;
if (((v - 1) & v) == 0 && v > r)
r = v;

return r;
}

union tipidiarray {
double a;
size_t v;
uint8_t *m;
};

uint32_t elemento;

uint8_t *IniMem(uint32_t s)
{
uint8_t *p;
uint32_t *pu;
uint32_t c;

if (s == 0)
return 0;
c = s;
c += elemento;
if (c <= s)
return 0;
p = malloc(c);
if (p == 0)
return 0;
pu = (uint32_t *) p;
p += elemento;
pu[0] = 1;
pu[1] = (uint32_t) p;
return p;
}

uint8_t *GetRef(uint8_t * v)
{
uint8_t *p;
uint32_t *pu;

if (v == 0)
return 0;
p = v - elemento;
pu = (uint32_t *) p;
if (pu[0] == 0 || pu[1] != (uint32_t) v)
return 0;
++pu[0];
if (pu[0] == 0) {
--pu[0];
return 0;
}
return v;
}

uint32_t GetRefCounter(uint8_t * v)
{
uint8_t *p;
uint32_t *pu;

if (v == 0)
return 0;
p = v - elemento;
pu = (uint32_t *) p;
if (pu[1] != (uint32_t) v)
return (uint32_t) - 1;
return pu[0];
}

uint8_t *PutRef(uint32_t * ris, uint8_t * v)
{
uint8_t *p;
uint32_t *pu;

if (ris == 0)
return 0;
*ris = 0;
if (v == 0)
return 0;
p = v - elemento;
pu = (uint32_t *) p;
if (pu[0] == 0 || pu[1] != (uint32_t) v) {
*ris = -1;
return 0;
}
--pu[0];
if (pu[0] == 0) {
pu[1] = 0;
free(p);
}
return 0;
}

int main(void)
{
double *arrd, *pad;
uint32_t *arru, *elm, ris;

elemento = ele();
printf("Elemento=%u\n", elemento);
if (2 * sizeof(uint32_t) > elemento) {
printf("Errore di inizializzazione\n");
return 0;
}
arrd = (double *)IniMem(10 * sizeof(double));
arrd[0] = 1.111;
pad = (double *)GetRef((uint8_t *) arrd);
if (pad == 0) {
printf("Errore della funzione GetRef()\n");
printf("o memoria insufficiente\n");
exit(0);
}
printf("val=%f nref=%u\n", pad[0],
(unsigned)GetRefCounter((uint8_t *) arrd));
pad = (double *)PutRef(&ris, (uint8_t *) pad);
printf("val=%f nref=%u pad=%p ris=%u\n",
arrd[0], (unsigned)GetRefCounter((uint8_t *) arrd),
(uint8_t *) pad, (unsigned)ris);

arrd = (double *)PutRef(&ris, (uint8_t *) pad);
printf("nref=%u ris=%u\n", (unsigned)GetRefCounter((uint8_t *) arrd),
(unsigned)ris);
return 0;
}

GCC gave:

io_x2.c: In function 'ele':
io_x2.c:15: warning: assignment from incompatible pointer type
io_x2.c:16: warning: assignment from incompatible pointer type
io_x2.c:24: warning: assignment from incompatible pointer type
io_x2.c:25: warning: assignment from incompatible pointer type
io_x2.c:33: warning: assignment from incompatible pointer type
io_x2.c:34: warning: assignment from incompatible pointer type
io_x2.c:39: warning: assignment from incompatible pointer type
io_x2.c:40: warning: assignment from incompatible pointer type
io_x2.c:45: warning: assignment from incompatible pointer type
io_x2.c:46: warning: assignment from incompatible pointer type
 

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

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top