LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   What's this: __attribute__((packed)) (https://www.linuxquestions.org/questions/programming-9/what%27s-this-__attribute__-packed-193570/)

johnsfine 09-11-2012 09:58 AM

Quote:

Originally Posted by rstewart (Post 4777728)
Why not use the pack pragma to set the alignment around the structure? IE:

I have seen some very convincing discussions by gcc experts on why #pragma is worse than __attribute__ for all the things that can be accomplished either way.

I don't remember the details well enough to repeat any of it convincingly, but I was convinced when I read it.

In real projects, it is a lot easier to wrap __attribute__ into a preprocessor macro (to make it properly conditional on the compiler/architecture in a semi portable project) than to do that with #pragma

Quote:

Originally Posted by rajesh180186 (Post 4777447)
struct s2 {
char a;
int i __attribute__ ((packed));
char b;
int i1;
};

I can't tell whether any of the answers to the reopening of this thread directly answer the question (vs. assume the answer). So my version of that answer is:

In the quoted code, the packed attribute applies only to i and not to i1
Other methods of specifying packed (appearing elsewhere in this thread) apply the packed attribute to the entire struct.

Quote:

Originally Posted by NevemTeve (Post 4777480)
But please note that this packed stuff:

- is a non-standard extension

That is important to understand when using it.

Quote:

- slows down the processing
That is only sometimes true at all and is rarely significant.

Quote:

- should be avoided
That claim should only be made about fundamentally flawed features, which this certainly is not. This is a very useful extension to C++, which should be used where appropriate. Like any other advanced language feature, it should not be scattered into your code without understanding or valid purpose. But that certainly doesn't mean it should be avoided.

theNbomr 09-13-2012 10:03 AM

Quote:

Originally Posted by NevemTeve (Post 4777480)
But please note that this packed stuff:
- should be avoided

I'd love to avoid it; it's a pain in the pants. What is your recommended alternative where data structures are part of a communications protocol that must be implemented in a consistent cross-platform manner?
--- rod.

NevemTeve 09-13-2012 10:27 AM

Code:

typedef struct network_format {
  char aChar;
  int8_t anInt [4]; /* determine byte-order */
} network_format;

typedef struct usable_format {
  char aChar;
  int32_t anInt;
} usable_format;

usable_from_network (usable_format *into, const network_format *from)
{
    into->aChar = from->aChar;
    into->anInt = big2hostl (*(int32_t *)from->anInt); /* pick */
    into->anInt = lit2hostl (*(int32_t *)from->anInt); /* one */
}

network_from_usable (network_format *into, const usable_format *from)
{
    into->aChar = from->aChar;
    *(int32_t *)into->anInt = host2bigl (from->anInt); /* pick */
    *(int32_t *)into->anInt = host2litl (from->anInt); /* one */
}


theNbomr 09-13-2012 12:35 PM

I agree that your suggestion will probably work with respect to packing/alignment (most of your suggestion seems to relate to byte-ordering; a different but related subject) on most architectures, there is nothing to ensure that the packing of the structure will necessarily be the same as a deliberately packed structure. Without the directive not to, padding bytes may be added in any part of the struct. In practice, AFAIK, this would rarely be done between char type elements, but again, this is not guaranteed. Nested structures make the problem even more difficult.
If the solution comes down to breaking every structure element into its respective char-sized elements, then I see the solution as much worse than the problem. I would say that the __attribute__((packed)) directive preserves the purpose of the C struct, by allowing an expression that plainly reflects the nature of the data. Unfortunately, it forces us to know when it is necessary, and embeds architecture-specific features into our source code.
--- rod.

NevemTeve 09-13-2012 11:08 PM

Sorry, from your answer I couldn't decide if my answer helped or not. Maybe I should summarize it in plain text: define a special structure only for the network traffic, in this structure every data-element that isn't aligned on its natural alignment (for elementary types it is an offset that is divisible with their size) are to be replaced with char-arrays. To convert from/to this special structure, you have to write conversion functions.

PS: The opposite problem may arise if the network protocol demands gaps between the fields that your compiler may or may not provide; you can add 'char unused_nnn [gapsize]' fields to be sure.

PPS: And obviously types short/int/long long mustn't be used in the network structure, int16_t/int32_t/int64_t are you friends.


All times are GMT -5. The time now is 05:34 AM.