By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
426,115 Members | 894 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 426,115 IT Pros & Developers. It's quick & easy.

Four or Two Bytes?

P: n/a
Does anybody know the answer to the following? An unsigned short is 2
bytes long. Why is the following file created as 4 bytes instead of
2?

file = fopen("data.bin", "wb");
if (file != NULL)
{
unsigned short s = 65535;
printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
fwrite(&s, sizeof(unsigned short), sizeof(s), file);
fclose(file); // File written as 4 bytes... hmm
}

- Hahnemann

Jun 27 '08 #1
Share this Question
Share on Google+
33 Replies


P: n/a
Hahnemann <ha*************@gmail.comwrites:
>Does anybody know the answer to the following? An unsigned short is 2
bytes long. Why is the following file created as 4 bytes instead of
2?
>file = fopen("data.bin", "wb");
if (file != NULL)
{
unsigned short s = 65535;
printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
fwrite(&s, sizeof(unsigned short), sizeof(s), file);
fclose(file); // File written as 4 bytes... hmm
}

Because you're asking it to?
Check the 3rd parameter of fwrite().

--
Chris.
Jun 27 '08 #2

P: n/a
On May 29, 9:39*pm, Chris McDonald <ch...@csse.uwa.edu.auwrote:
Hahnemann <hahnemann.or...@gmail.comwrites:
Does anybody know the answer to the following? An unsigned short is 2
bytes long. *Why is the following file created as 4 bytes instead of
2?
file = fopen("data.bin", "wb");
if (file != NULL)
{
* *unsigned short s = 65535;
* *printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
* *fwrite(&s, sizeof(unsigned short), sizeof(s), file);
* *fclose(file); // File written as 4 bytes... hmm
}

Because you're asking it to?
Check the 3rd parameter of fwrite().

--
Chris.
But notice that:

printf("Size of s: %d bytes\n", sizeof(s)) ;

returns 2 bytes. How can I make the file 2 bytes using:

unsigned short x = 65535;

Is this even possible?
Jun 27 '08 #3

P: n/a
"Hahnemann" <ha*************@gmail.comwrote in message
news:2f**********************************@d1g2000h sg.googlegroups.com...
Does anybody know the answer to the following? An unsigned short is 2
bytes long. Why is the following file created as 4 bytes instead of
2?

file = fopen("data.bin", "wb");
if (file != NULL)
{
unsigned short s = 65535;
printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
fwrite(&s, sizeof(unsigned short), sizeof(s), file);
fwrite(
pointer to buffer ... ok
size of an element of that buffer ... 2
number of elements to write ... 2
handle for file write should occur to ... ok

So, 2 elements of 2 bytes each should write four bytes.
fclose(file); // File written as 4 bytes... hmm
So, fwrite worked correctly. More or less, since it wrote out 4 bytes from
a 2 byte object. It could just about as easily have crashed when it went
beyond the bounds of the object.
}
- Bill

Jun 27 '08 #4

P: n/a
Hahnemann <hahnemann.or...@gmail.comwrote:
Chris McDonald <ch...@csse.uwa.edu.auwrote:
Hahnemann <hahnemann.or...@gmail.comwrites:
Does anybody know the answer to the following?
An unsigned short is 2 bytes long.
You mean _if_?
Why is the following file created as 4 bytes
instead of 2?
Because 2 lots of 2 bytes is 4 bytes.
* *unsigned short s = 65535;
* *fwrite(&s, sizeof(unsigned short), sizeof(s), file);
Because you're asking it to?
Check the 3rd parameter of fwrite().

But notice that:

printf("Size of s: %d bytes\n", sizeof(s)) ;

returns 2 bytes. *How can I make the file 2 bytes
using:
By only outputting 2 bytes once, instead of twice.
unsigned short x = 65535;

Is this even possible?
Hangliding is a topic best researched _before_ you
through yourself off the cliff. ;)

