tags:

views:

166

answers:

5

Came across this one while browsing the response to another question on SO (References Vs Variable Gets). My question is that for all 64bit environments is it guaranteed that a reference to a variable will be of 64 bits even if the original had a lesser size? As in char references in 64bit environment would be >sizeof(char)? Is there any section in the standard which specifies this explicitly?

EDIT: For more clarity -- char c1 = 'a'; char& c2 = c1; My question is sizeof(c2) > sizeof(c1) in 64bit machines?

+2  A: 

Yes. All references are the size of the architecture's width; on a 64-bit system, everything from char to long double references are 64 bits long.

Delan Azabani
I doubt this answer. references are not mandated to have any storage. sizeof(reference) is always the same as sizeof(referrand). If referrand is of type 'char' it is 1 e.g.
Chubsdad
+4  A: 

Internally, references are just pointers. Pointers take up 32 bits on a 32-bit system, 64 bits on a 64-bit system, etc. You can get the size of a pointer by doing sizeof(char*).

All pointers are the same size no matter what they are pointing to; for instance, a char* is the same size as long*. So all pointers on 64-bit systems take up 64 bits.

musicfreak
Depends on the architecture. On some architectures, byte references are not only larger, they require two pointers. These are architectures where the smallest accessible memory size is a word but the C compiler treats chars as bytes (an alternative is for the compiler to treat chars as words which is perfectly legal according to the standard).
slebetman
+11  A: 

The Standard (ISO C++-03) says the following thing about references

It is unspecified whether or not a reference requires storage (3.7).

Please someone correct me if I am wrong or if I have not understood his question correctly.

EDIT:

My question is sizeof(c2) > sizeof(c1) in 64bit machines?

No, as @Chubsdad noticed sizeof(c2) = sizeof (c1), the relevant quote from the Standard is

When applied to a reference or a reference type, the result is the size of the referenced type. (ISO C++ $5.3.3/2)

Prasoon Saurav
This answers the last part of the question. People forget that there are lots of strange CPU architectures out there, even today in the supposedly modern age.
slebetman
No. sizeof(c2) is always sizeof(c1) as both c1 and c2 are of type 'char' which by definition is 1.
Chubsdad
@Chubsdad : `sizeof(c1)` is always 1, `c2` is an alias of `c1`. So sizeof(`c2`) should be equal to 1. But you are overlooking the fact that a internally a reference may be implemented using a pointer. IMHO this is `implementation defined` to be pedantic.
Prasoon Saurav
Internal implementation mechanisms will never alter a visible behavior which is mandated by the Standard. Since c2 is an alias for c1 which is of type 'char', the sizeof(c2) should always be 1, no matter how it is implemented internally.
Chubsdad
@Chubsdad : Can you show me the relevant section of the Standard where it has been written about this. I think even though `sizeof(c2) should be equal to sizeof(c1)`, this is implementation defined. If you don't find the relevant section please ask this question at SO on my behalf. Thank you. :)
Prasoon Saurav
$5.3.3/2 - 'When applied to a reference or a reference type, the result is the size of the referenced type.'
Chubsdad
@Chubsdad : Thanks, that made everything clear. Added the quote to my answer.
Prasoon Saurav
@Chubsdad : Please lift your downvote(in case if you have downvoted) because I have updated the post accordingly and which is not flawed IMHO.
Prasoon Saurav
Johannes Schaub - litb
@Johannes : Right, but have a look at the experiment performed by [@Jonathen Leffer](http://stackoverflow.com/users/15168/jonathan-leffler) [here](http://stackoverflow.com/questions/3744675/size-of-references-in-64bit-environments/3744884#3744884). Initially I was convinced that the behaviour would be implementation defined, but Chubsdad made me think otherwise and now again by looking at the experiment performed by @Jonathen I think I was right. What do you think?
Prasoon Saurav
@Prasoon I'm not sure what you mean. The points that @chubsdad made to this answer appear to be right to me.
Johannes Schaub - litb
@Johannes : But have a look at the experiment/code done/written by Jonathan Leffer at the bottom of this page once which made me think the behaviour may well be implementation defined.
Prasoon Saurav
@Prasoon Saurav: BTW, I did not downvote.
Chubsdad
@Prasoon Saurav: The experiment simply suggests that the size of a reference is unspecified. The difference between unspecified and implementation defined is that of consistency. Implementation specific behaviour is something that is consistent everytime on a given implementation (e.g. sizeof int). Unspecified is something that is not guaranteed to be consistent everytime (e.g. the initial value of an uninitialized non static local variable)
Chubsdad
@Chubsdad : Yes, valid point.
Prasoon Saurav
+7  A: 

$8.3.2/3 - It is unspecified whether or not a reference requires storage.

sizeof applied to references is basically the size of the referrand.

So if 'r' is a integer reference to 'i', it is unspecified if there is an actual storage for 'r'. However sizeof(r) internally stands for sizeof(i).

If 'r' is a reference to a 'char', the sizeof(r) will be always sizeof(char) == 1 by definition.

Chubsdad
...unless you're on an 8-bit system with maximum 256 bytes memory ;P
Delan Azabani
@Delan Azabani: sizeof(char) by definition is always 1 even if it takes 32 bits on an architecture.
Chubsdad
@Delan: Chubsdad is right. It's the `CHAR_BITS` constant that changes with the number of bits. `sizeof(char)` is defined to always be `1`.
sbi
I never actually said otherwise. I'm saying that references to `char` are 64 bits on a 64-bit system. `char` itself is 8 bits.
Delan Azabani
+1  A: 

Although sizeof(ref_var) returns the size of the referenced object, space is still required to store a reference in a structure, for instance, and in common implementations the space allocated to store a reference is the same as the space allocated to store a pointer. That may not be required by the standard, but this code at least shows the effect:

#include <iostream>
using namespace std;

char  c1 = 'a';
char &c2 = c1;
struct x
{
    char  c1;
    char  c2;
    char  c3;
    char  c4;
    int   i4a;
    char &r1; 
    int   i4b;
    int   i4c;
    x() : r1(c1) { }
};
struct y
{
    char  c1;
    char  c2;
    char  c3;
    char  c4;
    int   i4a;
    int   i4b;
    int   i4c;
};
int main()
{
    cout << sizeof(c2) << endl;
    cout << sizeof(y) << endl;
    cout << sizeof(x) << endl;
    return 0;
}

I make no pretense that it is 'great code' - it isn't - but it demonstrates a point. Compiled on MacOS X 10.6.4 with the C++ compiler from the GNU Compiler Collection (GCC 4.5.1) in default (64-bit) mode, the output is:

1
16
24

When compiled in 32-bit mode, the output is:

1
16
20

The first line of output demonstrates that 'sizeof(ref_var)' does indeed return the size of the referenced object. The second line shows that a structure with no reference in it has a size of 16 bytes. The third line shows that a very similar structure with a reference embedded in it at an 8-byte boundary (on a system where sizeof(int) == 4) is 8 bytes larger than the simpler structure under a 64-bit compilation and 4 bytes larger under a 32-bit compilation. By inference, the reference part of the structure occupies more than 4 bytes and not more than 8 bytes under the 64-bit compilation, and occupies not more than 4 bytes under the 32-bit compilation. This suggests that (in at least one popular implementation of C++) that a reference in a structure occupies the same amount of space as a pointer - as asserted in some of the other answers.

So, it may be implementation dependent, but the comment that a reference occupies the same space as a pointer holds true in at least one (rather widely used) implementation.

Jonathan Leffler
+1 for the experiment.... :)
Prasoon Saurav