On Wednesday, 5 September 2012 at 11:01:50 UTC, Artur Skawina wrote:
On 09/04/12 20:19, Era Scarecrow wrote:
 I ask you, how do you check if it's a null pointer? &s?

Yes, obviously. If you need to do that manually.

 But you shouldn't have to.

  int getx(ref S s)
  //How does this make sense?? it looks wrong and is misleading
  in {assert(&s); }
  body {return s.x); }

It looks correct and is perfectly obvious. But see below - you don't need to do this manually - the compiler does it for you when calling methods and could handle the UFCS case too.

How I'm understanding references in D (And perhaps I'm repeating myself in two different topics) is they point to live variables (IE guaranteed pointers), and remains this way until you return from that function.

This is entirely valid and simplifies things. Remember in D we want the language to 'do the right thing', but if you make references where it works to 'sometimes works' then it becomes a problem (pointers 'sometimes' work and are not @safe, while ref is @safe). Checking the address of a reference shouldn't be needed, since it should be dereferenced at where it was called at if need be (throwing it there).

Any side effects that may rely on the validity of the 'pointer' (once the function ends) are compromised afterwards (I'm always assume you pass local variables for this logic, since it's likely 80% of the time).

Would you REALLY want to mark every single function that uses ref as @trusted? You're then blindly telling the compiler to 'shut up' so you can use the code and ignoring the checking; Or am I wrong?

int getItem(string[] inp, string cmp) @safe {
  //foreach not @safe!
  //only works not @safe or blindly adding @trusted
  foreach(i, ref s; inp) {
    if (s == cmp)
      return i;
  }

  //still might not compile, if foreach calls opApply
  //(Even if it doesn't use the reference).
  foreach(i, s; inp) {
  }
}

More importantly, if it's now a possibility do we have to start adding checks everywhere?

  int getx(S *s)
in {assert(s); } //perfectly acceptable check, we know it's a pointer
  body {return s.x); }

   struct S { int i; auto f() { return i; } }
   int main() {
      S* s;
      return s.f();
   }

This program will assert at runtime (and (correctly) segfault in a release-build). The compiler inserts not-null-this checks for "normal" methods in non-release mode, and could also do that before invoking any UFCS "method". So you wouldn't need to check for '!!&this' yourself.

I thought those checks weren't added (via the compiler) since if it causes a seg fault the CPU would catch it and kill the program on it's own (just add debugging flags); If you added the checks they would do the same thing (More buck for the same bang).

The problem w/ these checks is that they can not be disabled per-type - which prevents certain valid uses. The compiler-inserted assertions fire also when the methods can deal with null-this themselves (happens eg. when dealing with 'C' APIs and libraries, when you want to keep the C part as unmodified as possible). But that is a different issue.


Reply via email to