473,698 Members | 2,300 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

sizeof stuff and declarations

I have two questions. I hope they are about C. I chose to post
here instead of comp.unix.progr ammer (or some other) because I do
think this is a C question.

Question 1:

%cat float.c
main() {
float **m = malloc(5 * sizeof(float*)) ;
m[0] = malloc( sizeof(float) );
m[0][0] = 1.2;
printf("%f\n",m[0][0]);
}

Is this legal? I never really declare and assign so fast, but I
was wondering if it works because I'm lucky or if it really is
legal. Gcc doesn't like it much.

%gcc -c float.c
float.c: In function `main':
float.c:2: warning: initialization makes pointer from integer
without a cast float.c:3: warning: assignment makes pointer from
integer without a cast

Question 2:

(gdb) p sizeof(int)
$1 = 4
(gdb) p sizeof(long)
$2 = 4

I was expecting to see long a little bigger.
Why are they the same size?

Thank you.
Nov 14 '05 #1
12 1262
Kevin wrote:
I have two questions. I hope they are about C. I chose to post
here instead of comp.unix.progr ammer (or some other) because I do
think this is a C question.

Question 1:

%cat float.c
main() {
float **m = malloc(5 * sizeof(float*)) ;
m[0] = malloc( sizeof(float) );
m[0][0] = 1.2;
printf("%f\n",m[0][0]);
}

Is this legal? I never really declare and assign so fast, but I
was wondering if it works because I'm lucky or if it really is
legal. Gcc doesn't like it much.

%gcc -c float.c
float.c: In function `main':
float.c:2: warning: initialization makes pointer from integer
without a cast float.c:3: warning: assignment makes pointer from
integer without a cast
You forgot do declare 'malloc' functions. That's what causes the
warning, since the compiler assumes that 'malloc' returns an 'int'.
Place '#include <stdlib.h>' at the beginning of your source file and the
warning will go away.

You also forgot to declare 'printf' function. 'printf' is a variadic
function. It mast be declared before use, or the behavior is undefined.
Add '#include <stdio.h>' at the beginning of your source file.

Otherwise, the code is legal.
Question 2:

(gdb) p sizeof(int)
$1 = 4
(gdb) p sizeof(long)
$2 = 4

I was expecting to see long a little bigger.
Why are they the same size?


Why not? This is perfectly legal in C. 'long' is not required to be
bigger than 'int'.

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #2
On Thu, 17 Mar 2005 15:03:23 -0800,
Andrey Tarasevich <an************ **@hotmail.com> wrote:
Kevin wrote:

[...]
Question 2:

(gdb) p sizeof(int)
$1 = 4
(gdb) p sizeof(long)
$2 = 4

I was expecting to see long a little bigger.
Why are they the same size?


Why not? This is perfectly legal in C. 'long' is not required
to be bigger than 'int'.


But if they take the same amount of bytes, then how is it
possible that long can take bigger numbers?

Thanks, Andrey.
Nov 14 '05 #3
Kevin wrote:
...
> Question 2:
>
> (gdb) p sizeof(int)
> $1 = 4
> (gdb) p sizeof(long)
> $2 = 4
>
> I was expecting to see long a little bigger.
> Why are they the same size?


Why not? This is perfectly legal in C. 'long' is not required
to be bigger than 'int'.


But if they take the same amount of bytes, then how is it
possible that long can take bigger numbers?
...


Well, the _guaranteed_ range of type 'long' is indeed wider than that of
type 'int' (per C99 standard). But in actual implementation it is not
required to be strictly wider. Internally 'int' and 'long' can be
implemented in exactly the same way, which is the case on your platform,
I'm sure.

A more pedantic answer (which you probably don't care about, so you can
stop reading now :) is that by applying 'sizeof' to a type you get the
number of bytes in the so called 'object representation' of that type.
If you multiply that value by CHAR_BIT, you'll get the number of bits in
the object representation of the type. But not all of those bits are
actually required to participate in the value representation. Some of
those object representation bits can remain "unused" (they are called
"padding" bits). For example, let's assume that on your platform
CHAR_BIT is 8. In this case on your platform the object representation
of both 'int' and 'long' contains 32 bits. But theoretically it is
possible that 'int' uses only 16 of those bits (and other 16 are just
padding) and 'long' uses all 32. In this case 'long' would be able to
take bigger numbers than 'int' and at the same time 'sizeof' of those
types would still be the same.

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #4
> Kevin wrote:
%cat float.c
main() {
float **m = malloc(5 * sizeof(float*)) ;
m[0] = malloc( sizeof(float) );
m[0][0] = 1.2;
printf("%f\n",m[0][0]);
}

