Library bug or my fault?

S

Steven Woody

Hi,

Please check the sample code listed in the end of the message. It was
compiled using ARM/Linux cross-compiler and run on an ARM9 target. I
think the problem applies to this group because two cross-compiler
from different vendor result same error. So I guess it is not vendor
specific. If my guess is right, then it means the code itself may get
problem, but I can not figure out where it is.

The problem is, the line 38 which copy 3 bytes, starting from p2, to
p1, but the immediately followed memcmp (line 42) shows the memcpy was
not well done. I am sure the memcpy did not do the job, since if I
provide my own memcpy implemention as below, the error will go
disappear.

void memcpy(void *dest, void *src, size_t n)
{
uint8_t *d = (uint8_t*)dest;
uint8_t *s = (uint8_t*)src;

for (size_t i = 0; i < n; ++i)
*d++ = *s++;
}

Could you please check the code as well as the running result and
tell me what wrong with it? Thanks.


------------------------------------- the minimum sample
--------------------------------------------------
1 #include <stdio.h>
2 #include <string>
3 #include <stdint.h>
4 #include <assert.h>
5
6 struct Foo {
7 uint8_t x;
8 uint8_t y;
9 uint8_t z;
10 uint8_t m[3];
11 };
12
13 struct Bar
14 {
15 uint8_t m[3];
16 };
17
18 void pr(const char *title, const void *block, size_t n)
19 {
20 printf("%s\n", title);
21
22 uint8_t *p = (uint8_t*)block;
23 for (size_t i = 0; i < n; ++i)
24 printf("0x%02x ", *p++);
25
26 printf("\n");
27 }
28
29 void cp(const Foo *foo)
30 {
31 Bar bar;
32
33 Bar *p1 = &bar;
34 Bar *p2 = (Bar*)(foo->m);
35 pr("before: p1:", p1, 3);
36 pr("before: p2:", p2, 3);
37
38 memcpy(p1, p2, 3);
39 pr("after: p1:", p1, 3);
40 pr("after: p2:", p2, 3);
41
42 if (memcmp(p1, p2, 3) != 0)
43 printf("!!! cp is wrong\n");
44 }
45
46 int main()
47 {
48 Foo foo;
49 foo.x = 1;
50 foo.y = 2;
51 foo.z = 3;
52 foo.m[0] = 0x40;
53 foo.m[1] = 0x19;
54 foo.m[2] = 0x21;
55
56 cp(&foo);
57 cp2(&foo);
58 return 0;
59 }
------------------------------------------------------------------

Below is the running output on an ARM920T board:

before: p1:
0xfc 0x01 0x12
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x01 0x02
after: p2:
0x40 0x19 0x21
!!! cp is wrong
 
P

Peter Nilsson

Steven said:
...
The problem is, the line 38 which copy 3 bytes, starting from
p2, to p1, but the immediately followed memcmp (line 42)
shows the memcpy was not well done.

It's the lines before that signal a problem.
------------------------------------- the minimum sample
--------------------------------------------------
1 #include <stdio.h>
2 #include <string>
3 #include <stdint.h>
4 #include <assert.h>
5
6 struct Foo {
7 uint8_t x;
8 uint8_t y;
9 uint8_t z;
10 uint8_t m[3];
11 };
12
13 struct Bar
14 {
15 uint8_t m[3];
16 };

