ccpu-architecturemicro-optimizationmachine-instructionlow-level-code

C programming and error_code variable efficiency


Most code I have ever read uses a int for standard error handling (return values from functions and such). But I am wondering if there is any benefit to be had from using a uint_8 will a compiler -- read: most C compilers on most architectures -- produce instructions using the immediate address mode -- i.e., embed the 1-byte integer into the instruction ? The key instruction I'm thinking about is the compare after a function, using uint_8 as its return type, returns.

I could be thinking about things incorrectly, as introducing a 1 byte type just causes alignment issues -- there is probably a perfectly sane reason why compiles like to pack things in 4-bytes and this is possibly the reason everyone just uses ints -- and since this is stack related issue rather than the heap there is no real overhead.

Doing the right thing is what I'm thinking about. But lets say say for the sake of argument this is a popular cheap microprocessor for a intelligent watch and that it is configured with 1k of memory but does have different addressing modes in its instruction set :D

Another question to slightly specialize the discussion (x86) would be: is the literal in:

uint_32 x=func(); x==1;

and

uint_8 x=func(); x==1;

the same type ? or will the compiler generate a 8-byte literal in the second case. If so it may use it to generate a compare instruction which has the literal as an immediate value and the returned int as a register reference. See CMP instruction types..

Another Refference for the x86 Instruction Set.


Solution

  • Here's what one particular compiler will do for the following code:

    extern int foo(void) ;
    void bar(void)
    {
            if(foo() == 31) { //error code 31
                    do_something();
            } else {
                    do_somehing_else();
            }
    }
    
       0:   55                      push   %ebp
       1:   89 e5                   mov    %esp,%ebp
       3:   83 ec 08                sub    $0x8,%esp
       6:   e8 fc ff ff ff          call   7 <bar+0x7>
       b:   83 f8 1f                cmp    $0x1f,%eax
       e:   74 08                   je     18 <bar+0x18>
      10:   c9                      leave
      11:   e9 fc ff ff ff          jmp    12 <bar+0x12>
      16:   89 f6                   mov    %esi,%esi
      18:   c9                      leave
      19:   e9 fc ff ff ff          jmp    1a <bar+0x1a>
    

    a 3 byte instruction for the cmp. if foo() returns a char , we get b: 3c 1f cmp $0x1f,%al

    If you're looking for efficiency though. Don't assume comparing stuff in %a1 is faster than comparing with %eax