Question about __attribute__((packed))

Programming, for all ages and all languages.
Post Reply
psychobeagle12
Member
Member
Posts: 41
Joined: Wed Oct 26, 2011 9:31 am

Question about __attribute__((packed))

Post by psychobeagle12 »

Hey guys, I have a question. I am writing a FAT16 filesystem for my OS right now, and the structure I created to hold the filesystem information obviously did not work correctly without __attribute__((packed)). So I started reading into what this statement actually does since I realized I really didn't understand it well. As I was looking, I found lots of information that said that __attribute__((packed)) actually causes code to slow down due to misaligned accesses. So the question is, how do I know which structs I can pack, and which I can't? Also, does anyone have a suggestion how I may implement the filesystem driver without the packing attribute? I am basically using a FAT16-formatted ramdisk loaded by GRUB for loading the drivers necessary to start the system, and so I did something like this:

Code: Select all

static uint8_t *ramdisk_data;
struct fat16_bpb bios_blk;

initrd_initialize (void *ramfs) {

	ramdisk_data = (uint8_t *) ramfs;
	struct fat16_bpb *bios_blk_ptr = (&bios_blk);

	memcpy ((void *)bios_blk_ptr, (void *) ramdisk_data, sizeof (struct fat16_bpb));
}
I guess if I was going to ask OS-specific questions I should have posted in the OS Development thread... if that causes a problem, can this be moved? This is just a genuine curiosity for me. Thanks!
My i386-based kernel: https://github.com/bmelikant/missy-kernel
Picking a name for my kernel was harder than picking my wife, so I just used her name until I decide!
shmx
Member
Member
Posts: 68
Joined: Sat Jan 16, 2016 10:43 am

Re: Question about __attribute__((packed))

Post by shmx »

psychobeagle12 wrote:__attribute__((packed))
better use pragma pack
psychobeagle12 wrote:So the question is, how do I know which structs I can pack, and which I can't?
I did not understand the question.
psychobeagle12 wrote:Also, does anyone have a suggestion how I may implement the filesystem driver without the packing attribute?
Manually calculate offset and use typecast.
User avatar
b.zaar
Member
Member
Posts: 294
Joined: Wed May 21, 2008 4:33 am
Location: Mars MTC +6:00
Contact:

Re: Question about __attribute__((packed))

Post by b.zaar »

psychobeagle12 wrote: how do I know which structs I can pack, and which I can't?
You always need to pack a structure when the bytes are written in a set size and order. This almost always applies to file systems because the structure in memory is exactly the same as the structure on the disk. It will also apply to any structures you use with BIOS or VBE functions.

You don't need to pack a structure if it's optimised for speed and byte alignment, this could be for a structure used by a page/memory allocator. You can use unpacked structures if you don't plan to save the structures to long term storage.
"God! Not Unix" - Richard Stallman

Website: venom Dev
OS project: venom OS
Hexadecimal Editor: hexed
psychobeagle12
Member
Member
Posts: 41
Joined: Wed Oct 26, 2011 9:31 am

Re: Question about __attribute__((packed))

Post by psychobeagle12 »

how do I know which structs I can pack, and which I can't?
Sorry, this question should have read "Which structs I SHOULD pack and which I SHOULDN'T pack." I would suppose that, as I am developing OS code, that anything architecture-dependent is safe to be a packed struct. But... I have read that unaligned data access causes issues on SPARC machines. Not that I ever plan to develop for one, but if I wrote my fat16 driver with packed structs on such a machine, would I not cause myself headaches? That is mostly my question; when is it ok to use packed structs and when should I avoid them like the plague?
My i386-based kernel: https://github.com/bmelikant/missy-kernel
Picking a name for my kernel was harder than picking my wife, so I just used her name until I decide!
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Question about __attribute__((packed))

Post by FallenAvatar »

shmx wrote:
psychobeagle12 wrote:__attribute__((packed))
better use pragma pack
#pragma pack is a MSVC specific preprocessor macro. One that GCC happens to support for compatibility, but for gcc you should use their specific macros. Please don't post unles you actually know/understand what you are saying.

- Monk
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Question about __attribute__((packed))

Post by Combuster »

psychobeagle12 wrote:when is it ok to use packed structs and when should I avoid them like the plague?
If you want to be platform independent, never use packing and never read directly into a structure in the first place. Instead do proper endian (and float format) conversion from an uint8_t array. This is the obviously also the purist's way.

CPU structures are platform-specific by their very name, so you have a legitimate excuse to use packing here. If you want to cheat like most people, you can use packing for I/O only if you know you're never going to run into platform-specifics or don't care about that. If neither is the case, packing is always the worse solution.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
shmx
Member
Member
Posts: 68
Joined: Sat Jan 16, 2016 10:43 am

Re: Question about __attribute__((packed))

Post by shmx »

tjmonk15 wrote:#pragma pack is a MSVC specific preprocessor macro.
__attribute__((packed)) is only supported by GCC. :)
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: Question about __attribute__((packed))

Post by Roman »

Who cares about MSVC? Meanwhile they couldn't even support modern C themselves and decided to use clang for it. If portability is wanted, it's possible to use something like this:

Code: Select all

#ifdef _MSC_VER
#define PACKED_STRUCT(n, c) __pragma(pack(push)) struct n {c} __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_STRUCT(n, c) struct n __attribute__((packed)) {c}
#else
#error "This compiler is not supported."
#endif
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Question about __attribute__((packed))

Post by onlyonemac »

It's generally best to leave structures un-packed unless it is important that the fields do not have any padding in-between them. In this case, you're using a structure to represent a FAT filesystem node, so you don't want padding added to the structure because then won't match the layout of the data that has been read from disk.

Short answer: structures that are used internally by your operating system usually don't need packing because the exact layout of the fields doesn't matter; structures that are used to refer to formatted data obtained from or intended to be used by external entities (CPU page tables, filesystems, etc.) should be packed because the exact layout of the fields is important.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Post Reply