简体   繁体   中英

C why would a pointer be larger than an integer

I am playing around with sizeof() in GCC on a linux machine right now and I found something very surprising.

printf ("\nsize of int = %lu\n", sizeof(int));
printf ("\nsize of int* = %lu\n", sizeof(int *));

yields

size of int = 4
size of int* = 8

I thought the size of a pointer to an integer would be much smaller than the actual integer itself!

I am researching embedded software right now and I was under the understanding that passing by reference was more efficient ( in terms of power ) than passing by value.

Could someone please clarify why it is more efficient to pass by reference than by value if the size of the pointer is larger than the actual value.

Thanks!

Integer can be any size the compiler writer likes, the only rules (in standard C) are: a) int isn't smaller than a short or bigger than a long, and b) int has at least 16 bit.

It's not uncommon on a 64bit platform to keep int as 32bits for compatibility.

Passing by reference is more efficient than passing by value when the value to be passed is larger than the size of the reference. It makes a lot of sense to pass by reference if what you are passing is a large struct/object. It also makes sense to pass a reference if you want to make persistent modifications to your value.

Passing by reference is more efficient because no data (other than the pointer) needs to be copied. This means that this is only more efficient when passing classes with many fields or structs or any other data that is larger than a pointer on the system used.

In the case you mentioned it could indeed be more efficient to not use a pointer because the actual value is smaller than a pointer to it (at least on the machine you were using). Bare in mind that on a 32 bit-machine a pointer has 4 bytes (4*8 = 32bits) while on the 64-bit machine you were apparently using the pointer has 8 bytes (8*8 = 64bits).

On even older 16 bit machines pointers do only require 2 bytes, maybe there are some embedded systems still using this architecture, but I don't know about this...

In C, a pointer, any pointer, is just a memory address. You're on a 64-bit machine, and at the hardware level, memory addresses are referred to with 64-bit values. This is why 64-bit machines can use much more memory than 32-bit machines.

A pointer to an integer can point at a single integer, but the same pointer can also point at ten, twenty, one hundred or one million integers.

Obviously passing a single 8 byte pointer in lieu of a single 4 byte integer is not a win; but passing a single 8 byte pointer in lieu of one million 4 byte integers certainly is.

One thing has nothing to do with the other. One is an address, a pointer to something, doesnt matter if that is a char or short or int or structure. The other is a language specific thing called an int, which the compiler for that system and that version of compiler and perhaps command line options happens to define as some size.

It appears as if you are running on a 64 bit system so all your pointers/addresses are going to be 64 bit. What they point to is a separate discussion, longs are probably going to be 64 bits as well, sometimes ints, shorts probably still 16 bit but not a hard/fast rule and chars hopefully 8 bits, but also not a hard/fast rule.

Where this can get even worse is cross compiling, while using llvm-gcc, before clang was as solid as it is now. With a 64 bit host the bytecode was all being generated based on the 64 bit host, so 64 bit integers, 64 bit pointers, etc. then when you do the backend for the arm target it had to use compiler library calls for all of this 64 bit work. The variables hardly needed to be shorts much less ints, but were ints. the -m32 switch was broken you still got 64 bit integers due to the host not the ultimate target. gcc directly doesnt appear to have this problem and clang+llvm doesnt currently have this problem either.

The short answer is the language defines some data types char, short, int, long, etc and those data types have a compiler implementation defined size. and address is just another implementation defined data type. it is like asking why is a short not the same number of bytes as a long? Because they are different data types one is a short, one is a long. One is an address the other is a variable, two different things.

http://developers.sun.com/solaris/articles/ILP32toLP64Issues.html

When converting 32-bit programs to 64-bit programs, only long types and pointer types change in size from 32 bits to 64 bits; integers of type int stay at 32 bits in size.

In 64-bit executables, pointers are 64-bits. Long ints are also 64-bits, but ints are only 32-bits.

In 32-bit executables, pointers, int's and long ints are all 32-bits. 32-bit executables also support 64-bit "long long" ints.

A pointer must be able to reference all of memory. If the (virtual) memory is larger than 4 Gi bytes or so, then the pointer must be more than 32 bits.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM