Don’t create reference from pointer (part 1/2)

When programming in C++ (or any other language) you can sometime hit very weird behavior. Like your “if” statements are ignored. You usually find this the hard way. Like when your program crashes. You check the debugger and you see, that it crashes on null pointer inside “if”. Yes the “if” that checks for null pointers. Strange.
Well in this post I will try to explain what is happening to your program.

In C++ we have something called a reference. Reference is basically an alias to some value/object. This alias has several key points defined in standard. Like a reference has to be bound to a valid object in declaration.

This binding in declaration has the effect that reference can not be null. You will basically always create a valid reference because it is an alias to something. This has some consequences in compilation and especially in resulting assembly.

In compilation compiler can detect when you are doing something wrong and warn you. In resulting assembly the optimizer can omit some checks because it knows, that the object is valid.

A little example

This post is going to explain you why checks are ignored, when using references. First, however lets see a little sample code without references. You will see that the binary doesn’t contain the “if” we put there.

Check this simple code:

int doSomething();

int main( int argc, char** argv )
    int i = 5;

    if( i == 5 )

    return 0;

This is the assembly result when no optimization is applied.

        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $32, %rsp
        movl    %edi, -20(%rbp)
        movq    %rsi, -32(%rbp)
        movl    $5, -4(%rbp)
        cmpl    $5, -4(%rbp)
        jne     .L2
        call    _Z11doSomethingv
        movl    $0, %eax
        .cfi_def_cfa 7, 8

This is with -O3 passed to GCC compiler

        subq    $8, %rsp
        .cfi_def_cfa_offset 16
        call    _Z11doSomethingv
        xorl    %eax, %eax
        addq    $8, %rsp
        .cfi_def_cfa_offset 8

As you can see the compiled just completely ignored the “if” in the optimized build. Why? Because it knows, that the “if” will always evaluate to true.

This simple code and compiled assembly showed that compiler do some analysis based on what it knows. The same will apply to references. More on that in the second part of this article.

Building RPM – BuildRoot ignored

BuildRoot: %{_tmppath}/%{name}-%{version}-build

Will not be taken into account, because it is overwriten by .rpmrc or rpmbuild cmd line –buildroot
This behavior was introduced in rpm version 4.6.0 ( which was released 6th of January 2009 ). The BuildRoot should not be used any more, because to cite rpm mailing list:

Buildroot from spec is ignored on purpose in rpm 4.6.0. That specs should
(have to) define their own buildroot is simply bad design and a leftover
from ancient times.

The new default build root directory is simple:


So this explains a lot. If you are like me and read all kind of rpm tutorials on the internet. Then wonder why the hell it does not work as expected.
It is pity that this little detail is not mentioned in some tutorials, created even after 2009.