tags:

views:

69

answers:

2

This code:

int main(char[][] args)
{
  MyObject obj;
  obj.x;
  return 0;
}

gives me: Error: null dereference in function _Dmain when I compile it with -O flag (on dmd2) Why? Isn't obj allocated on the stack? Should I always use new to create objects?

A: 

I don't read your code all that well since I'm a VB guy, but it looks like you're initiating an object without it having a value.

You create an object called obj You call obj.x then you return "0" (zero)

what exactly are you doing? I'm pretty sure obj needs to be NEW, and you need to be returning something other than a physical "0"

rockinthesixstring
0 indicates success. It's an UNIX thing.
DK
All variables in D are automatically initialized with a default value if you don't give it one. In the case of references to objects, that value is null - hence why it's complaining that he's attempting to deference a null reference.
Jonathan M Davis
so the main point is still valid (forgetting about the zero), it needed to be initialized as "NEW".
rockinthesixstring
Yes. The main point is definitely valid. The problem is that the variable was initialized with null rather than assigning an actual object to it (presumably with `new` in this case). It's just that in D, it's not going to be an uninitialized value. Rather it's a default-initialized value. So, you get `null` instead of garbage. It's still an error, but it's a well-defined one which will be completely deterministic regardless of your platform or compiler implementation.
Jonathan M Davis
+8  A: 

Summary: you have to new objects. Always.

D's classes are closer to C# or Java than C++. Specifically, objects are always, always reference values.

MyObject is, under the hood, a pointer to the actual object. Thus, when you use MyObject obj;, you're creating a null pointer, and have not, in fact, created an object. An object must be created using the new operator:

auto obj = new Object();

This creates obj on the heap.

You cannot directly construct objects on the stack in D. The best you can do is something like this:

scope obj = new MyObject;

The compiler is allowed to place the object on the stack, but doesn't have to.

(Actually, I suspect this might be going away in a future version of D2.)

On a side note, if you are using D2, then I believe your main function should look like this:

int main(string[] args)
{
    ...
}

char[] and string have the same physical layout, but mean slightly different things; specifically, string is just an alias for immutable(char)[], so by using char[] you're circumventing the const system protections.

DK
So... is `MyObject *obj` a pointer to obj or actually a double pointer to obj? i.e. can I cast pointers to objects assuming it is OK?
Zeex
@serejko `MyObject* obj` would be a pointer to reference to an object, which would generally be a very weird thing to do. Generally, you shouldn't be using pointers in D. They're there if you need them, but they're not safe, and you generally don't need them. I would really suggest reading the documentation on the Digital Mars site in more detail. And even better, if you can afford it, pick up the new book *The D Programming Language* by Andrei Alexandrescu. It explains things quite well overall.
Jonathan M Davis
@DK `scope` in that context is definitely being phased out as I understand it, but it does still work for the moment. I believe that the idea at this point is that if you want to have user-defined types with finite lifetimes (e.g. being destroyed when existing the scope that they're created in), you should be using structs.
Jonathan M Davis
@Jonathan Pointers aren't necessarily unsafe. Provided you only take them to heap memory and don't cast them to incompatible types and don't do unchecked arithmetic on them, they're perfectly safe. It's only when you do stupid things like escaping stack memory or dividing a pointer by your height in furlongs that Bad Things happen.As for phasing out scope, it's a bloody stupid decision; I'll just leave it at that.
DK
@DK Well, in theory, SafeD allows whatever uses of pointers are safe and disallows the rest, so if you stick to SafeD, it should be fine and fairly clear. Getting a pointer from `in` with associative arrays would be a safe case, for instance. Still, D is designed such that pointers are not needed anywhere near as much as in C or C++, and if you don't specifically need them for whatever you're doing it's best to avoid them. In particular, classes are already reference types, so it generally would make no sense to use pointers with them.
Jonathan M Davis