Is this legal? I never really declare and assign so fast,
but I was wondering if it works because I'm lucky or if it
really is legal. Gcc doesn't like it much.

%gcc -c float.c
float.c: In function `main':
float.c:2: warning: initialization makes pointer from
integer without a cast float.c:3: warning: assignment
makes pointer from integer without a cast

Andrey Tarasevich wrote: You forgot do declare 'malloc' functions. That's what causes
the warning, since the compiler assumes that 'malloc' returns
an 'int'. Place '#include <stdlib.h>' at the beginning of your
source file and the warning will go away.

You also forgot to declare 'printf' function. 'printf' is a
variadic function. It mast be declared before use, or the
behavior is undefined.
Add '#include <stdio.h>' at the beginning of your source file.

Otherwise, the code is legal.


Depends what you mean by 'legal'? ;)

The implicit int declaration requires a diagnostic in C99. The
lack of return value from main means the status returned to the
host is undefined in C90. There is also the small matter of not
checking the return value from malloc.

--
Peter

Nov 14 '05 #5
On Thu, 17 Mar 2005 15:28:46 -0800,
Andrey Tarasevich <an************ **@hotmail.com> wrote:
Kevin wrote:
...
> Question 2:
>
> (gdb) p sizeof(int)
> $1 = 4
> (gdb) p sizeof(long)
> $2 = 4
>
> I was expecting to see long a little bigger.
> Why are they the same size?

Why not? This is perfectly legal in C. 'long' is notrequired> to be bigger than 'int'.

But if they take the same amount of bytes, then how is it
possible that long can take bigger numbers?
...


Well, the _guaranteed_ range of type 'long' is indeed wider
than that of type 'int' (per C99 standard). But in actual
implementation it is not required to be strictly wider.
Internally 'int' and 'long' can be implemented in exactly the
same way, which is the case on your platform, I'm sure.


Yes, you're right about my platform.
A more pedantic answer (which you probably don't care about, so
you can stop reading now :) is that by applying 'sizeof' to a
That's the answer I was looking for :-) Thank you.
type you get the number of bytes in the so called 'object
representation' of that type. If you multiply that value by
CHAR_BIT, you'll get the number of bits in the object
representation of the type. But not all of those bits are
actually required to participate in the value representation.
Some of those object representation bits can remain "unused"
(they are called"padding" bits). For example, let's assume that
on your platform CHAR_BIT is 8. In this case on your platform
the object representation of both 'int' and 'long' contains 32
bits. But theoretically it is possible that 'int' uses only 16
of those bits (and other 16 are just padding) and 'long' uses
all 32. In this case 'long' would be able to take bigger
numbers than 'int' and at the same time 'sizeof' of those types
would still be the same.


I see. That's what happens here then. I get 4 bytes in int, but I
can't use them all. That explains. The reason why an int takes 4
bytes is probably for compilers/whatever have an easy time
dealing with it. Is that right?

So anyway, if on my platform they both take the same amount of
bytes, I would conclude that I should never use an int (unless to
conform with a function prototype or something) because I will
consume the same amount of bytes when using a long. And by using
a long, at least I will have the freedom to use all the bits I
allocated.

Am I right, here? Or did I misunderstand everything? Thank you.
Nov 14 '05 #6
Kevin wrote:
...
A more pedantic answer (which you probably don't care about, so
you can stop reading now :) is that by applying 'sizeof' to a


That's the answer I was looking for :-) Thank you.
type you get the number of bytes in the so called 'object
representation' of that type. If you multiply that value by
CHAR_BIT, you'll get the number of bits in the object
representation of the type. But not all of those bits are
actually required to participate in the value representation.
Some of those object representation bits can remain "unused"
(they are called"padding" bits). For example, let's assume that
on your platform CHAR_BIT is 8. In this case on your platform
the object representation of both 'int' and 'long' contains 32
bits. But theoretically it is possible that 'int' uses only 16
of those bits (and other 16 are just padding) and 'long' uses
all 32. In this case 'long' would be able to take bigger
numbers than 'int' and at the same time 'sizeof' of those types
would still be the same.


I see. That's what happens here then. I get 4 bytes in int, but I
can't use them all. That explains. The reason why an int takes 4
bytes is probably for compilers/whatever have an easy time
dealing with it. Is that right?

So anyway, if on my platform they both take the same amount of
bytes, I would conclude that I should never use an int (unless to
conform with a function prototype or something) because I will
consume the same amount of bytes when using a long. And by using
a long, at least I will have the freedom to use all the bits I
allocated.

Am I right, here? Or did I misunderstand everything? Thank you.


I don't think this is the case. You must've misunderstood me. The reason
I called the above answer "pedantic" (and the reason I assumed that you
don't care about it) is that normally in practice objects of integral
types don't contain any padding bits (unless you are working on some
very exotic platform).

In your case, I'm [almost] sure, all bits of an 'int' object are used in
the value representation of that type. The C standard requires that
objects of type 'int' can hold _at_ _least_ values in -32767 - +32767
range. Note: _at_ _least_. Which means that if on some platform objects
of type 'int' can hold values in -2147483647 - +2147483647 range (which
also happens to be the guaranteed range of 'long' type), the
requirements of the standard are still formally satisfied. You simply
got a "free extension" of the range of your 'int' type. You can use this
"free extension" as you see fit. Bot keep in mind that if you want your
code to be absolutely portable, you shouldn't rely on the 'int's range
being that wide. On some other platform it could happen to be only
-32767 - +32767.

Once again, the specification of the C language doesn't require type
'int' to be neither narrower (in terms of value range) nor smaller (in
therms of 'sizeof') than type 'long'.

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #7
On Thu, 17 Mar 2005 16:32:46 -0800,
Andrey Tarasevich <an************ **@hotmail.com> wrote:
Kevin wrote:
...
A more pedantic answer (which you probably don't care about,so> you can stop reading now :) is that by applying 'sizeof'
to a

That's the answer I was looking for :-) Thank you.
type you get the number of bytes in the so called 'object
representation' of that type. If you multiply that value by
CHAR_BIT, you'll get the number of bits in the object
representation of the type. But not all of those bits are
actually required to participate in the value

representation .> Some of those object representation bits can
remain "unused"> (they are called"padding" bits). For example,
let's assume that> on your platform CHAR_BIT is 8. In this
case on your platform> the object representation of both 'int'
and 'long' contains 32> bits. But theoretically it is possible
that 'int' uses only 16> of those bits (and other 16 are just
padding) and 'long' uses> all 32. In this case 'long' would be
able to take bigger> numbers than 'int' and at the same time
'sizeof' of those types> would still be the same.

I see. That's what happens here then. I get 4 bytes in int,
but I can't use them all. That explains. The reason why an
int takes 4 bytes is probably for compilers/whatever have an
easy time dealing with it. Is that right?

So anyway, if on my platform they both take the same amount
of bytes, I would conclude that I should never use an int
(unless to conform with a function prototype or something)
because I will consume the same amount of bytes when using a
long. And by using a long, at least I will have the freedom
to use all the bits I allocated.

Am I right, here? Or did I misunderstand everything? Thank
you.


I don't think this is the case. You must've misunderstood me.
The reason I called the above answer "pedantic" (and the reason
I assumed that you don't care about it) is that normally in
practice objects of integral types don't contain any padding
bits (unless you are working on some very exotic platform).


Okay, sorry then. Let's see if I understood you now.

In your case, I'm [almost] sure, all bits of an 'int' object
are used in the value representation of that type. The C
standard requires that objects of type 'int' can hold _at_
_least_ values in -32767 - +32767 range. Note: _at_ _least_.
Which means that if on some platform objects of type 'int' can
hold values in -2147483647 - +2147483647 range (which also
happens to be the guaranteed range of 'long' type), the
requirements of the standard are still formally satisfied. You
simply got a "free extension" of the range of your 'int' type.
You can use this"free extension" as you see fit. Bot keep in
mind that if you want your code to be absolutely portable, you
shouldn't rely on the 'int's range being that wide. On some
other platform it could happen to be only-32767 - +32767.


So, in my case (freebsd/intel) I have the benefit of having int
just as big as a long? But as I think you explained, I should not
rely on this, because my code may not be portable then.

Did I get it now?

I wrote:
(gdb) list 0
1 main() {
2
3 unsigned int i;
4 unsigned long j;
5
6 i = 4294967295U;
7 j = 4294967295U;
8
9
10 }
(gdb) p i
$4 = 4294967295
(gdb) p j
$5 = 4294967295

Thank you.
Nov 14 '05 #8
[on machine X, "sizeof(int )" and "sizeof(lon g)" are the same]
On Thu, 17 Mar 2005 15:03:23 -0800,
Andrey Tarasevich <an************ **@hotmail.com> wrote:
Why not? This is perfectly legal in C. 'long' is not required
to be bigger than 'int'.

In article <20************ *************** @hotmail.com>
Kevin <ke***@hotmail. com> wrote:But if they take the same amount of bytes, then how is it
possible that long can take bigger numbers?


Maybe it can't -- on machine X anyway.

An analogy might help. Suppose the motor-vehicle administration
(DMV or MVA or whatever it is called where you are) says that you
need a different kind of license to drive a motorcycle vs a car vs
a tractor-trailer. You only have a "regular car" license. Suppose
also that they say "a car must hold two or more people side by
side". If your vehicle holds eight people, two in front seats and
three in second and third row seats, is it a car? (What if it
holds two or so people but can pull a triple trailer? :-) )

The C standard says that an "int" variable must hold, at the least,
values in the range -32767 to +32767, and "long" has to cover at
least -2147483647 to +2147483647. If your "int" and "long" both
happen to hold values in the range -2147483648 to +2147483647, is
that sufficient?

It is not unusual for a standard (or a law) to set some sort of
"least quality required" limit, and for people to exceed that, for
whatever reason.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #9
Kevin wrote:
...
In your case, I'm [almost] sure, all bits of an 'int' object
are used in the value representation of that type. The C
standard requires that objects of type 'int' can hold _at_
_least_ values in -32767 - +32767 range. Note: _at_ _least_.
Which means that if on some platform objects of type 'int' can
hold values in -2147483647 - +2147483647 range (which also
happens to be the guaranteed range of 'long' type), the
requirements of the standard are still formally satisfied. You
simply got a "free extension" of the range of your 'int' type.
You can use this"free extension" as you see fit. Bot keep in
mind that if you want your code to be absolutely portable, you
shouldn't rely on the 'int's range being that wide. On some
other platform it could happen to be only-32767 - +32767.
So, in my case (freebsd/intel) I have the benefit of having int
just as big as a long?


Exactly!
But as I think you explained, I should not
rely on this, because my code may not be portable then.

Did I get it now?


Yes. Whether you should rely on this or not is up to you. You shouldn't
rely on this if you want you code to be absolutely-pedantically-formally
portable. In practice this level of formal portability is rarely
required. I, for example, work with several platforms, all of which use
plain 'int's with 32-bit value range. I have no problem relying on this
fact in my code, because I'm pretty sure that I'll never encounter a
16-bit-'int' platform in my field.

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

70
8867
by: Roy Yao | last post by:
Does it mean "(sizeof(int))* (p)" or "sizeof( (int)(*p) )" ? According to my analysis, operator sizeof, (type) and * have the same precedence, and they combine from right to left. Then this expression should equal to "sizeof( (int)(*p) )", but the compiler does NOT think so. Why? Can anyone help me? Thanks. Best regards. Roy
7
4632
by: nzanella | last post by:
Hello, I just thought I would share the following observation with the rest of the group. The sizeof operator seems to act differently according to whether the number of elements in the array is known. Hence when passing arrays to functions the number of elements in the array must always be passed as an argument. If STL is available then people can just use vectors of course. Anyways, I guess this stuff is pretty standard. Well, have a...
7
1929
by: dam_fool_2003 | last post by:
#include<stdio.h> int main(void) { unsigned int a=20,b=50, c = sizeof b+a; printf("%d\n",c); return 0; } out put: 24
12
2410
by: sonu | last post by:
#include<stdio.h> main() { int x=10,y; y=sizeof(++x); printf("x=%d\ny=%d\n",x,y); } Oput Put
9
6077
by: CptDondo | last post by:
I am missing something about structure declarations.... I am trying to get the size of a structure member using sizeof. my xml.h file (beware of line wrap): struct fieldSchedule_t { uint8_t action; uint16_t fromBearing, toBearing; };
40
3643
by: Spiros Bousbouras | last post by:
Do you have an example of an implementation where sizeof(short int) does not divide sizeof(int) or sizeof(int) does not divide sizeof(long int) or sizeof(long int) does not divide sizeof(long long int) ? Same question for the corresponding unsigned types.
12
3634
by: aarklon | last post by:
Is y >(8 * (sizeof(int) -1)) portable expression to find The MSB of an unsigned integer y ?? will this work in all the cases, all three of the representations C allows: 1) two's complement 2) ones'complement 3) signed magnitude.
27
5598
by: CodeMonk3y | last post by:
gotta question on sizeof keyword does the sizeof keyword calcuates the size at compile time or run time ?? -- Posted on news://freenews.netfront.net - Complaints to news@netfront.net --
2
1613
by: Fraser Ross | last post by:
class A{}; void func() { sizeof ( A (A()) ); sizeof ( ( A (A()) ) ); sizeof ( A ((A())) ); } The first operand is a type-id of a function. It doesn't compile with Comeau which is fine.
0
8676
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8608
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9161
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
6522
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5860
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4370
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4619
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3050
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2006
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.