Re: [releng_6 tinderbox] failure on sparc64/sparc64



On 2006-02-13 21:05, "M. Warner Losh" <imp@xxxxxxxxxx> wrote:
In message: <20060214083530.K22079@xxxxxxxxxxxxxxx>
Bruce Evans <bde@xxxxxxxxxxx> writes:
: > It won't matter given how I'm going to fix this problem...
:
: Why not just access the object as an array of unsigned chars as someone
: wrote? Write it out 1 unsigned char at a time for the simple version.
: This avoids the complications.

Because it has to be fed to the hardware 4 bytes at a time.

That's still possible, using an intermediate unsigned char buffer, or if
that's too much to ask (i.e. because keeping a duplicate copy of the
'foo' structure is a waste of memory), using a 4-byte scratch buffer and
iterating over an (unsigned char *) pointer through `foo'.

I think, that given a `foo' struct defined as:

struct foo {
uint32_t a;
uint16_t b;
uint16_t c;
uint8_t d;
uint8_t e;
};

You are always allowed to use an (unsigned char *) pointer to iterate
through its bytes, as in:

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

struct foo {
uint32_t a;
uint16_t b;
uint16_t c;
uint8_t d;
uint8_t e;
};

int
main(void)
{
struct foo foo;
size_t k;

memset(&foo, 0, sizeof(foo));
foo.a = 1;
foo.b = 2;
foo.c = 3;
foo.d = 4;
foo.e = 5;

for (k = 0; k < sizeof(foo); k++)
printf("%s%02x", k ? " " : "", *((unsigned char *)&foo + k));
putchar('\n');
return EXIT_SUCCESS;
}

This prints padding bytes correctly here, even with:

$ CFLAGS='-std=c99 -pedantic' make WARNS=6 foo.c
[...]
$ ./foo
01 00 00 00 02 00 03 00 04 05 00 00
$

Then, if there's a 4-byte constraint, a single uint32_t can be used as a
'buffer':

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

struct foo {
uint32_t a;
uint16_t b;
uint16_t c;
uint8_t d;
uint8_t e;
};

int
main(void)
{
struct foo foo;
size_t k, nbytes;
uint32_t x;

memset(&foo, 0, sizeof(foo));
foo.a = 1;
foo.b = 2;
foo.c = 3;
foo.d = 4;
foo.e = 5;

for (k = 0; k < sizeof(foo); k++)
printf("%s%02x", k ? " " : "", *((unsigned char *)&foo + k));
putchar('\n');

for (k = 0; k < sizeof(foo); k += 4) {
nbytes = sizeof(uint32_t);
if (sizeof(foo) - k < nbytes) {
nbytes = sizeof(foo) - k;
memset(&x, 0, sizeof(x));
}
memcpy(&x, ((unsigned char *)&foo + k), nbytes);
printf("%s%zdb/%08x", k ? " " : "", nbytes, x);
}
putchar('\n');
return EXIT_SUCCESS;
}

and it seems to work as expected here on a little-endian machine:

$ ./foo
01 00 00 00 02 00 03 00 04 05 00 00
4b/00000001 4b/00030002 4b/00000504

This probably works much better than trying to cast the original into an
array of uint32_t objects too :)

_______________________________________________
freebsd-arch@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "freebsd-arch-unsubscribe@xxxxxxxxxxx"



Relevant Pages

  • Re: struct enumerating types
    ... typedef int bool; ... conversion argument for a pointer to an unsigned char, ... }; struct foo foo_obj; ...
    (comp.lang.c)
  • Re: Coding style survey
    ... rather than let it sit on your disk misleading future programmers. ... typedef struct foo foo; ... seriously concerned that 'unsigned char' may change in future versions, ...
    (comp.lang.c)
  • Re: Q: volatile struct elements or entire struct?
    ... > unsigned char command; ... > volatile unsigned char command; ... Reading email is like searching for food in the garbage, ...
    (comp.lang.c)
  • Re: pointer addition and structs
    ... > int i; ... unsigned char *p = pfoo + offsetof ... to char or unsigned char. ...
    (microsoft.public.vc.language)
  • Re: pointer addition and structs
    ... >>Is there a way using pointer addition to access struct members? ... > struct foo x; ... > to char or unsigned char. ...
    (microsoft.public.vc.language)