Subject: [FFC-dev] Changed storage of constants from reference to copy in forms. This is [...]

From: [email-masked]
Date: Sun, 11 Sep 2005 13:16:19 +0200

Commit from johanjan (2005-09-11 13:16 CEST)
--------------------

Changed storage of constants from reference to copy in forms. This is
to avoid this type of subtle memory error:

class LinearForm
{
public:
 Linearform(real& c0) : c0(c0)
 {
 }
 real& c0;
}

class MySolver
{
public:
 MySolver(real c) : L(c)
 {
   // !!! After this constructor returns, the contents of LinearForm::c0 are
   // no longer allocated.
 }
 LinearForm L;
}

  ffc  src/ffc/format/dolfin.py  1.34

---

From: Anders Logg <[email-masked]>
Date: Sun, 11 Sep 2005 07:49:35 -0500

The reason it's a reference is that in a time-stepping loop, you want
to be able to give the time step k or time t as an argument to the
form and have it automatically get updated as you change k and t.

Maybe one should require that one uses references for the constants,
that is, the constant must exist in a variable outside of the form, in
the same way as a Function must exist outside of the form?

/Anders

On Sun, Sep 11, 2005 at 01:16:19PM +0200, [email-masked] wrote:
> _______________________________________________
> FFC-dev mailing list
> [email-masked]
> http://www.fenics.org/cgi-bin/mailman/listinfo/ffc-dev
> 

-- 
Anders Logg
Research Assistant Professor
Toyota Technological Institute at Chicago
http://www.tti-c.org/logg/

---

From: Johan Jansson <[email-masked]>
Date: Sun, 11 Sep 2005 15:11:09 +0200

> the same way as a Function must exist outside of the form?

Ah right, I'll change it back.

I think the only reason it's a problem is because basic types are
usually passed as copies, not references, and it's very common to
construct them on the stack. Maybe it's enough to just make a class
Constant? Then people would treat it just as a Function, and it could
also be generalized to being tensor-valued etc.

I don't think we can keep it this way. As soon as you construct a form
in a separate function from where you use it, you will run into this
issue. Consider:

LinearForm* L;

init()
{
  real c = 13.7;
  L = new LinearForm(c)
}

solve()
{
  L.assemble(); // Here L->c0 is undefined
}

If it wasn't for valgrind telling me exactly what the problem was, I
would have spent a long time scratching my head on this.

  Johan

---

From: Anders Logg <[email-masked]>
Date: Sun, 11 Sep 2005 08:34:19 -0500

ok, I understand. Let's create a new class Constant in DOLFIN as you
suggest, which is good since then Constant and Function work the same
way in FFC/DOLFIN: you have to declare a pair of corresponding objects
in FFC and DOLFIN.

Even if we do this, you could run into things like

init()
{
  Constant c(13.7);
  L = new LinearForm(c)
}

which would give you the same problem.

What if we overload a constructor LinearForm(real c) in addition to
LinearForm(const real& c)? Will that work?

/Anders