Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #10181 > unrolled thread

C Macro define contain symbol #

Started byWang WolfLouis <wolflouiswang@gmail.com>
First post2011-09-13 02:47 -0700
Last post2011-09-13 16:54 -0400
Articles 20 — 15 participants

Back to article view | Back to comp.lang.c


Contents

  C Macro define contain symbol # Wang WolfLouis <wolflouiswang@gmail.com> - 2011-09-13 02:47 -0700
    Re: C Macro define contain symbol # Noob <root@127.0.0.1> - 2011-09-13 13:14 +0200
    Re: C Macro define contain symbol # Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-09-13 07:55 -0400
      Re: C Macro define contain symbol # Roberto Waltman <usenet@rwaltman.com> - 2011-09-13 08:24 -0400
        Re: C Macro define contain symbol # Keith Thompson <kst-u@mib.org> - 2011-09-13 11:12 -0700
          Re: C Macro define contain symbol # Keith Thompson <kst-u@mib.org> - 2011-09-13 20:19 -0700
            Re: C Macro define contain symbol # Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-16 00:43 +0300
              Re: C Macro define contain symbol # Keith Thompson <kst-u@mib.org> - 2011-09-15 18:34 -0700
          Re: C Macro define contain symbol # Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-13 22:51 -0400
            Re: C Macro define contain symbol # Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-14 12:16 +0100
        Re: C Macro define contain symbol # tom st denis <tom@iahu.ca> - 2011-09-13 11:20 -0700
        Re: C Macro define contain symbol # Ian Collins <ian-news@hotmail.com> - 2011-09-14 07:55 +1200
        Re: C Macro define contain symbol # Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-09-14 07:58 -0400
          Re: C Macro define contain symbol # Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-09-14 14:54 +0000
        Re: C Macro define contain symbol # Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-16 00:34 +0300
          Re: C Macro define contain symbol # Nobody <nobody@nowhere.com> - 2011-09-16 12:07 +0100
      Re: C Macro define contain symbol # "BartC" <bc@freeuk.com> - 2011-09-13 13:50 +0100
        Re: C Macro define contain symbol # James Kuyper <jameskuyper@verizon.net> - 2011-09-13 08:59 -0400
          Re: C Macro define contain symbol # Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-09-14 15:02 +0000
    Re: C Macro define contain symbol # Kenneth Brody <kenbrody@spamcop.net> - 2011-09-13 16:54 -0400

#10181 — C Macro define contain symbol #

FromWang WolfLouis <wolflouiswang@gmail.com>
Date2011-09-13 02:47 -0700
SubjectC Macro define contain symbol #
Message-ID<c351b443-5581-4db0-8760-3f117eebce77@x32g2000prf.googlegroups.com>
Dear all,

     #define WIN32_PACKED #pragma pack(1)
I want to define a Macro to simpilify and unify my code for Windows
and Unix. The special character # is the key. anybody can give me some
suggesstion? Thanks.

[toc] | [next] | [standalone]


#10183

FromNoob <root@127.0.0.1>
Date2011-09-13 13:14 +0200
Message-ID<j4nduf$a6v$1@dont-email.me>
In reply to#10181
Wang WolfLouis wrote:

>      #define WIN32_PACKED #pragma pack(1)
> I want to define a Macro to simplify and unify my code for Windows
> and Unix. The special character # is the key. anybody can give me some
> suggestion?

http://catb.org/~esr/faqs/smart-questions.html

$ cat cpp.c
#define WIN32_PACKED #pragma pack(1)
WIN32_PACKED

$ gcc -E cpp.c
# 1 "cpp.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "cpp.c"

 #pragma pack(1)

[toc] | [prev] | [next] | [standalone]


#10185

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-09-13 07:55 -0400
Message-ID<j4ngch$oqb$1@dont-email.me>
In reply to#10181
On 9/13/2011 5:47 AM, Wang WolfLouis wrote:
> Dear all,
>
>       #define WIN32_PACKED #pragma pack(1)
> I want to define a Macro to simpilify and unify my code for Windows
> and Unix. The special character # is the key. anybody can give me some
> suggesstion? Thanks.

     Can't be done this way.  For one thing, the # in the macro's
definition is an operator, with a different meaning than it would
have elsewhere.  For another, the Standard says (6.10.3.4p3)

	The resulting completely macro-replaced preprocessing token
	sequence is not processed as a preprocessing directive even
	if it resembles one [...]

So a macro expansion cannot generate a preprocessing directive.

     However, the same paragraph continues

	[...] but all pragma unary operator expressions within
	it are then processed as specified in 6.10.9 below.

