Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

assigning a temp to a const ref member causes a segmentation fault

better explained by an example:

tok.h

#include <string>

static const char* defaultDelim = ".,;";

class Tokenizer {
public:
    Tokenizer():
        // 'delim' is the const ref member that is initialized by the temp string 
        delim( (altDelim.size())? altDelim : std::string(defaultDelim) ) 
    {}

    size_t scan(const std::string& str)
    { return str.find_first_of(delim); }

    static void setDelim(const std::string& d) { altDelim = d; }
private:
    static std::string altDelim;
    const std::string& delim;
};

main.cpp

#include <iostream>
using namespace std;

#include "tok.h"

std::string Tokenizer::altDelim;

int main()
{
    Tokenizer tok;

    size_t pos = tok.scan("hello, world");
    cout << pos << endl;
}

the program prints 0 which is wrong. The real code gets a seg fault.

I'd expect that the rule of prolonging the life span of a temp assigned to a const reference would hold here, but apparently it's not. Do you know the reason'?

like image 855
davka Avatar asked Oct 07 '22 07:10

davka


1 Answers

That rule doesn't apply to class members. This is stated in 12.2.5 of the C++03 standard:

A temporary bound to a reference member in a constructor's ctor-initializer
persists until the constructor exits.

Making the temporary last longer than that would imply that the temporary would have to be kept as part of the class so that its lifetime could be maintained. This would be impossible if the constructor was in a separate compilation unit, because the size of the class has to be known when the class is defined.

// header file
struct A {
  A();
  B &b;
};


// file1.cpp
void f()
{
  A a; // Reserve the size of a single reference on the stack.
}


// file2.cpp
A::A()
: b(B()) // b is referencing a temporary, but where do we keep it?
         // can't keep the temporary on the stack because the
         // constructor will return and pop everything off the stack.
         // Can't keep it in the class because we've already said the
         // class just contains a single reference.
{
}
like image 67
Vaughn Cato Avatar answered Oct 12 '22 10:10

Vaughn Cato