--
Peter
Jun 27 '08 #5

P: n/a
Hahnemann <ha*************@gmail.comwrites:
On May 29, 9:39*pm, Chris McDonald <ch...@csse.uwa.edu.auwrote:
>Hahnemann <hahnemann.or...@gmail.comwrites:
>Does anybody know the answer to the following? An unsigned short is 2
bytes long. *Why is the following file created as 4 bytes instead of
2?
file = fopen("data.bin", "wb");
if (file != NULL)
{
* *unsigned short s = 65535;
* *printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
* *fwrite(&s, sizeof(unsigned short), sizeof(s), file);
* *fclose(file); // File written as 4 bytes... hmm
}

Because you're asking it to?
Check the 3rd parameter of fwrite().

But notice that:

printf("Size of s: %d bytes\n", sizeof(s)) ;

returns 2 bytes.
Yes, but ...

"%d" expects an argument of type int; you're giving it an argument of
type size_t. You should cast the value to int (one of the few cases
where a cast is appropriate):

printf("Size of s: %d bytes\n", (int)sizeof s);

And though unsigned short is 2 bytes on your implementation, that's
not guaranteed; it could be different on other implementations.
How can I make the file 2 bytes using:

unsigned short x = 65535;

Is this even possible?
Certainly.

fwrite() writes a specified number of elements. In your case, the
element(s) are of type unsigned short. The second argument is the
size of each element (you're passing ``sizeof(unsigned short)'', which
is ok). The third argument is the number of elements (you're passing
``sizeof(s)''). How many elements do you want to write (hint: 1).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #6

P: n/a
On Fri, 30 May 2008 04:59:22 +0100, Keith Thompson <ks***@mib.orgwrote:
"%d" expects an argument of type int; you're giving it an argument of
type size_t. You should cast the value to int (one of the few cases
where a cast is appropriate):

printf("Size of s: %d bytes\n", (int)sizeof s);
Generally, isn't it better to use

printf("Size of s: %lu bytes\n", (unsigned long)sizeof s);

as recommended in the answer to FAQ question 7.15?

--
Martin

Jun 27 '08 #7

P: n/a
Martin wrote:
On Fri, 30 May 2008 04:59:22 +0100, Keith Thompson <ks***@mib.org>
wrote:
>"%d" expects an argument of type int; you're giving it an argument of
type size_t. You should cast the value to int (one of the few cases
where a cast is appropriate):

printf("Size of s: %d bytes\n", (int)sizeof s);

Generally, isn't it better to use

printf("Size of s: %lu bytes\n", (unsigned long)sizeof s);

as recommended in the answer to FAQ question 7.15?
Guess Keith's point is that you should cast it to whatever the format
specified expects.

Bye, Jojo
Jun 27 '08 #8

P: n/a
On Fri, 30 May 2008 10:19:31 +0100, Joachim Schmitz
<no*********@schmitz-digital.dewrote:
Guess Keith's point is that you should cast it to whatever the format
specified expects.
I'll wait for Keith's response, but I would say that sometimes it may be
better to change the format specified. Casting an unsigned type to signed
type of equal or less width has the potential for data loss.

--
Martin

Jun 27 '08 #9

P: n/a
Martin wrote:
On Fri, 30 May 2008 10:19:31 +0100, Joachim Schmitz
<no*********@schmitz-digital.dewrote:
>Guess Keith's point is that you should cast it to whatever the format
specified expects.

I'll wait for Keith's response, but I would say that sometimes it may
be better to change the format specified. Casting an unsigned type to
signed type of equal or less width has the potential for data loss.
Yes it might have, but how likely is it that a data type is really larger
than INT_MAX?
Jun 27 '08 #10

P: n/a
Joachim Schmitz wrote:
Martin wrote:
>Joachim Schmitz <no*********@schmitz-digital.dewrote:
>>Guess Keith's point is that you should cast it to whatever the
format specified expects.