The "C99" version of the Standard introduced a _Pragma operator to
help with exactly this situation.  You could try

	#define WIN32_PACKED _Pragma("pack(1)")

to get the effect you want.  "Try," I said, because _Pragma was new
in C99, and I have heard that Microsoft's C implementations (which
it looks like you might be using) are mostly stuck in the C90 era,
before _Pragma came along.  It's worth a try, though.

     ... if you really think you need "pack(1)".  Usually (not always,
but usually) that's the sign of a short-term hack leading to long-
term headaches.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#10187

FromRoberto Waltman <usenet@rwaltman.com>
Date2011-09-13 08:24 -0400
Message-ID<92iu67h2ki8sgm1u9bvpfk8qu3hfremcoo@4ax.com>
In reply to#10185
Eric Sosman wrote:
>     ... if you really think you need "pack(1)".  Usually (not always,
>but usually) that's the sign of a short-term hack leading to long-
>term headaches.

Not when you are dealing with communication protocols, mapping
hardware control registers in embedded systems, etc.
Without the "pack" pragmas, instead of having a structure that
directly overlaps the desired memory layout, the packing/unpacking
would have to be in higher level software.
This is a much needed functionality, and I am puzzled why it never
became part of the language standard, instead of a not always
available compiler extension.
Even Pascal had packed records.
--
Roberto Waltman

[ Please reply to the group,
  return address is invalid ]

[toc] | [prev] | [next] | [standalone]


#10197

FromKeith Thompson <kst-u@mib.org>
Date2011-09-13 11:12 -0700
Message-ID<lnbouob9av.fsf@nuthaus.mib.org>
In reply to#10187
Roberto Waltman <usenet@rwaltman.com> writes:
> Eric Sosman wrote:
>>     ... if you really think you need "pack(1)".  Usually (not always,
>>but usually) that's the sign of a short-term hack leading to long-
>>term headaches.
>
> Not when you are dealing with communication protocols, mapping
> hardware control registers in embedded systems, etc.
> Without the "pack" pragmas, instead of having a structure that
> directly overlaps the desired memory layout, the packing/unpacking
> would have to be in higher level software.
> This is a much needed functionality, and I am puzzled why it never
> became part of the language standard, instead of a not always
> available compiler extension.
> Even Pascal had packed records.

Yes, but Pascal packed records, as I recall, are merely a hint to the
compiler that space should be minimized.  They're not necessarily
suitable for matching a specific externally imposed layout.

One example of a problem that would have to be solved:

    struct foo {
        char c;
        int i;
    };
    #pragma pack(struct foo) /* or whatever the syntax is */

    void some_func(int *p);

    struct foo obj;
    some_func(&obj.i);

I've worked on systems where an int* cannot contain an address that
isn't word-aligned.  Do you forbid taking the address of a member of a
packed struct?

Ada has "pragma Pack", which is a hint to minimize space, *and* an
elaborate system of representation clauses that let you specify layout
down to the bit level.

C has unsigned char[], memcpy(), and bit masks.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#10208

