Does UNALIGNED attribute exist in GNU C?

P

Pavel A.

Hello,

What is equivalent of __unaligned attribute in GNU C?
I've searched for some time and it seems that it just does not exist...

/*
For HP and new Microsoft compilers it works this way:
long_pointer = (some unaligned address)
long_value = (* (__unaligned long *) long_pointer );

This causes the compiler to emit code that gets the value
in some slow but sure way, but avoiding exceptions
*/

No need to suggest workarounds please...

Regards
--PA
 
R

Roger Leigh

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Pavel A. said:
What is equivalent of __unaligned attribute in GNU C?
I've searched for some time and it seems that it just does not exist...

It appears not to. That's probably because it should not be needed
unless your code is buggy. If your code is standard C, the compiler
should have aligned everything nicely for you. However, you didn't
post the code that creates the unaligned pointer.

Also:
- - Some CPUs allow unaligned access.
- - Some operating systems can transparently handle unaligned access on
systems that don't support it.


- --
Roger Leigh
Printing on GNU/Linux? http://gimp-print.sourceforge.net/
Debian GNU/Linux http://www.debian.org/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>

iD8DBQFCjOFQVcFcaSW/uEgRAu+aAKDDQqLP5PeBpB4RHt2Wn8bGN4lEXwCfQa4U
MDJleeQZG8u63b7TJZExNog=
=XMLL
-----END PGP SIGNATURE-----
 
T

those who know me have no need of my name

[fu-t set]

in comp.lang.c i read:
What is equivalent of __unaligned attribute in GNU C?
I've searched for some time and it seems that it just does not exist...

correct -- there is nothing standard.
 
P

Pavel A.

Thanks Roger for your reply.
I was looking how to implement functions like LoadUnalignedLong /
StoreUnalignedLong
(the need for these is obvious... if you get unaligned structure from file
or network etc).
So will do it anyway else.

--PA
 
C

CBFalconer

Pavel A. said:
I was looking how to implement functions like LoadUnalignedLong /
StoreUnalignedLong (the need for these is obvious... if you get
unaligned structure from file or network etc).
So will do it anyway else.

Please don't toppost. It is not acceptable in c.l.c. See sig
below.

There is no such need. How do you get an "unaligned structure"?
All you can receive from a network of file is some gestalt of
bytes, which should have a defined relationship to a field in a
structure. The details of a structure are not valid outside the
system that created it, and can be freely changed, even by a
compiler upgrade.

--
Some informative links:
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
 
R

Roger Leigh

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