I'll wait for Keith's response, but I would say that sometimes
it may be better to change the format specified. Casting an
unsigned type to signed type of equal or less width has the
potential for data loss.

Yes it might have, but how likely is it that a data type is
really larger than INT_MAX?
If you simply examine limits.h you will probably find that UINT_MAX
is roughly twice the size of INT_MAX. To me, this indicates your
probability is roughly 2:1. Anything over 0 is bad.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

** Posted from http://www.teranews.com **
Jun 27 '08 #11

P: n/a
CBFalconer wrote:
Joachim Schmitz wrote:
>Martin wrote:
>>Joachim Schmitz <no*********@schmitz-digital.dewrote:

Guess Keith's point is that you should cast it to whatever the
format specified expects.

I'll wait for Keith's response, but I would say that sometimes
it may be better to change the format specified. Casting an
unsigned type to signed type of equal or less width has the
potential for data loss.

Yes it might have, but how likely is it that a data type is
really larger than INT_MAX?

If you simply examine limits.h you will probably find that UINT_MAX
is roughly twice the size of INT_MAX. To me, this indicates your
probability is roughly 2:1. Anything over 0 is bad.
So what? The basic daty types have sizes of 1 to 8 bytes. Sensibel structs
and arrays are most probaly well smaller than 32K, which is the minimun for
INT_MAX, so again: how big is the chance that a real life data type is
larger than that?

Bye, Jojo
Jun 27 '08 #12

P: n/a
Joachim Schmitz wrote:
CBFalconer wrote:
>Joachim Schmitz wrote:
>>Martin wrote:
Joachim Schmitz <no*********@schmitz-digital.dewrote:

Guess Keith's point is that you should cast it to whatever the
format specified expects.

I'll wait for Keith's response, but I would say that sometimes
it may be better to change the format specified. Casting an
unsigned type to signed type of equal or less width has the
potential for data loss.

Yes it might have, but how likely is it that a data type is
really larger than INT_MAX?

If you simply examine limits.h you will probably find that UINT_MAX
is roughly twice the size of INT_MAX. To me, this indicates your
probability is roughly 2:1. Anything over 0 is bad.
So what? The basic daty types have sizes of 1 to 8 bytes. Sensibel
structs and arrays are most probaly well smaller than 32K, which is
the minimun for INT_MAX, so again: how big is the chance that a real
life data type is larger than that?
On top of that: here it is about 2 or 4, which even on the DS9K would easily
fit into INT_MAX.

Bye, Jojo
Jun 27 '08 #13

P: n/a
Joachim Schmitz wrote:
On top of that: here it is about 2 or 4, which even on the DS9K would easily
fit into INT_MAX.
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K.

--
pete
Jun 27 '08 #14

P: n/a
pete wrote:
Joachim Schmitz wrote:
>On top of that: here it is about 2 or 4, which even on the DS9K
would easily fit into INT_MAX.

Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K.
Chapter and verse please
Jun 27 '08 #15

P: n/a
Joachim Schmitz wrote:
pete wrote:
>Joachim Schmitz wrote:
>>On top of that: here it is about 2 or 4, which even on the DS9K
would easily fit into INT_MAX.
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K.
Chapter and verse please
N869
6.2.6.2 Integer types