FromKeith Thompson <kst-u@mib.org>
Date2011-09-13 20:19 -0700
Message-ID<ln7h5bbyjw.fsf@nuthaus.mib.org>
In reply to#10197
"BartC" <bc@freeuk.com> writes:
> "Keith Thompson" <kst-u@mib.org> wrote in message 
> news:lnbouob9av.fsf@nuthaus.mib.org...
>> Roberto Waltman <usenet@rwaltman.com> writes:
>
>>> Even Pascal had packed records.
>>
>> Yes, but Pascal packed records, as I recall, are merely a hint to the
>> compiler that space should be minimized.  They're not necessarily
>> suitable for matching a specific externally imposed layout.
>>
>> One example of a problem that would have to be solved:
>>
>>    struct foo {
>>        char c;
>>        int i;
>>    };
>>    #pragma pack(struct foo) /* or whatever the syntax is */
>>
>>    void some_func(int *p);
>>
>>    struct foo obj;
>>    some_func(&obj.i);
>
>> I've worked on systems where an int* cannot contain an address that
>> isn't word-aligned.  Do you forbid taking the address of a member of a
>> packed struct?
>
> Suppose *all* addresses have to be word-aligned (which used to be quite 
> common). Then you'd have the same problem with:
>
>     struct foo {
>         char c[2];
>         int i;
>     };
>
> and trying to take the address of c[1] (or even just trying to access it). 
> (This assumes you don't just make char and int the same size.)

You're making assumptions that make a conforming C implementation
impossible, unless a "word" is 1 byte.  c[1] must have a valid address.
That address is of type char*, which may or may not have the same
representation as an int*.  On the system I was referring to, a char*
can old a byte-aligned address, but an int* can only hold a word-aligned
address.

(The system was the Cray T90.  The word size was 64 bits, and there was
no hardware support for byte addressing.  Byte addresses were
implemented in software by storing an offset in the high-order 3 bits of
a 64-bit pointer.)

> The Pascal 'packed' directive perhaps *was* an instructive to pack things 
> more tightly than hardware considerations would normally dictate.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#10295

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-09-16 00:43 +0300
Message-ID<87sjnx4h2e.fsf@bazspaz.fatphil.org>
In reply to#10208
Keith Thompson <kst-u@mib.org> writes:
> (The system was the Cray T90.  The word size was 64 bits, and there was
> no hardware support for byte addressing.  Byte addresses were
> implemented in software by storing an offset in the high-order 3 bits of
> a 64-bit pointer.)

I presume the Cray T3E is the similar, as that was based on DEC's
21164 which only had word (64 bit) memory access, and then arbitrary
byte shuffle/extraction operations to extract the byte you're
interested in. That used to throw a few bubbles in the pipeline, so
you didn't do it unless you absolutely needed it.

Not that I ever used mine (21164, not T3E) for anything
apart from FP stuff, so I'm not speaking from experience,
just hearsay.

Phil
-- 
"Religion is what keeps the poor from murdering the rich."
-- Napoleon

[toc] | [prev] | [next] | [standalone]


#10305

FromKeith Thompson <kst-u@mib.org>
Date2011-09-15 18:34 -0700
Message-ID<lnmxe58e40.fsf@nuthaus.mib.org>
In reply to#10295
Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> (The system was the Cray T90.  The word size was 64 bits, and there was
>> no hardware support for byte addressing.  Byte addresses were
>> implemented in software by storing an offset in the high-order 3 bits of
>> a 64-bit pointer.)
>
> I presume the Cray T3E is the similar, as that was based on DEC's
> 21164 which only had word (64 bit) memory access, and then arbitrary
> byte shuffle/extraction operations to extract the byte you're
> interested in. That used to throw a few bubbles in the pipeline, so
> you didn't do it unless you absolutely needed it.
>
> Not that I ever used mine (21164, not T3E) for anything
> apart from FP stuff, so I'm not speaking from experience,
> just hearsay.

No, it wasn't (I worked on both).  The T3E used the DEC Alpha.
The C compiler had 8-bit char, 32-bit short, and 64-bit int and long.
It may have required extra work to access bytes (I never looked into
it that deeply, but machine addresses pointed to bytes, not words,
so there was no special format for void* vs. int*.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#10211

FromRichard Damon <news.x.richarddamon@xoxy.net>
Date2011-09-13 22:51 -0400
Message-ID<j4p4ri$u8a$1@dont-email.me>
In reply to#10197
On 9/13/11 7:52 PM, BartC wrote:
>
> Suppose *all* addresses have to be word-aligned (which used to be quite
> common). Then you'd have the same problem with:
>
> struct foo {
> char c[2];
> int i;
> };
>
> and trying to take the address of c[1] (or even just trying to access
> it). (This assumes you don't just make char and int the same size.)
>
> The Pascal 'packed' directive perhaps *was* an instructive to pack
> things more tightly than hardware considerations would normally dictate.
>

If you can only take address of word aligned objects then the compiler 
can either make char the size of a word, even if this is more that the 
"expected" 8 bits, or it can make a char* (and void*) pointer bigger by 
adding an extra word to it that tells it which "byte" within the word to 
access and adds code to all char accesses to use that extra information. 
I have seen both done on systems I have programed for, and both can trip 
up people who are used to "normal systems", and who assume CHAR_BIT = 8 
and sizeof(int*) == sizeof(char*)

[toc] | [prev] | [next] | [standalone]


#10215

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-09-14 12:16 +0100
Message-ID<0.aaa4f602fe520d833c9f.20110914121651BST.871uvj1iho.fsf@bsb.me.uk>
In reply to#10211
Richard Damon <news.x.richarddamon@xoxy.net> writes:

> On 9/13/11 7:52 PM, BartC wrote:
>>
>> Suppose *all* addresses have to be word-aligned (which used to be quite
>> common). Then you'd have the same problem with:
>>
>> struct foo {
>> char c[2];
>> int i;
>> };
>>
>> and trying to take the address of c[1] (or even just trying to access
>> it). (This assumes you don't just make char and int the same size.)
>>
>> The Pascal 'packed' directive perhaps *was* an instructive to pack
>> things more tightly than hardware considerations would normally dictate.
>>
>
> If you can only take address of word aligned objects then the compiler
> can either make char the size of a word, even if this is more that the
> "expected" 8 bits, or it can make a char* (and void*) pointer bigger
> by adding an extra word to it that tells it which "byte" within the
> word to access and adds code to all char accesses to use that extra
> information. I have seen both done on systems I have programed for,
> and both can trip up people who are used to "normal systems", and who
> assume CHAR_BIT = 8 and sizeof(int*) == sizeof(char*)

Another strategy I've seen is to use unused bits of the address to
denote which char from the word a char * (or void *) points to.  These
can be high bits or low bits.  If high bits are used, bytes addresses
need to be masked, if low bits are used they need to be shifted.

Non-portable code is something of a self-fulfilling prophesy.  Machines
with interesting architectures are very likely to fail because there is
so much code that is hard to run on them.  Chip designers have one hand
tied behind their backs.  Odd since software is supposed to be the
flexible member of the partnership.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#10198

Fromtom st denis <tom@iahu.ca>
Date2011-09-13 11:20 -0700
Message-ID<6f8bff1c-4137-4116-870f-55d181f70500@d12g2000vba.googlegroups.com>
In reply to#10187
On Sep 13, 8:24 am, Roberto Waltman <use...@rwaltman.com> wrote:
> Eric Sosman wrote:
> >     ... if you really think you need "pack(1)".  Usually (not always,
> >but usually) that's the sign of a short-term hack leading to long-
> >term headaches.
>
> Not when you are dealing with communication protocols, mapping
> hardware control registers in embedded systems, etc.

I write device drivers as part of my job (among other things) ... the
long-short of that is if you want a driver that has a hell of a chance
of being portable you don't use packing tricks or overlaying of
registers.  If you're really tight on one platform then you can
deviate but then you're really heading down a nightmare of forked
code.

I've never used a pragma in any of my development efforts.  If I need
to serialize some data I manually pack it using appropriate C
constructs (like shifting bits out of a long to get a stream of
bytes).  Aliasing is also a big no-no and generally a sign of trouble
ahead.

Tom

[toc] | [prev] | [next] | [standalone]


#10200

FromIan Collins <ian-news@hotmail.com>
Date2011-09-14 07:55 +1200
Message-ID<9d9qp0F784U3@mid.individual.net>
In reply to#10187
On 09/14/11 12:24 AM, Roberto Waltman wrote:
> Eric Sosman wrote:
>>      ... if you really think you need "pack(1)".  Usually (not always,
>> but usually) that's the sign of a short-term hack leading to long-
>> term headaches.
>
> Not when you are dealing with communication protocols, mapping
> hardware control registers in embedded systems, etc.
> Without the "pack" pragmas, instead of having a structure that
> directly overlaps the desired memory layout, the packing/unpacking
> would have to be in higher level software.
> This is a much needed functionality, and I am puzzled why it never
> became part of the language standard, instead of a not always
> available compiler extension.

Try using "pack(1)" on something like Sparc that does not allow 
misaligned access....

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#10217

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-09-14 07:58 -0400
Message-ID<j4q4uq$54u$1@dont-email.me>
In reply to#10187
On 9/13/2011 8:24 AM, Roberto Waltman wrote:
> Eric Sosman wrote:
>>      ... if you really think you need "pack(1)".  Usually (not always,
>> but usually) that's the sign of a short-term hack leading to long-
>> term headaches.
>
> Not when you are dealing with communication protocols, mapping
> hardware control registers in embedded systems, etc.

     For communication protocols: Even if you can arrange a struct's
layout to match the foreign format, you still need to deal with
representation. That two-byte integer: Is it big- or little-endian?
Ordinary positional binary or a Gray code? Is the low-order bit a
value, or is it parity? Layout is only one of the issues when mediating
between internal values and external forms, and "solving" them by
arranging a struct merely ignores the others.  If you manage to get it
working with a particular compiler on a particular machine, and if "it
works" seduces you into thinking you've found the right approach, I
predict long-term headaches.

     For memory-mapped registers: Although it's quite unlikely that
issues like endianness will arise, brand-new problems crop up.  For
example, a four-byte register at 0xF00-0xF03 might do nothing at all
in response to accesses at 0xF01,0xF02,0xF03 -- it's not memory,
after all, but a little gadget somewhere that's waiting for 0xF00
to show up on the address lines. So you lay out your struct just like
the manual says: Four flag bits, four must-be-zero bits, a three-bit
command code and five bit sub-command code, and a two-byte integer for
the swizzle selector value. And then you store to the swizzle selector
(at 0xF02), and the hardware device ... ignores you.  (Even worse,
maybe it ignores the two low-order address bits and treats the swizzle
selector as flags-and-commands!) The pretty layout of the struct has
not helped in the slightest; again, you need a completely different
approach.

> Without the "pack" pragmas, instead of having a structure that
> directly overlaps the desired memory layout, the packing/unpacking
> would have to be in higher level software.

     It has to be so anyhow. If not today, then tomorrow when the
long-term headaches begin to throb.

> This is a much needed functionality, and I am puzzled why it never
> became part of the language standard, instead of a not always
> available compiler extension.

     It could be made to work even on machines that have alignment
requirements for memory-resident objects.  All you need to do is
fetch and store multi-byte objects one byte at a time, marshalling
them and unmarshalling them with extra instructions.  You've got to
do this not only for packed structs, but for any pointer that might
point to a misaligned object somewhere -- yes, qsort() just slowed
down some more.  This seems a high price to pay for functionality
which, despite your statement to the contrary, is in no way "needed."

     That's my story, and I'm sticking to it.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#10225

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2011-09-14 14:54 +0000
Message-ID<slrnj71g1o.gtj.grahn+nntp@frailea.sa.invalid>
In reply to#10217
On Wed, 2011-09-14, Eric Sosman wrote:
> On 9/13/2011 8:24 AM, Roberto Waltman wrote:
>> Eric Sosman wrote:
>>>      ... if you really think you need "pack(1)".  Usually (not always,
>>> but usually) that's the sign of a short-term hack leading to long-
>>> term headaches.
>>
>> Not when you are dealing with communication protocols, mapping
>> hardware control registers in embedded systems, etc.
>
>      For communication protocols: Even if you can arrange a struct's
> layout to match the foreign format, you still need to deal with
> representation. That two-byte integer: Is it big- or little-endian?
> Ordinary positional binary or a Gray code? Is the low-order bit a
> value, or is it parity? Layout is only one of the issues when mediating
> between internal values and external forms, and "solving" them by
> arranging a struct merely ignores the others.

Plus, you now have leaked the concept of foreign endianness into your
code. As soon as you open a hole in the type system

   const struct Foo* foo = (struct Foo*)some_octet_buffer;

things which look like integers but /aren't/ are free to leak into any
part of your code, and sooner or later you'll accidentally do
arithmetics on something which is in foreign byte-order.

Foreign byte-order scalars are like zombies. You don't want them
indoors; they have bad manners.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#10294

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-09-16 00:34 +0300
Message-ID<87wrd94hib.fsf@bazspaz.fatphil.org>
In reply to#10187
Roberto Waltman <usenet@rwaltman.com> writes:
> Eric Sosman wrote:
> >     ... if you really think you need "pack(1)".  Usually (not always,
> >but usually) that's the sign of a short-term hack leading to long-
> >term headaches.
> 
> Not when you are dealing with communication protocols, mapping
> hardware control registers in embedded systems, etc.

Packing doesn't address endianness. You have lost already.

Phil
-- 
"Religion is what keeps the poor from murdering the rich."
-- Napoleon

[toc] | [prev] | [next] | [standalone]


#10312

FromNobody <nobody@nowhere.com>
Date2011-09-16 12:07 +0100
Message-ID<pan.2011.09.16.11.07.25.478000@nowhere.com>
In reply to#10294
On Fri, 16 Sep 2011 00:34:20 +0300, Phil Carmody wrote:

>> >     ... if you really think you need "pack(1)".  Usually (not always,
>> >but usually) that's the sign of a short-term hack leading to long-
>> >term headaches.
>> 
>> Not when you are dealing with communication protocols, mapping
>> hardware control registers in embedded systems, etc.
> 
> Packing doesn't address endianness. You have lost already.

It doesn't matter for the "hardware control registers" case, as these are
inherently in the native byte order.

It doesn't always matter for the case of communication protocols; some
protocols offer a choice of byte order. Similarly for file formats.

For floating-point values, reading bytes directly into a C float/double
then optionally byte-swapping is rather common. If your platform doesn't
use IEEE-754 representation, you lose.

Even if portability is important enough to justify explicit
(de)serialisation code, performance is often important enough to justify:

	#if FILE_FORMAT_IS_NATIVE_FORMAT
		return fwrite(&obj, sizeof(obj), 1, fp);
	#else
		// explicit seralisation
	#endif

[toc] | [prev] | [next] | [standalone]


#10188

From"BartC" <bc@freeuk.com>
Date2011-09-13 13:50 +0100
Message-ID<j4njli$f4f$1@dont-email.me>
In reply to#10185
"Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message 
news:j4ngch$oqb$1@dont-email.me...
> On 9/13/2011 5:47 AM, Wang WolfLouis wrote:

>>       #define WIN32_PACKED #pragma pack(1)

>     ... if you really think you need "pack(1)".  Usually (not always,
> but usually) that's the sign of a short-term hack leading to long-
> term headaches.

I would guess that 'usually' it is to match a layout defined outside your 
control. (In this case, perhaps because it's not practical to rewrite the 
whole of Windows.)

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#10189

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-09-13 08:59 -0400
Message-ID<j4nk2u$hns$1@dont-email.me>
In reply to#10188
On 09/13/2011 08:50 AM, BartC wrote:
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message 
> news:j4ngch$oqb$1@dont-email.me...
>> On 9/13/2011 5:47 AM, Wang WolfLouis wrote:
> 
>>>       #define WIN32_PACKED #pragma pack(1)
> 
>>     ... if you really think you need "pack(1)".  Usually (not always,
>> but usually) that's the sign of a short-term hack leading to long-
>> term headaches.
> 
> I would guess that 'usually' it is to match a layout defined outside your 
> control. (In this case, perhaps because it's not practical to rewrite the 
> whole of Windows.)

There's no need to rewrite Windows; just read the data into an array of
unsigned char, then unpack the array into each member of the structure
using memcpy(). Reverse the process when writing such data. I've written
such code far more often than I'd like to remember, and I wish C had
provided mechanisms that would allow me to avoid writing such code, but
it's not horribly difficult, either.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#10227

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2011-09-14 15:02 +0000
Message-ID<slrnj71ggv.gtj.grahn+nntp@frailea.sa.invalid>
In reply to#10189
On Tue, 2011-09-13, James Kuyper wrote:
> On 09/13/2011 08:50 AM, BartC wrote:
>> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message 
>> news:j4ngch$oqb$1@dont-email.me...
>>> On 9/13/2011 5:47 AM, Wang WolfLouis wrote:
>> 
>>>>       #define WIN32_PACKED #pragma pack(1)
>> 
>>>     ... if you really think you need "pack(1)".  Usually (not always,
>>> but usually) that's the sign of a short-term hack leading to long-
>>> term headaches.
>> 
>> I would guess that 'usually' it is to match a layout defined outside your 
>> control. (In this case, perhaps because it's not practical to rewrite the 
>> whole of Windows.)
>
> There's no need to rewrite Windows; just read the data into an array of
> unsigned char, then unpack the array into each member of the structure
> using memcpy().

Or utility functions like

    static unsigned eat16(const uint8_t*& p)
    {
        unsigned n = *p++ << 8;
        n |= *p++;
        return n;
    }

(OK, that was the C++ version, but that was what I had handy.)

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#10205

FromKenneth Brody <kenbrody@spamcop.net>
Date2011-09-13 16:54 -0400
Message-ID<WYadnf3966vfXvLTnZ2dnUVZ_sSdnZ2d@bestweb.net>
In reply to#10181
On 9/13/2011 5:47 AM, Wang WolfLouis wrote:
> Dear all,
>
>       #define WIN32_PACKED #pragma pack(1)
> I want to define a Macro to simpilify and unify my code for Windows
> and Unix. The special character # is the key. anybody can give me some
> suggesstion? Thanks.

As noted elsethread, a preprocessor directive cannot generate another 
preprocessor directive.

However, just about all Windows implementations (and many *nix 
implementations) I have seen include a set of #include files with the 
necessary implementation-specific way of specifying structure packing. 
Simply surround the code with a pair of #include's.  For example:

#include <pshpack1.h>
/* Code that requires 1-byte packing. */
#include <poppack.h>

- or -

#include <pshpack2.h>
/* Code that requires 2-byte packing. */
#include <poppack.h>

And so on.

It's certainly not standard, but specifying such packing is necessarily 
implementation-specific anyway, and this at least comes close to being 
"portable" across a variety of platforms.

-- 
Kenneth Brody

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web