What is this?

C

Cesar Rodas

Hello to all

As far I know the unsigned char just use 1-byte, long 4-bytes... is
this right???

Well I have the next code...

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

typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar;

int main(int argc, char *argv[])
{
printf("%d\n", sizeof(bar));
}

/*******************************************************************************/
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Is something wrong?
 
C

Chris Hills

Cesar said:
Hello to all

As far I know the unsigned char just use 1-byte, long 4-bytes... is
this right???

No. It depends on your platform...

Under ISO C there are certain minimum's but They could be larger.
However many implementations, due to the hardware use non standard type
sizes.

Well I have the next code...

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

typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar;

int main(int argc, char *argv[])
{
printf("%d\n", sizeof(bar));
}

/***********************************************************************
********/
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Is something wrong?
 
M

matevzb

Hello to all

As far I know the unsigned char just use 1-byte, long 4-bytes... is
this right???
A char is always 1 byte, but a long may or may not be 4 bytes in size.
Well I have the next code...

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

typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];

} bar;int main(int argc, char *argv[])
{
printf("%d\n", sizeof(bar));

}/*******************************************************************************/
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Is something wrong?
No, nothing is wrong. This is called padding and the compiler does it
to align the structure members according to their types. See the c.l.c
FAQ (http://www.c-faq.com/struct/padding.html) for more detail.
 
J

jacob navia

Cesar Rodas a écrit :
Hello to all

As far I know the unsigned char just use 1-byte, long 4-bytes... is
this right???

Well I have the next code...

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

typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar;

int main(int argc, char *argv[])
{
printf("%d\n", sizeof(bar));
}

/*******************************************************************************/
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Is something wrong?

No
Let us count:

unsigned char lock; 1 byte
long a; 4 bytes. BUT

The long is aligned to an address multiple of four.
This means that 3 bytes are left empty between the char
and the long. This is why your structure is 3 bytes
bigger than what you think
 
F

Francois Grieu

As far I know the unsigned char just use 1-byte, long 4-bytes...
is this right???

This is right in many, but no all C implementations.
The C standard implies that
unsigned char can hold at least 8 bits
unsigned long can hold at least 32 bits
long can hold any value in the range -2147483647 to 2147483647
Well I have the next code...

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

typedef struct _foo

identifiers starting with _ are reserved; dont use them.
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar;

int main(int argc, char *argv[])
{
printf("%d\n", sizeof(bar));

There is a potential bug here: sizeof(bar) is of type size_t, not int.
Thus what is printed is undefined, from this group's standpoint.
This is likely NOT bitting you right now, thought.

likely, your compiler issues a warning for the lack of a return value.

WHY THE OUTPUT IS 1034?

Likely, because the compiler decided to align the field a to some mutlple
of 4 bytes, creating a hole of 3 bytes between lock and a.
The compiler is free to do such things, and does. On many architectures
(with a bus wider than 8-bit) this improve performance. On some
architectures it may be necessary for the program to work at all.
Is need to be 1024 + 4 + 4 + 1 = 1033

No it does not. The standard requires the result to be at least 1027
(that could occur if sizeof(long) is 1). I'm unsure of a maximum.

On architectures where alignment it is not absolutely necessary, the
compiler often has a pragma to force the behaviour that you are expecting.


Francois Grieu
 
K

Keith Thompson

Cesar Rodas said:
As far I know the unsigned char just use 1-byte, long 4-bytes... is
this right???

unsigned char is 1 byte by definition. The size of long can vary
from one implementation to another.
Well I have the next code...

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

typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar;

int main(int argc, char *argv[])
{
printf("%d\n", sizeof(bar));
}

/*******************************************************************************/
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Is something wrong?

No, nothing is wrong.

The comp.lang.c FAQ is at <http://www.c-faq.com/>. You've asked
question 2.12 and/or 2.13.
 
D

David T. Ashley

Cesar Rodas said:
Hello to all

As far I know the unsigned char just use 1-byte, long 4-bytes... is
this right???

Well I have the next code...

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

typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar;

int main(int argc, char *argv[])
{
printf("%d\n", sizeof(bar));
}

/*******************************************************************************/
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Is something wrong?

This question is covered here.

http://www.c-faq.com/struct/padding.html

There is a lot of modulo arithmetic involved, but the compiler HAS TO pad if
there are alignment requirements for individual structure members.

The general nature of the language requires that one be able to array
structures using sizeof(struct) as the offset between them. This leads to
some unexpected behavior.

For example, assume that sizeof(long) is 4 with required mod 4 alignment,
sizeof(int) is 2 with required mod 2 alignment, and sizeof(char) is 1 with
required byte alignment.

Consider these two structures:

struct A {
int x1;
int x2;
char c;
}

and

struct B {
long x;
char c;
}

It might seem that the size of both structures is going to be equivalent,
because they each sum to 5 bytes. Seem reasonable?

Probably wrong. "B" needs to have a size of 8, because if the structure is
arrayed, mod 4 alignment has to be achieved on every array element.
However, "A" only needs to a size of 6, because only mod 2 alignment needs
to be achieved on every element.

Trying to guess what the compiler is going to do is a sure way to write
platform-dependent code. sizeof() returns what it does. Don't even worry
about what it will be or why.
 
K

Keith Thompson

Cesar Rodas said:
typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar; [snip]
printf("%d\n", sizeof(bar)); [snip]
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Another question for you: *why* do you need sizeof bar to be 1033.

It's likely that the answer is that you don't; the compiler knows what
it needs to do, and you should stand back and let it do its job. But
sometimes you do need to match some externally imposed data layout.
If you can give us more details about what you're trying to do, we can
probably help.
 
M

Mark McIntyre

On 21 Jan 2007 07:49:44 -0800, in comp.lang.c , "Cesar Rodas"

(question about why the size of a struct was not the sum of the size
of its members.)

This is a FAQ.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
S

Spiros Bousbouras

Keith said:
unsigned char is 1 byte by definition. The size of long can vary
from one implementation to another.

It should be clarified here that in the C standard "byte"
is a synonym for char and doesn't have to be exactly
8 bits , simply at least 8 bits.
 
C

christian.bau

Francois said:
There is a potential bug here: sizeof(bar) is of type size_t, not int.
Thus what is printed is undefined, from this group's standpoint.
This is likely NOT bitting you right now, thought.

On the other hand, it will byte you really, really, really hard once
you use a 64 bit compiler.

Use the "zu" format specifier in C99, or cast to unsigned long and use
"lu", which is safe for objects up to 4 GB.
 
I

iu2

I work with a DSP which can only access 4-bytes memory addresses. Hence
everything is 4-bytes: chars, ints, longs, floats... :eek:)
 
C

CBFalconer

iu2 said:
I work with a DSP which can only access 4-bytes memory addresses.
Hence everything is 4-bytes: chars, ints, longs, floats... :eek:)