These are completely different structs.
29 void cp(const Foo *foo)
30 {
31 Bar bar;
32
33 Bar *p1 = &bar;
34 Bar *p2 = (Bar*)(foo->m);

The fact you have a cast to silence a warning (or more likely
error) on incompatible types is the problem. Bar is not an array,
it is a struct containing an array.

The standard allows the conversion (if foo->m is aligned
properly), but it says nothing more. Only if you convert it
back must it compare equal.
35 pr("before: p1:", p1, 3);
36 pr("before: p2:", p2, 3);
37
38 memcpy(p1, p2, 3);

If you really wanted to do this, then the following should work...

memcpy(bar->m, foo->m, sizeof foo->m);

If that fails, you have cuase for concern.

You have other options, like putting a Bar struct inside foo.
The you can use Bar pointers and simple assignment.

But fundamentally, you should be copying like to like.

<snip>
 
S

Steven Woody

It seems to be written in some non-C but C-like language. Did you mean
to post to C++ instead? See if this version (notice the changes, more
may be advisable, but I address only what might be your problem) works
for you.

I am sorry, the #include <string> is a typo, and I should typedef
struct ... Foo/Bar to make it a pure C. Actually I did these in my
new version, but the problem keeps same.
There are clearly possible problems remaining (for example,
are you sure that accessing the uninitialized contents of 'bar' is safe?).

Why I cann't? I did not go beyond its boundary.

#include <stdio.h>
#include <string.h> /* mha: was 'string' */
#include <stdint.h>

struct Foo
{
uint8_t x;
uint8_t y;
uint8_t z;
uint8_t m[3];

};

struct Bar
{
uint8_t m[3];

};

void pr(const char *title, const void *block, size_t n)
{
printf("%s\n", title);

uint8_t *p = (uint8_t *) block;
for (size_t i = 0; i < n; ++i)
printf("0x%02x ", *p++);

printf("\n");

}

void cp(const struct Foo /* mha: added needed 'struct' */ *foo)
{
struct Bar bar; /* mha: added needed 'struct' here &
below */
struct Bar *p1 = &bar;
struct Bar *p2 = (struct Bar *) (foo->m);
pr("before: p1:", p1, 3);
pr("before: p2:", p2, 3);

memcpy(p1, p2, 3);
pr("after: p1:", p1, 3);
pr("after: p2:", p2, 3);

if (memcmp(p1, p2, 3) != 0)
printf("!!! cp is wrong\n");

}

int main()
{
struct Foo foo; /* mha: added need 'struct' */
foo.x = 1;
foo.y = 2;
foo.z = 3;
foo.m[0] = 0x40;
foo.m[1] = 0x19;
foo.m[2] = 0x21;

cp(&foo);
return 0;

}

before: p1:
0x20 0x20 0x20
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x19 0x21
after: p2:
0x40 0x19 0x21

Certainly the output is different from yours.
Below is the running output on an ARM920T board:
before: p1:
0xfc 0x01 0x12
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x01 0x02
after: p2:
0x40 0x19 0x21

I copy/paste your version exactly, the output is totally same as whay
I posted previously. I guess you are running the code on a normal x86
PC. My original code also works on x86/Linux, it only appears when
run on ARM.
 
N

Nick Keighley

Please check the sample code listed in the end of the message.  It was
compiled using ARM/Linux cross-compiler and run on an ARM9 target. I
think the problem applies to this group because two cross-compiler
from different vendor result same error.  So I guess it is not vendor
specific.  If my guess is right, then it means the code itself may get
problem, but I can not figure out where it is.

The problem is, the line 38 which copy 3 bytes, starting from p2, to
p1, but the immediately followed memcmp (line 42) shows the memcpy was
not well done.  I am sure the memcpy did not do the job, since if I
provide my own memcpy implemention as below, the error will go
disappear.

void memcpy(void *dest, void *src, size_t n)
{
    uint8_t *d = (uint8_t*)dest;
    uint8_t *s = (uint8_t*)src;

    for (size_t i = 0; i < n; ++i)
        *d++ = *s++;

}

Could you please check the code as well as  the running result and
tell me what wrong with it?  Thanks.

------------------------------------- the minimum sample
--------------------------------------------------
1 #include <stdio.h>
2 #include <string>
3 #include <stdint.h>
4 #include <assert.h>
5
6 struct Foo {
7     uint8_t x;
8     uint8_t y;
9     uint8_t z;
10     uint8_t m[3];
11 };
12
13 struct Bar
14 {
15     uint8_t m[3];
16 };
17
18 void pr(const char *title, const void *block, size_t n)
19 {
20     printf("%s\n", title);
21
22     uint8_t *p = (uint8_t*)block;
23     for (size_t i = 0; i < n; ++i)
24         printf("0x%02x ", *p++);
25
26     printf("\n");
27 }
28
29 void cp(const Foo *foo)
30 {
31     Bar bar;
32
33     Bar *p1 = &bar;
34     Bar *p2 = (Bar*)(foo->m);
35     pr("before: p1:", p1, 3);
36     pr("before: p2:", p2, 3);
37
38     memcpy(p1, p2, 3);
39     pr("after: p1:", p1, 3);
40     pr("after: p2:", p2, 3);
41
42     if (memcmp(p1, p2, 3) != 0)
43         printf("!!! cp is wrong\n");
44 }
45
46 int main()
47 {
48     Foo foo;
49     foo.x = 1;
50     foo.y = 2;
51     foo.z = 3;
52     foo.m[0] = 0x40;
53     foo.m[1] = 0x19;
54     foo.m[2] = 0x21;
55
56     cp(&foo);
57     cp2(&foo);
58     return 0;
59 }
------------------------------------------------------------------

Below is the running output on an ARM920T board:

before: p1:
0xfc 0x01 0x12
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x01 0x02
after: p2:
0x40 0x19 0x21
!!! cp is wrong

post your code!!
You have no definition for cp2() so the code above won't compile.

I don't have a C99 compiler so I compiled this instead:
(can you miss out the "struct" keyword in C99?)

***************

#include <stdio.h>
/* #include <string> */ /* njk */
/* #include <stdint.h> */ /* njk */
#include <string.h> /* njk */
#include <assert.h>

typedef unsigned char uint8_t; /* njk */

struct Foo {
uint8_t x;
uint8_t y;
uint8_t z;
uint8_t m[3];
};

struct Bar
{
uint8_t m[3];
};

void pr(const char *title, const void *block, size_t n)
{
uint8_t *p = (uint8_t*)block; /* njk */
size_t i; /* njk */

printf("%s\n", title);

for (i = 0; i < n; ++i) /* njk */
printf("0x%02x ", *p++);

printf("\n");
}

void cp(const struct Foo *foo) /* njk */
{
struct Bar bar; /* njk */

struct Bar *p1 = &bar; /* njk */
struct Bar *p2 = (struct Bar*)(foo->m); /* njk */
pr("before: p1:", p1, 3);
pr("before: p2:", p2, 3);

memcpy(p1, p2, 3);
pr("after: p1:", p1, 3);
pr("after: p2:", p2, 3);

if (memcmp(p1, p2, 3) != 0)
printf("!!! cp is wrong\n");
}

int main()
{
struct Foo foo; /* njk */
foo.x = 1;
foo.y = 2;
foo.z = 3;
foo.m[0] = 0x40;
foo.m[1] = 0x19;
foo.m[2] = 0x21;

cp(&foo);
/* cp2(&foo); */ /* njk */
return 0;
}

***************



the lines I changes are marked /* njk */

This produced the following output

C:\bin\Debug>woody.exe
before: p1:
0x00 0x08 0x00
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x19 0x21
after: p2:
0x40 0x19 0x21

which looks ok to me


--
Nick Keighley

"Of course I'm going to be in an aeroplane on 31st December 1999.
You scientists wouldn't be stupid enough to build things that don't
work.
Besides what have computers got to do with aeroplanes anyway?"
 
N

Nick Keighley

Steven Woody wrote:
The problem is, the line 38 which copy 3 bytes, starting from
p2, to p1, but the immediately followed memcmp (line 42)
shows the memcpy was not well done.

It's the lines before that signal a problem.
------------------------------------- the minimum sample
--------------------------------------------------
1 #include <stdio.h>
2 #include <string>
3 #include <stdint.h>
4 #include <assert.h>
5
6 struct Foo {
7     uint8_t x;
8     uint8_t y;
9     uint8_t z;
10     uint8_t m[3];
11 };
12
13 struct Bar
14 {
15     uint8_t m[3];
16 };

These are completely different structs.

yes, so?
The fact you have a cast to silence a warning (or more likely
error) on incompatible types is the problem. Bar is not an array,
it is a struct containing an array.

yes, but there can't be padding at the beginning of a struct
hence Bar.m and Bar must be at the same address. Also
uint8_t is probably (almost certainly) an alias (typedef) for
unsigned char and you can safely cast *anything* to
unsigned char I'd say this pretty well had to work (do you
have a compiler where it doesn't work?)

The standard allows the conversion (if foo->m is aligned
properly),

why would foo->m not be correctly aligned? Suppose it was int
rather than uint8_t; I reckon it would *still* work (even on a
68000, which was the fussiest hardware I ever worked on)

but it says nothing more. Only if you convert it
back must it compare equal.

unless it's an unsigned char...

If you really wanted to do this, then the following should work...

  memcpy(bar->m, foo->m, sizeof foo->m);

If that fails, you have cuase for concern.

I think he has cause already
You have other options, like putting a Bar struct inside foo.
The you can use Bar pointers and simple assignment.

But fundamentally, you should be copying like to like.

"up to a point, Lord Copper"


--
Nick Keighley

If cosmology reveals anything about God, it is that He has
an inordinate fondness for empty space and non-baryonic dark
matter.
 
S

Steven Woody

Steven said:
...
The problem is, the line 38 which copy 3 bytes, starting from
p2, to p1, but the immediately followed memcmp (line 42)
shows the memcpy was not well done.

It's the lines before that signal a problem.


------------------------------------- the minimum sample
--------------------------------------------------
1 #include <stdio.h>
2 #include <string>
3 #include <stdint.h>
4 #include <assert.h>
5
6 struct Foo {
7 uint8_t x;
8 uint8_t y;
9 uint8_t z;
10 uint8_t m[3];
11 };
12
13 struct Bar
14 {
15 uint8_t m[3];
16 };

These are completely different structs.
29 void cp(const Foo *foo)
30 {
31 Bar bar;
32
33 Bar *p1 = &bar;
34 Bar *p2 = (Bar*)(foo->m);

The fact you have a cast to silence a warning (or more likely
error) on incompatible types is the problem. Bar is not an array,
it is a struct containing an array.

The standard allows the conversion (if foo->m is aligned
properly), but it says nothing more. Only if you convert it
back must it compare equal.
35 pr("before: p1:", p1, 3);
36 pr("before: p2:", p2, 3);
37
38 memcpy(p1, p2, 3);

If you really wanted to do this, then the following should work...

memcpy(bar->m, foo->m, sizeof foo->m);

If that fails, you have cuase for concern.

You have other options, like putting a Bar struct inside foo.
The you can use Bar pointers and simple assignment.

But fundamentally, you should be copying like to like.

<snip>

Dear Peter,

Among all the replies, after real test, I found your fix is right. I
think your point is Foo::m is not Bar even though Bar is defined
exactly a structure contains merely Foo::m. This conflics with my
memory about the language. But, anyway, the result shows your are
absolutely right.

I am just wondering some things which still showing unreasonable:

1. In line 36 and line 40, why I can still use p2 to print the memory
without presenting a problem?
2. Why everything works normal when I substitue the memcpy with my
own implemention?
3. Why this won't happened on X86 but on ARM?

I hope get more opinions from your experts on the subject.

Thanks.

-
narke
 
S

Steven Woody

post your code!!
You have no definition for cp2() so the code above won't compile.

Sorry. You just need to remove the line which invoke cp2(). It's not
important to the problem.
I don't have a C99 compiler so I compiled this instead:
(can you miss out the "struct" keyword in C99?)

***************

#include <stdio.h>
/* #include <string> */ /* njk */
/* #include <stdint.h> */ /* njk */
#include <string.h> /* njk */
#include <assert.h>

typedef unsigned char uint8_t; /* njk */

struct Foo {
uint8_t x;
uint8_t y;
uint8_t z;
uint8_t m[3];

};

struct Bar
{
uint8_t m[3];

};

void pr(const char *title, const void *block, size_t n)
{
uint8_t *p = (uint8_t*)block; /* njk */
size_t i; /* njk */

printf("%s\n", title);

for (i = 0; i < n; ++i) /* njk */
printf("0x%02x ", *p++);

printf("\n");

}

void cp(const struct Foo *foo) /* njk */
{
struct Bar bar; /* njk */

struct Bar *p1 = &bar; /* njk */
struct Bar *p2 = (struct Bar*)(foo->m); /* njk */
pr("before: p1:", p1, 3);
pr("before: p2:", p2, 3);

memcpy(p1, p2, 3);
pr("after: p1:", p1, 3);
pr("after: p2:", p2, 3);

if (memcmp(p1, p2, 3) != 0)
printf("!!! cp is wrong\n");

}

int main()
{
struct Foo foo; /* njk */
foo.x = 1;
foo.y = 2;
foo.z = 3;
foo.m[0] = 0x40;
foo.m[1] = 0x19;
foo.m[2] = 0x21;

cp(&foo);
/* cp2(&foo); */ /* njk */
return 0;

}

***************

the lines I changes are marked /* njk */

This produced the following output

C:\bin\Debug>woody.exe
before: p1:
0x00 0x08 0x00
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x19 0x21
after: p2:
0x40 0x19 0x21

which looks ok to me

Your code works on x86 but not on ARM as I pointed out.
 
S

Steven Woody

It's the lines before that signal a problem.
------------------------------------- the minimum sample
--------------------------------------------------
1 #include <stdio.h>
2 #include <string>
3 #include <stdint.h>
4 #include <assert.h>
5
6 struct Foo {
7 uint8_t x;
8 uint8_t y;
9 uint8_t z;
10 uint8_t m[3];
11 };
12
13 struct Bar
14 {
15 uint8_t m[3];
16 };
These are completely different structs.

yes, so?
The fact you have a cast to silence a warning (or more likely
error) on incompatible types is the problem. Bar is not an array,
it is a struct containing an array.

yes, but there can't be padding at the beginning of a struct
hence Bar.m and Bar must be at the same address. Also
uint8_t is probably (almost certainly) an alias (typedef) for
unsigned char and you can safely cast *anything* to
unsigned char I'd say this pretty well had to work (do you
have a compiler where it doesn't work?)
The standard allows the conversion (if foo->m is aligned
properly),

why would foo->m not be correctly aligned? Suppose it was int
rather than uint8_t; I reckon it would *still* work (even on a
68000, which was the fussiest hardware I ever worked on)

Yes, I thing every data elements here are aligned properly, since I
don't use any option such as #program pack() to bring in misalignment
problem. That's one thing I can not understand. If only one compiler
failed, I may believe that's the compiler's cause, but you see, two
different compiler from different vendor both failed in the same
place, this makes it looks not an conincident.
 
N

Nick Keighley

you've lost some of the attributions

Sorry. You just need to remove the line which invoke cp2(). It's not
important to the problem.

so you didn't post the ACTUAL code that exhibited the fault!

I don't have a C99 compiler so I compiled this instead:
(can you miss out the "struct" keyword in C99?)

#include <stdio.h>
/* #include <string>   */        /* njk */
/* #include <stdint.h> */        /* njk */
#include <string.h>        /* njk */
#include <assert.h>
typedef unsigned char uint8_t;  /* njk */
struct Foo {
    uint8_t x;
    uint8_t y;
    uint8_t z;
    uint8_t m[3];

struct Bar
{
    uint8_t m[3];

void pr(const char *title, const void *block, size_t n)
{
    uint8_t *p = (uint8_t*)block;       /* njk */
        size_t i;                       /* njk */
    printf("%s\n", title);
    for (i = 0; i < n; ++i)        /* njk */
        printf("0x%02x ", *p++);
    printf("\n");

void cp(const struct Foo *foo)        /* njk */
{
    struct Bar bar;                   /* njk */
    struct Bar *p1 = &bar;            /* njk */
    struct Bar *p2 = (struct Bar*)(foo->m);        /* njk */
    pr("before: p1:", p1, 3);
    pr("before: p2:", p2, 3);
    memcpy(p1, p2, 3);
    pr("after: p1:", p1, 3);
    pr("after: p2:", p2, 3);
    if (memcmp(p1, p2, 3) != 0)
        printf("!!! cp is wrong\n");

int main()
{
    struct Foo foo;        /* njk */
    foo.x = 1;
    foo.y = 2;
    foo.z = 3;
    foo.m[0] = 0x40;
    foo.m[1] = 0x19;
    foo.m[2] = 0x21;
    cp(&foo);
    /* cp2(&foo); */         /* njk */
    return 0;


the lines I changes are marked /* njk */
This produced the following output
C:\bin\Debug>woody.exe
before: p1:
0x00 0x08 0x00
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x19 0x21
after: p2:
0x40 0x19 0x21
which looks ok to me

Your code works on x86 but not on ARM as I pointed out

my code exhibts the bug?
very strange, you might actually have to debug it!
 
D

Dik T. Winter

> On 22 Jul, 10:03, Steven Woody <[email protected]> wrote:
....

Note the alignment problems I give below:
> > > struct Foo {
> > > uint8_t x;
> > > uint8_t y;
> > > uint8_t z;
> > > uint8_t m[3];
> > > };

A compiler can align 'm' any way it wants to, so it may start at any byte
address. And it can require stricter alignment of the struct itself.
> > > struct Bar
> > > {
> > > uint8_t m[3];
> > > };

A compiler is allowed to require stricter alignment rules for this struct.

This is a cast that does not necessariy work as you want because of alignment
differences.
 
R

Richard Tobin

Because of the possibility of bit patterns which don't correspond to
integral values (that's real).
[/QUOTE]
I don't endorse accessing uninitialized variables. But what are bit
patterns which don't correspond to integral values? All you get is a
series of 1s and 0s and you will be getting some value. You don't care
about the value as you are deliberately using uninitialized variables.

This is only a theoretical problem, not a practical one. It's
possible for an implementation to represent integers in such a way
that not all bit patterns are possible, but all modern general-purpose
computers use 2's complement arithmetic and use all the bits, so
it does not arise.

-- Richard
 
J

jacob navia

rahul said:
I don't endorse accessing uninitialized variables. But what are bit
patterns which don't correspond to integral values?

They exist only on the minds of the regulars here...
All you get is a
series of 1s and 0s and you will be getting some value. You don't care
about the value as you are deliberately using uninitialized variables.

You are applying logic in comp.lang.c. Note that for most regulars that
is an unknown concept.
 
J

jacob navia

Martin said:
Because of the possibility of bit patterns which don't correspond to
integral values (that's real).

It is incredible how much nonsense can be posted in this group without
anyone commenting.

Mr Ambuhl is completely wrong. There isn't any single "bit pattern" that
can't be interpreted as an integer.

Proof:

Consider any bit pattern of any length. It is built from the alphabet:
{1,0}

Algorithm for finding the integer value:

1: Set the result to zero.
Set the bit counter to zero

2: Start at the right end of the number. [1]

3: If the bit at the current position is 1 add 2^counter
to the result.

4: Increment counter. If counter is less than the length of the bit
pattern go to step 3.

[1] What is the "right end" is not relevant. It is a matter of
convention. In all cases this algorithm does not depend on it
since it will equally yield an integer if we start at the "left"
end
 
R

Richard Tobin

Mr Ambuhl is completely wrong. There isn't any single "bit pattern" that
can't be interpreted as an integer.

He didn't say it can't be interpreted as an integer. The issue is
whether it corresponds to an integer on the processor in question.
This is not a problem on any machine you're likely to encounter, but
it is a theoretical possibility.

-- Richard
 
D

Dik T. Winter

>
> It is incredible how much nonsense can be posted in this group without
> anyone commenting.

Have a look wider than your narrow view. There are (or at least were)
computers where within a word some particular bit pattern corresponded
to a trap representation. 2-s complement with the range
[-int_max, int_max]
where the remaining pattern was a trap representation.
> Mr Ambuhl is completely wrong. There isn't any single "bit pattern" that
> can't be interpreted as an integer.

Of course that is true. But the question is not whether it *can* be
done, but whether the computer in fact *does* do it. And there are
computers that do not do it.
> 1: Set the result to zero.
> Set the bit counter to zero
>
> 2: Start at the right end of the number. [1]
>
> 3: If the bit at the current position is 1 add 2^counter
> to the result.
>
> 4: Increment counter. If counter is less than the length of the bit
> pattern go to step 3.
>
> [1] What is the "right end" is not relevant. It is a matter of
> convention. In all cases this algorithm does not depend on it
> since it will equally yield an integer if we start at the "left"
> end

Yes, for unsigned integers where each bit in the pattern represents a
value. Consider Honeywell machines (now Unisys, I think) with 72-bit
words where the first 8 bits or so are not value bits.
 
C

Chris Dollin

jacob said:
Mr Ambuhl is completely wrong. There isn't any single "bit pattern" that
can't be interpreted as an integer.

That's true, but irrelevant; there are bit-patterns whose interpretation
as an integer isn't given by the algorithm you present, and other
bit-patterns that don't represent integers and so for which your
integer interpretation is meaningless.

--
'It changed the future .. and it changed us.' /Babylon 5/

Hewlett-Packard Limited registered office: Cain Road,
Bracknell,
registered no: 690597 England Berks RG12
1HN
 
J

jacob navia

Chris said:
That's true, but irrelevant; there are bit-patterns whose interpretation
as an integer isn't given by the algorithm you present, and other
bit-patterns that don't represent integers and so for which your
integer interpretation is meaningless.

If you would care to see the context of the discussion before
starting you would see that the discussion was about accessing
the bits of an uninitialized integer variable. In this context
it is obvious that even if the content of the variable is random
the value is an integer!

when I write

int aFunction(void)
{
int foo;
// Function start
}

At the comment point the value in "foo" is an integer.
 
J

jacob navia

Dik said:
Yes, for unsigned integers where each bit in the pattern represents a
value. Consider Honeywell machines (now Unisys, I think) with 72-bit
words where the first 8 bits or so are not value bits.

Who cares about machines that do not exist since at least 10 years?
We are discussing a problem in a specific processor here, or at least
in current machines.

The regulars insist on their "trap representations" even if there
isn't a single machine today that uses this kind of crap.
 
N

Nick Keighley

Because of the possibility of bit patterns which don't correspond to
integral values (that's real).

It is incredible how much nonsense can be posted in this group without
anyone commenting.

Mr Ambuhl is completely wrong. There isn't any single "bit pattern" that
can't be interpreted as an integer.

Proof:

Consider any bit pattern of any length. It is built from the alphabet:
{1,0}

Algorithm for finding the integer value:

1: Set the result to zero.
    Set the bit counter to zero

2: Start at the right end of the number. [1]

3: If the bit at the current position is 1 add 2^counter
    to the result.

4: Increment counter. If counter is less than the length of the bit
    pattern go to step 3.

[1] What is the "right end" is not relevant. It is a matter of
     convention. In all cases this algorithm does not depend on it
     since it will equally yield an integer if we start at the "left"
     end

I have used a machine that had trap representations.
It was a 1's complement machine and therefore had a +0
and a -0. Reading a value that contained -0 caused a
trap to occur (I've no idea of the details but it
terminated your program).

<snip>
 

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,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top