[Please don't top-post]
I was looking how to implement functions like LoadUnalignedLong /
StoreUnalignedLong
(the need for these is obvious... if you get unaligned structure from file
or network etc).

I've never seen those non-standard functions. Due to the hideous
naming, I assume they come from MS Windows?

The need for them aside, you could always memcpy to a known aligned
memory location before reading/writing. It should be fairly cheap,
but still less than ideal. If your software is properly written, you
simply won't have alignment issues.


- --
Roger Leigh
Printing on GNU/Linux? http://gimp-print.sourceforge.net/
Debian GNU/Linux http://www.debian.org/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>

iD8DBQFCkMXUVcFcaSW/uEgRAq1GAJ9GYG9AuzlZcETFP5rGatDYmrDu7gCfX20d
TKSkV3oERlS9U9DF21grf60=
=BlzH
-----END PGP SIGNATURE-----
 
R

Richard Bos

Roger Leigh said:
[Please don't top-post]
I was looking how to implement functions like LoadUnalignedLong /
StoreUnalignedLong
(the need for these is obvious... if you get unaligned structure from file
or network etc).

I've never seen those non-standard functions. Due to the hideous
naming, I assume they come from MS Windows?

You'd say so, but AFAICT not even that.
The need for them aside, you could always memcpy to a known aligned
memory location before reading/writing. It should be fairly cheap,
but still less than ideal.

If you have a halfway decently defined network or file format, you won't
be reading directly into your objects if that's impossible. You'll be
manipulating the byte _values_, rather than their representations in
memory.

Richard
 
T

Thomas Carter

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



It appears not to. That's probably because it should not be needed
unless your code is buggy.

I respectfully disagree: In networking applications, for performance
reasons (to avoid data copying) one must frequently deal with portions of
buffers that are not correctly aligned.
 
T

Tim Prince

Thomas said:
I respectfully disagree: In networking applications, for performance
reasons (to avoid data copying) one must frequently deal with portions of
buffers that are not correctly aligned.
That depends on what you mean by unaligned. The C standards don't allow
the kinds of type punning which would place, for example, a long long
int at an odd short int address. Code which does so is non-portable.
Even Microsoft C, in the newer 64-bit versions, gets away from the
requirement to maximize support of 64-bit data located on any 32-bit
boundary, but this NG is about standard C.
If you mean, for example, a string of ints starting at any legal int
boundary, that's the default, and doesn't require any attribute or
pragma. gcc does support specification of higher alignments, such as
those which would allow the use of aligned pair load and store instructions.
 
L

Lawrence Kirby

I respectfully disagree: In networking applications, for performance
reasons (to avoid data copying) one must frequently deal with portions of
buffers that are not correctly aligned.

This is a generalisation which is the for most part wrong. Not totally
wrong but still mostly wrong. However a discussion of why is beyond the
scope of comp.lang.c (i.e. where I am reading this).

Lawrence
 
T

Thomas Carter

This is a generalisation which is the for most part wrong. Not totally
wrong but still mostly wrong.

typedef unsigned int UInt32 ;
UInt32 * x = (UInt32 *) malloc(10) ;
UInt32 * p = x + 1 ;

f(p) ;

f() is now dealing with an unaligned buffer. Lots of examples similar to
this can be found e.g. in the OpenSSL library.

That's what I meant.
 
P

Paul Pluzhnikov

Thomas Carter said:
typedef unsigned int UInt32 ;
UInt32 * x = (UInt32 *) malloc(10) ;
UInt32 * p = x + 1 ;

f(p) ;

f() is now dealing with an unaligned buffer.

No, it isn't. Perhaps you need a refresher on how 'C' pointers work?

Cheers,
 
M

Maurizio Loreti

Thomas Carter said:
typedef unsigned int UInt32 ;
UInt32 * x = (UInt32 *) malloc(10) ;
UInt32 * p = x + 1 ;

f(p) ;

f() is now dealing with an unaligned buffer. Lots of examples similar to

1) Wrong. p will point to x + sizeof(UInt32) .
2) If UInt32 means "unsigned int 32 bits long" there is no guarantee
that a plain "unsigned int" is 32 bits long. Actually, with my
compiler & platform of choice, it is 64 bits long.
 
M

Martin Ambuhl

Thomas said:
typedef unsigned int UInt32 ;
UInt32 * x = (UInt32 *) malloc(10) ;
UInt32 * p = x + 1 ;

f(p) ;

f() is now dealing with an unaligned buffer.

No it isn't.

Go over the following carefully, testing it with your implementation.
Then go back to your elementary C text and learn how pointer arithmetic
works.

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

#define MAGICNUMBER 10

int main(void)
{
unsigned int *x = malloc(MAGICNUMBER);
unsigned int *p = x + 1;
unsigned i;
if (!x) {
fprintf(stderr, "The allocation of x failed.\n"
"Bailing out ...\n");
exit(EXIT_FAILURE);
}
printf("The buffer x is of %u unsigned ints.\n"
"Each is properly aligned.\n"
"The addresses x are:\n", MAGICNUMBER);
for (i = 0; i < MAGICNUMBER; i++)
printf(" &x[%u] = %p, x+%u = %p\n",
i, (void *) &x, i, (void *) (x + i));
printf("\nAnd p, initialized to point at x + 1, has the\n"
"same value as the correctly aligned &x[1] above:\n"
" p = %p\n", (void *) p);
free(x);
return 0;
}


