Re: Programming question: sizeof struct?

1999-07-27 Thread E.L. Meijer \(Eric\)
Joop Stakenborg writes:

 Hi there,
 
 The upstream maintainer of one of my packages is having problems
 with his code. I thought it would be nice to use the debian mailing
 lists, to see if we can an answer on this. I will forward any solution
 to him.
 
 --
 The reason why I have not released LogConv 1.54 for Linux is that I am
 having problems with packed structures that is causing some file formats
 to not be handled properly.  Even though I specify -fpack_struct the
 generated code does not appear to actually do this.  Structure fields
 are
 offset and the return from sizeof() returns a value that is not valid.

The return value from sizeof _is_ valid.  It returns the amount of
memory the object occupies in memory.  Maybe you don't like it, but
that is another issue.

 For instance, if the structure were:
 
 struct foo {
 char text[3];
 int  num;
 };
 
 sizeof would return 6 and not 5.

Um, I get 8 instead of 7 (an int is usually 4 bytes in linux):

oef.c

#include stdio.h

struct A {
  char a[3];
  int b;
};

int main(void) {
  printf(%u\n, (unsigned) sizeof(struct A));

  return 0;
}


If I compile and run like this:

$ gcc -O2 -o oef oef.c
$ ./oef
8

... I do get padding, and if I compile and run like this:

$ gcc -fpack-struct -O2 -o oef oef.c
$ ./oef
7

... I don't get padding.  This is using gcc 2.7.2.3.  I can imagine
that there exist optimization options that affect this though,
especially the -malign-... type.  Maybe you need to switch these off.

There is a second, very-unportable-too-I-guess way:

oef2.c:

#include stdio.h

struct A {
  char a[3];
  int b __attribute__ ((packed));
};

int main(void) {
  printf(%u\n, (unsigned) sizeof(struct A));

  return 0;
}


This yields:
$ gcc -O2 -o oef2 oef2.c
$ ./oef2
7

However, unless you are really tight on memory, it is a bad idea to muck
around with the default padding in structures, since it degrades
performance.  If the issue is to write binary files that are portable
across different architectures, then padding in structures is only one
of the problems you will encounter.  Have a look at the C-FAQ-list at
URL: http://www.eskimo.com/~scs/C-faq/top.html, item 20.5, for
references on how to tackle this problem.

HTH,
Eric

-- 
 E.L. Meijer ([EMAIL PROTECTED])
 Eindhoven Univ. of Technology
 Lab. for Catalysis and Inorg. Chem. (SKA)


Re: Programming question: sizeof struct?

1999-07-27 Thread Jonathan Guthrie
On Fri, 9 Jul 1999, Joop Stakenborg wrote:

 struct foo {
 char text[3];
 int  num;
 };
 
 sizeof would return 6 and not 5.  So it's obvious that the compiler is
 placing a pad byte between text and num to align num.  I want it to
 stop!

That's odd.  On most architectures, I would expect sizeof to result in at
least 7 because int's are at least four bytes long.

It is generally bad form to write code that, like this appears to do,
relies upon the rules of packing and alignment.  Of course, you didn't
write it so you're stuck with it, but such code is generally less portable
than doing things another way.

Coding up a simple example, I see that, without any options, the
sizeof(struct foo) results in 8.  Adding the -fpack-struct option, causes
the sizeof(struct foo) to result in 7.  Adding the line #pragma pack(1)
before the definition of the struct causes sizeof(struct foo) to result in
7.  This is with what I have installed (it says egcs-2.91.60 on the
computer at the house, but I get identical results on an older system
running gcc 2.7.2.1)

#include stdlib.h
#include stdio.h

struct foo {
  char text[3];
  int num;
};

int
main() {
  printf(sizeof(struct foo) = %d\n, sizeof(struct foo));
  return EXIT_SUCCESS;
}