So? You seem to have no problems or questions. See my sig. below.

--
If you want to post a followup via groups.google.com, ensure
you quote enough for the article to make sense. Google is only
a poor interface to usenet. There is no reason to assume your
readers can, or ever will, see any previous articles.
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
R

Richard Heathfield

iu2 said:
I work with a DSP which can only access 4-bytes memory addresses. Hence
everything is 4-bytes: chars, ints, longs, floats... :eek:)

If sizeof(char) yields a result > 1, you're not using a conforming C
implementation.

char is always exactly one byte wide. Bytes may, however, contain any number
of bits >= 8. The number of bits in a byte as far as your implementation is
concerned is recorded by CHAR_BIT in <limits.h>

Incidentally, like anything in standard headers, that's a read-only value;
changing it is of no more value to you than scribbling over the "amount
owing" part of the phone bill that drops through your door.
 
M

Mike Wahler

iu2 said:
I work with a DSP which can only access 4-bytes memory addresses. Hence
everything is 4-bytes: chars, ints, longs, floats... :eek:)

If your C implementation reports sizeof(char)
as any value other than one, its 'CHAR_BIT'
macro evaluates to less than eight, it's
nonconforming.

-Mike
 
C

Chris Dollin

Cesar said:
As far I know the unsigned char just use 1-byte, long 4-bytes... is
this right???
No.

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

typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar;

int main(int argc, char *argv[])
{
printf("%d\n", sizeof(bar));
}

/*******************************************************************************/
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Is something wrong?

Yes.

[sizeof struct uselessunderbarwhydidyoubotherfoo is
sizeof char (ie 1) + compiler-whim padding
+ sizeof long + compiler-whim padding
+ sizeof long + compiler-whim padding
+ sizeof char[1024] (ie 1024) + compiler-whim padding]
 
K

Keith Thompson

iu2 said:
I work with a DSP which can only access 4-bytes memory addresses. Hence
everything is 4-bytes: chars, ints, longs, floats... :eek:)

Please provide context when you post a followup. Don't assume that
your readers can easily see the article to which you're replying. See
<http://cfaj.freeshell.org/google/>.

In C, a char is one byte by definition. A "byte" in C is at least 8
bits, but it can be larger.
 
C

Cesar Rodas

Keith said:
Cesar Rodas said:
typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar; [snip]
printf("%d\n", sizeof(bar)); [snip]
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Another question for you: *why* do you need sizeof bar to be 1033.
I need because I want to write a file that need to be read in windows,
linux, freebsd and mobile handlers.
 
C

Chris Dollin

Cesar said:
Keith said:
Cesar Rodas said:
typedef struct _foo
{
unsigned char lock;
long a;
long b;
unsigned char data[1024];
} bar; [snip]
printf("%d\n", sizeof(bar)); [snip]
WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

Another question for you: *why* do you need sizeof bar to be 1033.
I need because I want to write a file that need to be read in windows,
linux, freebsd and mobile handlers.

You don't need sizeof(bar) to be 1033 to do that.

You're trying the tempting shortcut of

int written = fwrite( &bar, sizeof bar, 1, streamyThing );

I suspect. Fall not into temptation, for it will turn round and
bite your arteries when you're not looking.
 
R

Richard Tobin

Another question for you: *why* do you need sizeof bar to be 1033.
[/QUOTE]
I need because I want to write a file that need to be read in windows,
linux, freebsd and mobile handlers.

Writing structures directly is not portable. Not only may the total
size be different, but the representation of the parts may be
different too. For example, the byte order may be different.

Do it some other way, for example by writing functions to write each
part of the structure.

-- Richard
 

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

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top