Say in a statement like this
char var;
if( var == 'x');
Do we allocate any memory for 'x' at first place?
If yes, which is it (stack/data)?
Thanks!
The value 'x' may be stored directly in the code segment as part of the comparison instruction, or it may be stored in the code segment for an immediate load into a register, or in the data segment for an indirect load or compare. It is up to the compiler.
Almost every compiler targeting a capable architecture (16-bit and up) will put the constant for 'x' in the CPU instruction for comparison:
cmp r0, #'x'
The less capable architectures tend to put such constants in a table in const memory and either load it for comparison, or do the comparison directly from memory.
Here's a technique to answer some questions like this for any architecture targeted by an installed copy of GCC. Use the -S
flag to get an assembly source file for a suitable code fragment. Alternatively, use -Wa,-al
to get an assembly listing showing the actual bytes generated by the assembler. For example,
int foo(char var) {
if (var == 'x')
return 42;
return 17;
}
compiles with gcc -c -Wa,-al
on my Windows PC to produce
GAS LISTING C:\DOCUME~1\Ross\LOCALS~1\Temp/ccyDNLLe.s page 1 1 .file "q3715034.c" 2 .text 3 .p2align 4,,15 4 .globl _foo 5 .def _foo; .scl 2; .type 32; .endef 6 _foo: 7 0000 55 pushl %ebp 8 0001 31C0 xorl %eax, %eax 9 0003 89E5 movl %esp, %ebp 10 0005 807D0878 cmpb $120, 8(%ebp) 11 0009 5D popl %ebp 12 000a 0F94C0 sete %al 13 000d 48 decl %eax 14 000e 83E0E7 andl $-25, %eax 15 0011 83C02A addl $42, %eax 16 0014 C3909090 ret 16 90909090 16 90909090
The lines 7 and 9 are all that remain of the function entry boiler plate, and lines 11 and 16 are the function exit boiler plate. Line 8 clears the entire return value register to 0. Line 10 is the actual comparison var == 'x'
and you can see the magic number $120
in the cmpb $120, 8(%ebp)
instruction; the ASCII code for 'x'
is 120 decimal or 0x78 in hex. You can see the 0x78 in the .text segment at offset 8 where it is stored as a part of the CMPB instruction. The rest of the body implements the choice of return values from my sample fragment, taking advantage of the SETE instruction to make AL
be 1 if the comparison was true, or 0 otherwise. The remaining instructions DECL
, ANDL
, and ADDL
then generate either 17 or 42 depending on the initial value of the AL
register in the entire EAX
register which is where the return values from integer functions are stored in this architecture.
Anthony answered the practical side of things. Let me comment on the question from a more language theoretic point. The C++ standard defines literals to be rvalue expressions with the exception of string literals which are lvalue expressions referring to arrays. The C++ standard has a clear concept on what an object is. Basically, an object is something of an object type (int, double, MyClass, ...) that has an address. But pure rvalues of scalar types such as char
or double
are not considered objects. They are just values and don't refer to a memory location. This includes literals like 'x'
and 3.14
.
How and where a compiler stores these values is outside of the scope of the standard. It doesn't even have to store them directly. For example, an expression like x * 8
could be translated to assembly code which shifts the value of x three bits to the left.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With