I believe that, based upon your entire message, there are three possible
conclusions that can be reached about your difficulty.  1:  You may be
using an architecture where the char type (upon which the typedef is
based) is two or more bytes long.  2: You may be using a different C
compiler than I expect.  3:  You may be misinterpreting the output from
the compiler.  (Suppose struct foo is defined as you give it, but you're
actually looking at sizeof(foo) where foo is completely different.  That
sort of thing can drive you crazy.)
-- 
Jonathan Guthrie ([EMAIL PROTECTED])
Brokersys  +281-895-8101   http://www.brokersys.com/
12703 Veterans Memorial #106, Houston, TX  77014, USA



Re: Programming question: sizeof struct?

1999-07-12 Thread Goswin Brederlow
Joop Stakenborg [EMAIL PROTECTED] writes:

 For instance, if the structure were:
 
 struct foo {
 char text[3];
 int  num;
 };
 
 sizeof would return 6 and not 5.  So it's obvious that the compiler is
 placing a pad byte between text and num to align num.  I want it to
 stop!

Actually thats 8 on alpha.
And if you pack that to 5 the program will run with 10% speed and
generate a lot of unaligned traps. DON'T do that. Write a parser that
can read the data from file in a arch independant manner.

If you don't you will get a critical bug as soon as you release the
package, because if won't work on different endianess, even if you
pack the struct.

May the Source be with you.
Goswin


Re: Programming question: sizeof struct?

1999-07-12 Thread Goswin Brederlow
Carl Mummert [EMAIL PROTECTED] writes:

 #pragma pack(1)
 struct {};
 #pragma pack()
 
 Which forces the layout to be as you specified.
 
 Using a command line option is a Bad Idea (tm) as it may corrupt glibc's
 structures
 
 To test a resonse to the original message, I made the follwing c file
 ( I was not familiar with the attribute flag, so I guessed wrong):
 --begin
 
 __attribute__ ((packed)) struct foo 
struct foo __attribute__ ((packed)) ???
 {
   char c[3];
   int x;
 };
 
 int main()
 {
   printf(%d \n, sizeof(struct foo));
 }
 --end
...
 Which made me think... and check... and sure enough
 the ORIGINAL STRUCT actually has a size of 7 with the command line option!
 THe guy is either crazy, or he is using some strange compiler that
 we don't know about (althoguh he did say the size was 6, as if he
 had a 286...)

Maybe he meant

struct foo {
char c[3];
short s;
// char __PAD;
}

or

struct ofoo {
char c[3];
// char __PAD;
short
}

as any normal compiler would generate.

MfG,
Goswin


Re: Programming question: sizeof struct?

1999-07-11 Thread Oleg Krivosheev
On Sun, 11 Jul 1999, Antti-Juhani Kaijanaho wrote:

 On Sat, Jul 10, 1999 at 11:26:19PM +1000, Hamish Moffatt wrote:
  Or even 8, since an int is 32 bits.
 
 int can be anything from 16 bits up.  

we do not have such architectures, i believe

 In fact, I believe we have
 architectures where int is 64 bits.  

well, that is not true either. I believe Linux follows
LP64 model on 64bit hw, where long and pointer are 64bits
while int is still 32bits

 Do *not* depend on the size of int!

agreed

OK



Re: Programming question: sizeof struct?

1999-07-10 Thread Hamish Moffatt
On Fri, Jul 09, 1999 at 09:44:06AM -0600, Jason Gunthorpe wrote:
   struct foo {
   char text[3];
   int  num;
   };
   
   sizeof would return 6 and not 5.  
  
  6? Are you sure you're using Linux/gcc?
 
 Yes, 6, it will insert a single extra character at the end of text to
 place the alignment of num on a 4 byte boundry.

Or even 8, since an int is 32 bits.


Hamish
-- 
Hamish Moffatt VK3SB (ex-VK3TYD). 
CCs of replies from mailing lists are welcome.


Re: Programming question: sizeof struct?

1999-07-10 Thread Antti-Juhani Kaijanaho
On Sat, Jul 10, 1999 at 11:26:19PM +1000, Hamish Moffatt wrote:
 Or even 8, since an int is 32 bits.

int can be anything from 16 bits up.  In fact, I believe we have
architectures where int is 64 bits.  Do *not* depend on the size of int!

-- 
%%% Antti-Juhani Kaijanaho % [EMAIL PROTECTED] % http://www.iki.fi/gaia/ %%%

   ... memory leaks are quite acceptable in many applications ...