[output on my implementation]
The buffer x is of 10 unsigned ints.
Each is properly aligned.
The addresses x are:
&x[0] = 20d50, x+0 = 20d50
&x[1] = 20d54, x+1 = 20d54
&x[2] = 20d58, x+2 = 20d58
&x[3] = 20d5c, x+3 = 20d5c
&x[4] = 20d60, x+4 = 20d60
&x[5] = 20d64, x+5 = 20d64
&x[6] = 20d68, x+6 = 20d68
&x[7] = 20d6c, x+7 = 20d6c
&x[8] = 20d70, x+8 = 20d70
&x[9] = 20d74, x+9 = 20d74

And p, initialized to point at x + 1, has the
same value as the correctly aligned &x[1] above:
p = 20d54
 
C

Chris Torek

#define MAGICNUMBER 10

[the magic number came from elsewhere; all Martin Ambuhl did was
move it to a #define.]
unsigned int *x = malloc(MAGICNUMBER); ....
if (!x) {
fprintf(stderr, "The allocation of x failed.\n"
"Bailing out ...\n");
exit(EXIT_FAILURE);
}
printf("The buffer x is of %u unsigned ints.\n"
"Each is properly aligned.\n"
"The addresses x are:\n", MAGICNUMBER);


It is worth noting here that "x" now points to ten *bytes*, not
ten "unsigned int"s. If sizeof(unsigned int) is 2, this is five
"unsigned int"s; if sizeof(unsigned int) is 4, this is two with
two leftover bytes; and if sizeof(unsigned int) is 8, this is one
unsigned int, with two leftover bytes again. Only in the case when
sizeof(unsigned int) == 1 -- which is probably not supported by
GCC, although this does occur on some standalone implementations
-- is it ten unsigned ints.

Of course, it is true that sometimes one must deal with "misaligned"
memory, in places like network drivers (Ethernet headers are,
inconveniently, 14 bytes instead of 16). But there are ways to
deal with this without ever using a single line of nonstandard C.
Sometimes -- perhaps even "often" or "usually" -- the portability
gain of doing byte-at-a-time arithmetic to work with 16 and 32 bit
values outweighs the (usually tiny) performance gain one can obtain
using a compiler's "special features" for accessing unaligned value.
(The only way to find out for sure, of course, is to do both,
and measure.)
 
T

Thomas Carter

No, it isn't. Perhaps you need a refresher on how 'C' pointers work?

I actually forgot the definition of f :-(

void f(UInt32 * p)
{
UInt64 * q = (UInt64 *) p ;

*q = 1234ULL ;

return ;
}

with UInt64 typedef'd in the obvious way. Isn't there an unaligned access
on q now?
 
P

Paul Pluzhnikov

Thomas Carter said:
void f(UInt32 * p)
{
UInt64 * q = (UInt64 *) p ;
*q = 1234ULL ;
return ;
}

with UInt64 typedef'd in the obvious way. Isn't there an unaligned access
on q now?

Yes, now there is. However, that code is now wrong, or at least
assumes that the caller passes a pointer to UInt64 without requiring
the caller to do so (which is a bad idea(TM)).

You claimed that such code is common (it isn't and it's obviously
broken) and that you've found such code in OpenSSL (did you?).

Cheers,
 
T

Thomas Carter

Yes, now there is. However, that code is now wrong, or at least
assumes that the caller passes a pointer to UInt64 without requiring
the caller to do so (which is a bad idea(TM)).

You claimed that such code is common (it isn't and it's obviously
broken) and that you've found such code in OpenSSL (did you?).

I admit to being carried away in my assessment here :-( My apologies.
Here is the case I have in mind:

A certain library uses char * throughout, with arbitrary alignments.
Since a char will be 1 byte long (at least, in general, I believe) such
pointers can have any alignment. Now if we have a low-level function that,
for performance reasons, and for a particular architecture, manipulates
unsigned int * as input, then we have a potential problem.

The code above, while obviously wrong, attempts to illustrate such case.
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top