Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where are literals stored in statement like this if( var == 'x')?

Tags:

c++

c

syntax

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!

like image 229
KedarX Avatar asked Sep 15 '10 06:09

KedarX


4 Answers

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.

like image 157
Anthony Williams Avatar answered Nov 01 '22 12:11

Anthony Williams


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.

like image 42
wallyk Avatar answered Nov 01 '22 13:11

wallyk


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.

like image 4
RBerteig Avatar answered Nov 01 '22 13:11

RBerteig


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.

like image 1
sellibitze Avatar answered Nov 01 '22 11:11

sellibitze