(Bjarne Stroustrup, The Design and Evolution of C++, page 220)


Programming question: sizeof struct?

1999-07-09 Thread Joop Stakenborg
Hi there,

The upstream maintainer of one of my packages is having problems
with his code. I thought it would be nice to use the debian mailing
lists, to see if we can an answer on this. I will forward any solution
to him.

--
The reason why I have not released LogConv 1.54 for Linux is that I am
having problems with packed structures that is causing some file formats
to not be handled properly.  Even though I specify -fpack_struct the
generated code does not appear to actually do this.  Structure fields
are
offset and the return from sizeof() returns a value that is not valid.
For instance, if the structure were:

struct foo {
char text[3];
int  num;
};

sizeof would return 6 and not 5.  So it's obvious that the compiler is
placing a pad byte between text and num to align num.  I want it to
stop!
---

Thanks for your attention.

Joop
-- 

 Joop Stakenborg PA4TU, ex-PA3ABA [EMAIL PROTECTED]
 Linux Hamradio Applications and Utilities Homepage
 http://www.casema.net/~aba


Re: Programming question: sizeof struct?

1999-07-09 Thread Antti-Juhani Kaijanaho
On Fri, Jul 09, 1999 at 09:09:15AM +0200, Joop Stakenborg wrote:
 The reason why I have not released LogConv 1.54 for Linux is that I am
 having problems with packed structures that is causing some file formats
 to not be handled properly.

Reading and writing structs to files is at best unportable, it is generally
considered bad design - and it is usually a broken method.  When handling
binary files you must think of the length of any specific field (int is not
necessarily 16 bit or 32 bit or 64 bit, for example!) and you must handle
bytesex.  These things CANNOT be reliably handled with structs without
kluging around.

NEVER read/write C data types to/from a binary file.  There are exceptions,
of course, but they are rare.

You should write a reader/writer that treats the file as an octet stream and
parses the data from it.

 So it's obvious that the compiler is
 placing a pad byte between text and num to align num.  I want it to
 stop!

You want your C compiler to compile something other than C.  In C, the only
guarantee you get is that the struct elements are stored in order (IIRC).

-- 
%%% Antti-Juhani Kaijanaho % [EMAIL PROTECTED] % http://www.iki.fi/gaia/ %%%

   ... memory leaks are quite acceptable in many applications ...
(Bjarne Stroustrup, The Design and Evolution of C++, page 220)


Re: Programming question: sizeof struct?

1999-07-09 Thread Oleg Krivosheev
Hi,

 Hi there,
 
 The upstream maintainer of one of my packages is having problems
 with his code. 

with his code?

 I thought it would be nice to use the debian mailing
 lists, to see if we can an answer on this. I will forward any solution
 to him.
 
 --
 The reason why I have not released LogConv 1.54 for Linux is that I am
 having problems with packed structures that is causing some file formats
 to not be handled properly.  Even though I specify -fpack_struct the
 generated code does not appear to actually do this.  Structure fields
 are
 offset and the return from sizeof() returns a value that is not valid.

what do you mean it is not valid? Read ANSI standard or any
decent C book. It is quite valid - compiler may insert any padding
between struct members...

 For instance, if the structure were:
 
 struct foo {
 char text[3];
 int  num;
 };
 
 sizeof would return 6 and not 5.  

6? Are you sure you're using Linux/gcc?

The sizeof should be equal to 8 ! It would be 6 only on 16bit platform
(MS DOS comes to mind...)

 So it's obvious that the compiler is
 placing a pad byte between text and num to align num.  I want it to
 stop!
 ---
 
 Thanks for your attention.
 
 Joop

from GCC info manual:

Specifying Attributes of Variables
==

   The keyword `__attribute__' allows you to specify special attributes
of variables or structure fields.  This keyword is followed by an
attribute specification inside double parentheses.  Eight attributes
are currently defined for variables: `aligned', `mode', `nocommon',
`packed', `section', `transparent_union', `unused', and `weak'.  Other
attributes are available for functions (*note Function Attributes::.)
and for types (*note Type Attributes::.).

   You may also specify attributes with `__' preceding and following
each keyword.  This allows you to use them in header files without
being concerned about a possible macro of the same name.  For example,
you may use `__aligned__' instead of `aligned'.