[#1] For unsigned integer types other than unsigned char,
the bits of the object representation shall be divided into
two groups: value bits and padding bits (there need not be
any of the latter). If there are N value bits, each bit
shall represent a different power of 2 between 1 and 2N-1,
so that objects of that type shall be capable of
representing values from 0 to 2N-1 using a pure binary
representation; this shall be known as the value
representation. The values of any padding bits are
unspecified.

--
pete
Jun 27 '08 #16

P: n/a
Martin <m@b.cwrites:
On Fri, 30 May 2008 04:59:22 +0100, Keith Thompson <ks***@mib.orgwrote:
>"%d" expects an argument of type int; you're giving it an argument of
type size_t. You should cast the value to int (one of the few cases
where a cast is appropriate):

printf("Size of s: %d bytes\n", (int)sizeof s);

Generally, isn't it better to use

printf("Size of s: %lu bytes\n", (unsigned long)sizeof s);

as recommended in the answer to FAQ question 7.15?
Yes. In this particular case, the expression ``sizeof s'' is the size
of an object of type unsigned short, so it's practically certain to be
no greater than INT_MAX. But using int rather than unsigned long was
just laziness in my part; IMHO it's better to get into the habit of
using unsigned long whether it's necessary or not, rather than wasting
time figuring out whether int is ok in this or that particular
instance.

In C99, you can use

printf("Size of s: %zu bytes\n", sizeof s);

to print a size_t value directly. I look forward eagerly to the day
when C99 is widely implemented and that code is reasonably portable.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #17

P: n/a
pete <pf*****@mindspring.comwrites:
Joachim Schmitz wrote:
>On top of that: here it is about 2 or 4, which even on the DS9K
would easily fit into INT_MAX.

Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K.
Padding *bits*, not padding bytes.

But I think you have to pay for the commercial version of the DS9K C
compiler to get unsigned short with CHAR_BIT*INT_MAX padding bits; the
free version only has sizeof(unsigned short)==INT_MAX.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #18

P: n/a
Joachim Schmitz wrote:
>
Martin wrote:
On Fri, 30 May 2008 10:19:31 +0100, Joachim Schmitz
<no*********@schmitz-digital.dewrote:
Guess Keith's point is that you should cast it to whatever the format
specified expects.
I'll wait for Keith's response, but I would say that sometimes it may
be better to change the format specified. Casting an unsigned type to
signed type of equal or less width has the potential for data loss.
Yes it might have, but how likely is it that a data type is really larger
than INT_MAX?
As I recall, "huge model" on real-mode x86 processors use 32-bit
pointers, yet 16-bit ints. As such, I would expect that size_t
could hold values larger than INT_MAX.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Jun 27 '08 #19

P: n/a
Kenneth Brody <ke******@spamcop.netwrites:
Joachim Schmitz wrote:
>Martin wrote:
On Fri, 30 May 2008 10:19:31 +0100, Joachim Schmitz
<no*********@schmitz-digital.dewrote:
Guess Keith's point is that you should cast it to whatever the format
specified expects.

I'll wait for Keith's response, but I would say that sometimes it may
be better to change the format specified. Casting an unsigned type to
signed type of equal or less width has the potential for data loss.
Yes it might have, but how likely is it that a data type is really larger
than INT_MAX?

As I recall, "huge model" on real-mode x86 processors use 32-bit
pointers, yet 16-bit ints. As such, I would expect that size_t
could hold values larger than INT_MAX.
Which is not particularly relevant in this case. The issue, as
Joachim wrote, is whether "a data type is really larger than INT_MAX".
It's not about whether the data type (unsigned short in this case) is
able to hold values larger than INT_MAX; it's about whether the size
of the data type is larger than INT_MAX bytes.

If I had an integer type bigger than 262136 bits, I don't think I'd
call it "short".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #20

P: n/a
pete <pf*****@mindspring.comwrites:
>Joachim Schmitz wrote:
>pete wrote:
>>Joachim Schmitz wrote:
On top of that: here it is about 2 or 4, which even on the DS9K
would easily fit into INT_MAX.
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K.
Chapter and verse please
>N869
6.2.6.2 Integer types
[#1] For unsigned integer types other than unsigned char,
the bits of the object representation shall be divided into
two groups: value bits and padding bits (there need not be
any of the latter). If there are N value bits, each bit
shall represent a different power of 2 between 1 and 2N-1,
so that objects of that type shall be capable of
representing values from 0 to 2N-1 using a pure binary
representation; this shall be known as the value
representation. The values of any padding bits are
unspecified.

One has to feel sorry for the OP at this point!

--
Chris.
Jun 27 '08 #21

P: n/a
Keith Thompson wrote:
pete <pf*****@mindspring.comwrites:
>Joachim Schmitz wrote:
>>On top of that: here it is about 2 or 4, which even on the DS9K
would easily fit into INT_MAX.
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K.

Padding *bits*, not padding bytes.
I refer to a byte composed entirely of padding bits,
as a "padding byte".
But I think you have to pay for the commercial version of the DS9K C
compiler to get unsigned short with CHAR_BIT*INT_MAX padding bits;
It can have more padding bits than that.
The number of padding bits allowable,
doesn't have to be within the range of any integer type.
As long as the number of bytes of the type in question
is within the limit of size_t, everything C still works.
--
pete
Jun 27 '08 #22

P: n/a
pete wrote:
Joachim Schmitz wrote:
>pete wrote:
>>Joachim Schmitz wrote:
On top of that: here it is about 2 or 4, which even on the DS9K
would easily fit into INT_MAX.
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K. Chapter
and verse please

N869
6.2.6.2 Integer types

[#1] For unsigned integer types other than unsigned char,
the bits of the object representation shall be divided into
two groups: value bits and padding bits (there need not be
any of the latter). If there are N value bits, each bit
shall represent a different power of 2 between 1 and 2N-1,
so that objects of that type shall be capable of
representing values from 0 to 2N-1 using a pure binary
representation; this shall be known as the value
representation. The values of any padding bits are
unspecified.
N1256
5.2.4.2.1 Sizes of integer types <limits.h>

....

Their implementation-defined values shall be equal or greater in magnitude

(absolute value) to those shown, with the same sign.

....

- maximum value for an object of type int

INT_MAX +32767 // 215 - 1

So even on a DS9K printf's %d has to be able to display numbers up to 32767.

Bye, Jojo
Jun 27 '08 #23

P: n/a
pete <pf*****@mindspring.comwrites:
Keith Thompson wrote:
>pete <pf*****@mindspring.comwrites:
>>Joachim Schmitz wrote:
On top of that: here it is about 2 or 4, which even on the DS9K
would easily fit into INT_MAX.
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K.
Padding *bits*, not padding bytes.

I refer to a byte composed entirely of padding bits,
as a "padding byte".
Ok, but the standard doesn't. In fact, the standard specifically uses
the phrase "padding bytes" for padding in structs or unions.

[...]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #24

P: n/a
On Thu, 29 May 2008 22:53:32 -0400, "Bill Leary" <Bi********@msn.com>
wrote:
>"Hahnemann" <ha*************@gmail.comwrote in message
news:2f**********************************@d1g2000 hsg.googlegroups.com...
>Does anybody know the answer to the following? An unsigned short is 2
bytes long. Why is the following file created as 4 bytes instead of
2?

file = fopen("data.bin", "wb");
if (file != NULL)
{
unsigned short s = 65535;
printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
> fwrite(&s, sizeof(unsigned short), sizeof(s), file);

fwrite(
pointer to buffer ... ok
size of an element of that buffer ... 2
number of elements to write ... 2
handle for file write should occur to ... ok

So, 2 elements of 2 bytes each should write four bytes.
> fclose(file); // File written as 4 bytes... hmm

So, fwrite worked correctly. More or less, since it wrote out 4 bytes from
a 2 byte object. It could just about as easily have crashed when it went
beyond the bounds of the object.
Actually, fwrite invoked undefined behavior and only appeared to work
correctly because the OP was using it on a system where he was allowed
to access memory beyond the end of s. On a well-behaved system (tm),
his program would have been interrupted in an implementation defined
manner.
Remove del for email
Jun 27 '08 #25

P: n/a
Joachim Schmitz wrote:
pete wrote:
>Joachim Schmitz wrote:
>>pete wrote:
Joachim Schmitz wrote:
On top of that: here it is about 2 or 4, which even on the DS9K
would easily fit into INT_MAX.
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K. Chapter
and verse please
N869
6.2.6.2 Integer types

[#1] For unsigned integer types other than unsigned char,
the bits of the object representation shall be divided into
two groups: value bits and padding bits (there need not be
any of the latter). If there are N value bits, each bit
shall represent a different power of 2 between 1 and 2N-1,
so that objects of that type shall be capable of
representing values from 0 to 2N-1 using a pure binary
representation; this shall be known as the value
representation. The values of any padding bits are
unspecified.
N1256
5.2.4.2.1 Sizes of integer types <limits.h>

...

Their implementation-defined values shall be equal or greater in magnitude

(absolute value) to those shown, with the same sign.

...

- maximum value for an object of type int

INT_MAX +32767 // 215 - 1

So even on a DS9K printf's %d has to be able to display numbers up to 32767.
printf's %d being able to display numbers up to 32767,
is irrelevant as to how many padding bytes
(or bytes composed of padding bits),
an object of type unsigned short is allowed to have.
--
pete
Jun 27 '08 #26

P: n/a
pete wrote:
Joachim Schmitz wrote:
>pete wrote:
>>Joachim Schmitz wrote:
pete wrote:
Joachim Schmitz wrote:
>On top of that: here it is about 2 or 4, which even on the DS9K
>would easily fit into INT_MAX.
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K. Chapter
Chapterand verse please
N869
6.2.6.2 Integer types

[#1] For unsigned integer types other than unsigned char,
the bits of the object representation shall be divided into
two groups: value bits and padding bits (there need not be
any of the latter). If there are N value bits, each bit
shall represent a different power of 2 between 1 and 2N-1,
so that objects of that type shall be capable of
representing values from 0 to 2N-1 using a pure binary
representation; this shall be known as the value
representation. The values of any padding bits are
unspecified.
N1256
5.2.4.2.1 Sizes of integer types <limits.h>

...

Their implementation-defined values shall be equal or greater in
magnitude (absolute value) to those shown, with the same sign.

...

- maximum value for an object of type int

INT_MAX +32767 // 2^15 - 1

So even on a DS9K printf's %d has to be able to display numbers up
to 32767.

printf's %d being able to display numbers up to 32767,
is irrelevant as to how many padding bytes
(or bytes composed of padding bits),
an object of type unsigned short is allowed to have.
INT_MAX is for int, not short, or unsignd short
(%d prints an int, not an unsigned short)

Ah, so you're saying that an int, in addition to it's minimum of 15 value
bits can have as many pading bits (whos's _values_ are unspecified) as it
likes, making the entire sizeof(int) larger than 32727 (as long as it still
fits a size_t)? And not that 'padding _bits_' implies that they are only
allowed to fill up to the next byte size? (the values are explicitly
unspecivied, what about the number?)

Bye, Jojo
Jun 27 '08 #27

P: n/a
Hahnemann wrote:
On May 29, 9:39 pm, Chris McDonald <ch...@csse.uwa.edu.auwrote:
>Hahnemann <hahnemann.or...@gmail.comwrites:
>>Does anybody know the answer to the following? An unsigned short is 2
bytes long. Why is the following file created as 4 bytes instead of
2?
file = fopen("data.bin", "wb");
if (file != NULL)
{
unsigned short s = 65535;
printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
fwrite(&s, sizeof(unsigned short), sizeof(s), file);
fclose(file); // File written as 4 bytes... hmm
}
Because you're asking it to?
Check the 3rd parameter of fwrite().

--
Chris.

But notice that:

printf("Size of s: %d bytes\n", sizeof(s)) ;

returns 2 bytes. How can I make the file 2 bytes using:

unsigned short x = 65535;

Is this even possible?
fwrite(&s, 1, sizeof s, file);

There are several books on C that you could peruse.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jun 27 '08 #28

P: n/a
Joachim Schmitz wrote:
Ah, so you're saying that an int, in addition to it's minimum of 15 value
bits can have as many pading bits (whos's _values_ are unspecified) as it
likes, making the entire sizeof(int) larger than 32727 (as long as it still
fits a size_t)?
Yes.

--
pete
Jun 27 '08 #29

P: n/a
"Joachim Schmitz" <no*********@schmitz-digital.dewrites:
pete wrote:
[...]
>printf's %d being able to display numbers up to 32767,
is irrelevant as to how many padding bytes
(or bytes composed of padding bits),
an object of type unsigned short is allowed to have.
INT_MAX is for int, not short, or unsignd short
(%d prints an int, not an unsigned short)
Right, but we're talking about printing the *size* of an unsigned
short, not its value. The line that led to this long digression was
my own (very slightly sloppy):

printf("Size of s: %d bytes\n", (int)sizeof s);

where s was an object of type unsigned short.
Ah, so you're saying that an int, in addition to it's minimum of 15 value
bits can have as many pading bits (whos's _values_ are unspecified) as it
likes, making the entire sizeof(int) larger than 32727 (as long as it still
fits a size_t)? And not that 'padding _bits_' implies that they are only
allowed to fill up to the next byte size? (the values are explicitly
unspecivied, what about the number?)
The standard says (C99 6.2.6.2p2):

For unsigned integer types other than unsigned char, the bits of
the object representation shall be divided into two groups: value
bits and padding bits (there need not be any of the latter).

For unsigned short, there must be at least 16 value bits (this follows
from the requirement that the range must be at least 0 .. 65535, and
the fact that mathematically you need at least 16 bits to represent
all the values in that range).

The standard places no upper limit on the number of value bits
or on the number of padding bits. sizeof(unsigned short) is
(VB + PB) / CHAR_BIT; VB + PB must be a whole multiple of CHAR_BIT.

This entire discussion is about as close to having no practical
meaning as I can imagine. An implementation that had as many padding
bits for unsigned short as we're talking about, or even as many value
bits, would be beyond exotic; it would be clinically insane.

In practice, I do prefer this:
printf("Size of s: %lu bytes\n", (unsigned long)sizeof s);
to this:
printf("Size of s: %d bytes\n", (int)sizeof s);
but only because it's a good habit, not because I'm the least bit
concerned about the possibility that sizeof s could exceed INT_MAX.
Or the code might be changed so that s is of some larger type (likely
if the code purpose is just to print the sizes of several types).

Note that for ``(int)sizeof(unsigned short)'' to overflow, almost all
the bits of unsigned short would have to be padding bits. If it had a
huge number N of value bits, then int would have to have at least N-1
value bits (-1 for the sign bit), so it would have more than enough
range to represent the value of sizeof(unsigned short).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #30

P: n/a
Keith Thompson wrote:
"Joachim Schmitz" <no*********@schmitz-digital.dewrites:
>pete wrote:
[...]
This entire discussion is about as close to having no practical
meaning as I can imagine. An implementation that had as many padding
bits for unsigned short as we're talking about, or even as many value
bits, would be beyond exotic; it would be clinically insane.
We were discussing the DS9K.

--
pete
Jun 27 '08 #31

P: n/a
"Barry Schwarz" <sc******@dqel.comwrote in message
news:68********************************@4ax.com...
On Thu, 29 May 2008 22:53:32 -0400, "Bill Leary" <Bi********@msn.com>
wrote:
>>"Hahnemann" <ha*************@gmail.comwrote in message
news:2f**********************************@d1g200 0hsg.googlegroups.com...
>>Does anybody know the answer to the following? An unsigned short is 2
bytes long. Why is the following file created as 4 bytes instead of
2?

file = fopen("data.bin", "wb");
if (file != NULL)
{
unsigned short s = 65535;
printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
>> fwrite(&s, sizeof(unsigned short), sizeof(s), file);

fwrite(
pointer to buffer ... ok
size of an element of that buffer ... 2
number of elements to write ... 2
handle for file write should occur to ... ok

So, 2 elements of 2 bytes each should write four bytes.
>> fclose(file); // File written as 4 bytes... hmm

So, fwrite worked correctly. More or less, since it wrote out 4 bytes
from
a 2 byte object. It could just about as easily have crashed when it went
beyond the bounds of the object.

Actually, fwrite invoked undefined behavior and only appeared to work
correctly because the OP was using it on a system where he was allowed
to access memory beyond the end of s. On a well-behaved system (tm),
his program would have been interrupted in an implementation defined
manner.
Sure. But since the specific question was why he got four bytes rather than
two in the target file I emphasized that 2 * 2 is 4, and alluded your point
by commenting "More or less..." and mentioning the crash.

- Bill

Jun 27 '08 #32

P: n/a
On Sun, 1 Jun 2008 19:56:33 -0400, "Bill Leary" <Bi********@msn.com>
wrote:
>"Barry Schwarz" <sc******@dqel.comwrote in message
news:68********************************@4ax.com.. .
snip
>Actually, fwrite invoked undefined behavior and only appeared to work
correctly because the OP was using it on a system where he was allowed
to access memory beyond the end of s. On a well-behaved system (tm),
his program would have been interrupted in an implementation defined
manner.

Sure. But since the specific question was why he got four bytes rather than
two in the target file I emphasized that 2 * 2 is 4, and alluded your point
by commenting "More or less..." and mentioning the crash.
But once the OP has invoked undefined behavior, there is no guarantee
that 2*2 will still equal 4. The only reason fwrite produced 4 bytes
is that this particular manifestation of undefined behavior produced 4
bytes. The fact that he inadvertently asked for 4 bytes is only
unfortunate coincidence. The next time it executes it could do
something completely different. If the OP were to recompile with
different options, who knows what the code could do.
Remove del for email
Jun 27 '08 #33

P: n/a
"Barry Schwarz" <sc******@dqel.comwrote in message
news:1t********************************@4ax.com...
On Sun, 1 Jun 2008 19:56:33 -0400, "Bill Leary" <Bi********@msn.com>
wrote:
>>Sure. But since the specific question was why he got four bytes rather
than
two in the target file I emphasized that 2 * 2 is 4, and alluded your
point
by commenting "More or less..." and mentioning the crash.

But once the OP has invoked undefined behavior, there is no guarantee
that 2*2 will still equal 4. The only reason fwrite produced 4 bytes
is that this particular manifestation of undefined behavior produced 4
bytes. The fact that he inadvertently asked for 4 bytes is only
unfortunate coincidence. The next time it executes it could do
something completely different. If the OP were to recompile with
different options, who knows what the code could do.
You are both technically and theoretically correct.

The root issue, however, was that he was telling the function to write four
bytes when he thought he was telling it to write two bytes.

Explaining the potentially world shattering side effects* of what might have
happened due to his misunderstanding invoking "undefined behavior" would
hardly have been profitable. What he needed, and asked for, was an
explanation of what actually did happen.

If you want to go on in the "undefined behavior" vein, please do so.
Someone has to fight the Good Fight, and you seem to understand your topic
well and do it with great verve.**

For me, I'm done.

- Bill
______________
* I recall someone in another "undefined behavior" thread saying that the
program was free to do anything at all, including implode the world, if it
so desired.
** Yeah, I'm being a little sarcastic. But just a little. I've just
re-examined a half dozen messages where you made your "undefined behavior"
spiel and in each of them (as far as I could tell) you were dead on correct.
An impressive accomplishment.

Jun 27 '08 #34

This discussion thread is closed

Replies have been disabled for this discussion.