...

`packed'
 The `packed' attribute specifies that a variable or structure field
 should have the smallest possible alignment--one byte for a
 variable, and one bit for a field, unless you specify a larger
 value with the `aligned' attribute.

 Here is a structure in which the field `x' is packed, so that it
 immediately follows `a':

  struct foo
  {
char a;
int x[2] __attribute__ ((packed));
  };

But i advise to use gcc default padding - it is definitely
more efficient and portable...

IMO, you have problems with structs I/O. The UNIX paradigm is that
files have no structure, they're just byte streams... And in order to
be endian-neutral, choose some byte ordering - for example, lets keep
network byte ordering in the file

Provide two small functions like

write_struct_foo( int fd, const struct foo* ptr ) {
  
  int tmp = htonl( ptr-num );
  write( fd, ptr-name, 3 );
  write( fd, tmp, sizeof(int) );

}

read_struct_foo( int fd, struct foo* ptr ) {
  int tmp;

  read( fd, ptr-name, 3 );
  read( fd, tmp, sizeof(int) );

  ptr-num = ntohl( tmp );

}

Of course, error checking and other stuff should be added but hope 
you got the idea. Just in case, some info from glibc doc:

Byte Order Conversion
-

   Different kinds of computers use different conventions for the
ordering of bytes within a word.  Some computers put the most
significant byte within a word first (this is called big-endian
order), and others put it last (little-endian order).

   So that machines with different byte order conventions can
communicate, the Internet protocols specify a canonical byte order
convention for data transmitted over the network.  This is known as the
network byte order.

   When establishing an Internet socket connection, you must make sure
that the data in the `sin_port' and `sin_addr' members of the
`sockaddr_in' structure are represented in the network byte order.  If
you are encoding integer data in the messages sent through the socket,
you should convert this to network byte order too.  If you don't do
this, your program may fail when running on or talking to other kinds
of machines.

   If you use `getservbyname' and `gethostbyname' or `inet_addr' to get
the port number and host address, the values are already in the network
byte order, and you can copy them directly into the `sockaddr_in'
structure.

   Otherwise, you have to convert the values explicitly.  Use `htons'
and `ntohs' to convert values for the `sin_port' member.  Use `htonl'
and `ntohl' to convert IPv4 addresses for the `sin_addr' member.
(Remember, `struct in_addr' is equivalent to `uint32_t'.)  These
functions are declared in `netinet/in.h'.

 - Function: uint16_t htons (uint16_t HOSTSHORT)
 This function converts the `uint16_t' integer 

Re: Programming question: sizeof struct?

1999-07-09 Thread Jason Gunthorpe

On Fri, 9 Jul 1999, Oleg Krivosheev wrote:

  to not be handled properly.  Even though I specify -fpack_struct the
  generated code does not appear to actually do this.  Structure fields
  are
  offset and the return from sizeof() returns a value that is not valid.
 
 what do you mean it is not valid? Read ANSI standard or any
 decent C book. It is quite valid - compiler may insert any padding
 between struct members...

He probably means it is not exactly what he wants :

  For instance, if the structure were:
  
  struct foo {
  char text[3];
  int  num;
  };
  
  sizeof would return 6 and not 5.  
 
 6? Are you sure you're using Linux/gcc?

Yes, 6, it will insert a single extra character at the end of text to
place the alignment of num on a 4 byte boundry.

  So it's obvious that the compiler is
  placing a pad byte between text and num to align num.  I want it to
  stop!

I always hated gcc __attribute__, I prefer the simpler and more common

#pragma pack(1)
struct {};
#pragma pack()

Which forces the layout to be as you specified.

Using a command line option is a Bad Idea (tm) as it may corrupt glibc's
structures

Jason


Re: Programming question: sizeof struct?

1999-07-09 Thread Oleg Krivosheev

Hi,

On Fri, 9 Jul 1999, Jason Gunthorpe wrote:

 On Fri, 9 Jul 1999, Oleg Krivosheev wrote:
 
   to not be handled properly.  Even though I specify -fpack_struct the
   generated code does not appear to actually do this.  Structure fields
   are
   offset and the return from sizeof() returns a value that is not valid.
  
  what do you mean it is not valid? Read ANSI standard or any
  decent C book. It is quite valid - compiler may insert any padding
  between struct members...
 
 He probably means it is not exactly what he wants :
 
   For instance, if the structure were:
   
   struct foo {
   char text[3];
   int  num;
   };
   
   sizeof would return 6 and not 5.  
  
  6? Are you sure you're using Linux/gcc?
 
 Yes, 6, it will insert a single extra character at the end of text to
 place the alignment of num on a 4 byte boundry.

Once again, sizeof(int) = 4 on Linux/ia32 and Linux/SPARC
(that is what i can check), 
sizeof(text) is at least 3, therefore sizeof( struct foo )
should be at least 7 !!! With additional padding byte sizeof would be
equal to 8. 

What platform/OS/compiler are you using? 

 
   So it's obvious that the compiler is
   placing a pad byte between text and num to align num.  I want it to
   stop!
 
 I always hated gcc __attribute__, I prefer the simpler and more common
 
 #pragma pack(1)
 struct {};
 #pragma pack()
 
 Which forces the layout to be as you specified.

i got an impression it doesn't work for the code...

if i misinterpreted the original message, i'm sorry
 
 Using a command line option is a Bad Idea (tm) as it may corrupt glibc's
 structures

Attributes have nothing in common with command line switches, they're
just like pragmas

From gcc info:

   The keyword `__attribute__' allows you to specify special attributes
of variables or structure fields.

 Jason

Anyway, i think better redesign and rewrite struct I/O stuff.
pragma pack and __attribute__ is just gross hack

OK


Re: Programming question: sizeof struct?

1999-07-09 Thread Carl Mummert
#pragma pack(1)
struct {};
#pragma pack()

Which forces the layout to be as you specified.

Using a command line option is a Bad Idea (tm) as it may corrupt glibc's
structures

To test a resonse to the original message, I made the follwing c file
( I was not familiar with the attribute flag, so I guessed wrong):
--begin

__attribute__ ((packed)) struct foo 
{
  char c[3];
  int x;
};

int main()
{
  printf(%d \n, sizeof(struct foo));
}
--end

This has a size of 8 without the command-line option, but 7 with it.

But this has 7 with or without:

struct foo 
{
  char c[3];
  int x __attribute__ ((packed));
};


And this has 7 with or without

#pragma pack(1)
struct foo 
{
  char c[3];
  int x;
};
#pragma pack()


Which made me think... and check... and sure enough
the ORIGINAL STRUCT actually has a size of 7 with the command line option!
THe guy is either crazy, or he is using some strange compiler that
we don't know about (althoguh he did say the size was 6, as if he
had a 286...)


Carl


Re: Programming question: sizeof struct?

1999-07-09 Thread Paul D. Smith
%% Jason Gunthorpe [EMAIL PROTECTED] writes:

For instance, if the structure were:

struct foo {
char text[3];
int  num;
};

sizeof would return 6 and not 5.  
   
   6? Are you sure you're using Linux/gcc?

  jg Yes, 6, it will insert a single extra character at the end of text to
  jg place the alignment of num on a 4 byte boundry.

Yes, so 4 bytes for the array and... how many for the int?  Right :).

So it's obvious that the compiler is placing a pad byte between
text and num to align num.  I want it to stop!

  jg I always hated gcc __attribute__, I prefer the simpler and more common

  jg #pragma pack(1)
  jg struct {};
  jg #pragma pack()

Ugh.  #pragma is terrible.  See the GCC manual for a description of why.

__attribute__ may be verbose but it's _much_ better than #pragma.

-- 
---
 Paul D. Smith [EMAIL PROTECTED] Network Management Development
 Please remain calm...I may be mad, but I am a professional. --Mad Scientist
---
   These are my opinions---Nortel Networks takes no responsibility for them.