www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D newb

reply Tim H <thockin+d hockin.org> writes:
Hi, I am a D newbie.  Why does this program segfault?

import std.stdio;
import std.c.stdlib;

class Foo
{
        public int m_int = 0;
}

int
main(string[] args)
{
        Foo f;
        printf("foo %d\n", f.m_int);
        return EXIT_SUCCESS;
}
Aug 17 2008
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Tim,

 Hi, I am a D newbie.  Why does this program segfault?
 
 import std.stdio;
 import std.c.stdlib;
 class Foo
 {
 public int m_int = 0;
 }
 int
 main(string[] args)
 {
 Foo f;
 printf("foo %d\n", f.m_int);
 return EXIT_SUCCESS;
 }
The default value for any object Reference (f in this case) is null. create a new object to use (Foo f = new F();)
Aug 17 2008
parent reply Tim H <thockin+d hockin.org> writes:
BCS Wrote:

 Reply to Tim,
 
 Hi, I am a D newbie.  Why does this program segfault?
 
 import std.stdio;
 import std.c.stdlib;
 class Foo
 {
 public int m_int = 0;
 }
 int
 main(string[] args)
 {
 Foo f;
 printf("foo %d\n", f.m_int);
 return EXIT_SUCCESS;
 }
The default value for any object Reference (f in this case) is null. create a new object to use (Foo f = new F();)
Doh, can you guess what language I am coming from? :) Is there any way to do C++ style on-stack local object ?
Aug 17 2008
next sibling parent BCS <ao pathlink.com> writes:
Reply to Tim,

 BCS Wrote:
 
 Reply to Tim,
 
 Hi, I am a D newbie.  Why does this program segfault?
 
 import std.stdio;
 import std.c.stdlib;
 class Foo
 {
 public int m_int = 0;
 }
 int
 main(string[] args)
 {
 Foo f;
 printf("foo %d\n", f.m_int);
 return EXIT_SUCCESS;
 }
The default value for any object Reference (f in this case) is null. create a new object to use (Foo f = new F();)
Doh, can you guess what language I am coming from? :) Is there any way to do C++ style on-stack local object ?
"scope" look it up in the classes spec page (I have not used it myself)
Aug 17 2008
prev sibling next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Tim H wrote:
 BCS Wrote:
 
 Reply to Tim,

 Hi, I am a D newbie.  Why does this program segfault?

 import std.stdio;
 import std.c.stdlib;
 class Foo
 {
 public int m_int = 0;
 }
 int
 main(string[] args)
 {
 Foo f;
 printf("foo %d\n", f.m_int);
 return EXIT_SUCCESS;
 }
The default value for any object Reference (f in this case) is null. create a new object to use (Foo f = new F();)
Doh, can you guess what language I am coming from? :) Is there any way to do C++ style on-stack local object ?
scope Foo f = new Foo(); The "scope" keyword in the declaration says to the compiler "this will not escape the function" thus creating the data on the stack. "f" is still a reference type in this case, however (although it may not be implemented as a reference -- that's up o the compiler).
Aug 17 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
Robert Fraser:
 scope Foo f = new Foo();
 
 The "scope" keyword in the declaration says to the compiler "this will 
 not escape the function" thus creating the data on the stack. "f" is 
 still a reference type in this case, however (although it may not be 
 implemented as a reference -- that's up o the compiler).
But the 'scope' works only in some situations, the original poster can take a look at the docs about 'scope'. My question: does the compiler raise a compilation error if the 'scope' keyword is used where the compiler can't actually allocate the class on the stack? (if not, then I think it may be better for the compiler to raise such error, avoiding the illusion of efficiency). Bye, bearophile
Aug 17 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"bearophile" wrote
 Robert Fraser:
 scope Foo f = new Foo();

 The "scope" keyword in the declaration says to the compiler "this will
 not escape the function" thus creating the data on the stack. "f" is
 still a reference type in this case, however (although it may not be
 implemented as a reference -- that's up o the compiler).
But the 'scope' works only in some situations, the original poster can take a look at the docs about 'scope'. My question: does the compiler raise a compilation error if the 'scope' keyword is used where the compiler can't actually allocate the class on the stack? (if not, then I think it may be better for the compiler to raise such error, avoiding the illusion of efficiency).
In what situations does it not work? As long as the class is not too large for the stack (which is very unlikely), it should be able to allocate. -Steve
Aug 17 2008
parent reply JAnderson <ask me.com> writes:
Steven Schveighoffer wrote:
 "bearophile" wrote
 Robert Fraser:
 scope Foo f = new Foo();

 The "scope" keyword in the declaration says to the compiler "this will
 not escape the function" thus creating the data on the stack. "f" is
 still a reference type in this case, however (although it may not be
 implemented as a reference -- that's up o the compiler).
But the 'scope' works only in some situations, the original poster can take a look at the docs about 'scope'. My question: does the compiler raise a compilation error if the 'scope' keyword is used where the compiler can't actually allocate the class on the stack? (if not, then I think it may be better for the compiler to raise such error, avoiding the illusion of efficiency).
In what situations does it not work? As long as the class is not too large for the stack (which is very unlikely), it should be able to allocate. -Steve
If the class has a component sub-class the component may be heap allocated. I don't agree with making that an error though. -Joel
Aug 17 2008
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"JAnderson" wrote
 Steven Schveighoffer wrote:
 "bearophile" wrote
 Robert Fraser:
 scope Foo f = new Foo();

 The "scope" keyword in the declaration says to the compiler "this will
 not escape the function" thus creating the data on the stack. "f" is
 still a reference type in this case, however (although it may not be
 implemented as a reference -- that's up o the compiler).
But the 'scope' works only in some situations, the original poster can take a look at the docs about 'scope'. My question: does the compiler raise a compilation error if the 'scope' keyword is used where the compiler can't actually allocate the class on the stack? (if not, then I think it may be better for the compiler to raise such error, avoiding the illusion of efficiency).
In what situations does it not work? As long as the class is not too large for the stack (which is very unlikely), it should be able to allocate. -Steve
If the class has a component sub-class the component may be heap allocated. I don't agree with making that an error though.
If the class allocates anything dynamically, it would be heap allocated. I think there's no way around that. for instance, C++'s vector class can be stack allocated, but the elements will be heap allocated. However, a frequently asked-for enhancement is to allow scope members which could be allocated as part of the class' space (and therefore would be allocated on the stack in the case of a scope allocated class). -Steve
Aug 17 2008
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Joel Anderson:
 bearophile:
 My question: does the compiler raise a compilation error if the 'scope' 
 keyword is used where the compiler can't actually allocate the class on 
 the stack? (if not, then I think it may be better for the compiler to 
 raise such error, avoiding the illusion of efficiency).
If the class has a component sub-class the component may be heap allocated. I don't agree with making that an error though.
May I ask you why you don't like that as an error? Generally I don't like undefined situations, if I add the 'scope' keyword I want the class to be stack-allocated, and I assume the compiler does that. Then the layout of the memory used by the code is different, and I can for example take care to avoid a stack overflow. If the compiler at compile time is able to tell me that the class can't be allocated on the stack, then I think the program has to not compile until I remove the 'scope' keyword there. This makes the code reflect what the program actually does. Bye, bearophile
Aug 18 2008
parent reply JAnderson <ask me.com> writes:
bearophile wrote:
 Joel Anderson:
 bearophile:
 My question: does the compiler raise a compilation error if the 'scope' 
 keyword is used where the compiler can't actually allocate the class on 
 the stack? (if not, then I think it may be better for the compiler to 
 raise such error, avoiding the illusion of efficiency).
If the class has a component sub-class the component may be heap allocated. I don't agree with making that an error though.
May I ask you why you don't like that as an error? Generally I don't like undefined situations, if I add the 'scope' keyword I want the class to be stack-allocated, and I assume the compiler does that. Then the layout of the memory used by the code is different, and I can for example take care to avoid a stack overflow. If the compiler at compile time is able to tell me that the class can't be allocated on the stack, then I think the program has to not compile until I remove the 'scope' keyword there. This makes the code reflect what the program actually does. Bye, bearophile
What I'm talking about is: class A { } class B { ... A a = new A(); // Heap Allocated ... }; ... scope B b = new B; //B is scope allocated but A is not Say your using someone else's class. You get latest and you using one of there classes with the word scope. They've decided to add something that is heap allocated. Now suddenly your code is not working because someone made a slight change to their interface. Of course you might not be responsible for either pieces of code. You might be using a template from lib A to iterate over some class in lib B. Anyway what ends up happening is the code becomes very un-generic. People have to create 2 versions of everything. I think the idea of having scope members is a good one. However if your using someone else class that has heap allocation you really have no choice. If you make this an error then your limiting that classes use. As to the class overflowing the stack size. I think if a class is so big that that the compiler automatically heap allocates it, then there's a lot of other issues with your code or your running on some platform where it works better that way. The compiler should do what it can to make sure your code runs, slow as it may be, without logical errors. I think you always want to tell the compiler what you want to do rather then how and let it decide the best approach. That way you get more portable code that is optimized for whatever system its going on. -Joel
Aug 18 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"JAnderson" wrote
 bearophile wrote:
 Joel Anderson:
 bearophile:
 My question: does the compiler raise a compilation error if the 
 'scope' keyword is used where the compiler can't actually allocate the 
 class on the stack? (if not, then I think it may be better for the 
 compiler to raise such error, avoiding the illusion of efficiency).
If the class has a component sub-class the component may be heap allocated. I don't agree with making that an error though.
May I ask you why you don't like that as an error? Generally I don't like undefined situations, if I add the 'scope' keyword I want the class to be stack-allocated, and I assume the compiler does that. Then the layout of the memory used by the code is different, and I can for example take care to avoid a stack overflow. If the compiler at compile time is able to tell me that the class can't be allocated on the stack, then I think the program has to not compile until I remove the 'scope' keyword there. This makes the code reflect what the program actually does. Bye, bearophile
What I'm talking about is: class A { } class B { ... A a = new A(); // Heap Allocated ... }; ... scope B b = new B; //B is scope allocated but A is not Say your using someone else's class. You get latest and you using one of there classes with the word scope. They've decided to add something that is heap allocated. Now suddenly your code is not working because someone made a slight change to their interface.
The compiler cannot know when a constructor will decide to heap-allocate. So it cannot predict whether the entire class will be stack-allocated. Once the constructor is called, you cannot extend the previous stack frame (without a lot of extra work), and even then, it cannot be sure that the calling function won't use that stack space later in the function. I think what you ask for is impossible to implement, and impossible to detect. -Steve
Aug 19 2008
parent JAnderson <ask me.com> writes:
Steven Schveighoffer wrote:
 "JAnderson" wrote
 bearophile wrote:
 Joel Anderson:
 bearophile:
 My question: does the compiler raise a compilation error if the 
 'scope' keyword is used where the compiler can't actually allocate the 
 class on the stack? (if not, then I think it may be better for the 
 compiler to raise such error, avoiding the illusion of efficiency).
If the class has a component sub-class the component may be heap allocated. I don't agree with making that an error though.
May I ask you why you don't like that as an error? Generally I don't like undefined situations, if I add the 'scope' keyword I want the class to be stack-allocated, and I assume the compiler does that. Then the layout of the memory used by the code is different, and I can for example take care to avoid a stack overflow. If the compiler at compile time is able to tell me that the class can't be allocated on the stack, then I think the program has to not compile until I remove the 'scope' keyword there. This makes the code reflect what the program actually does. Bye, bearophile
What I'm talking about is: class A { } class B { ... A a = new A(); // Heap Allocated ... }; ... scope B b = new B; //B is scope allocated but A is not Say your using someone else's class. You get latest and you using one of there classes with the word scope. They've decided to add something that is heap allocated. Now suddenly your code is not working because someone made a slight change to their interface.
The compiler cannot know when a constructor will decide to heap-allocate. So it cannot predict whether the entire class will be stack-allocated. Once the constructor is called, you cannot extend the previous stack frame (without a lot of extra work), and even then, it cannot be sure that the calling function won't use that stack space later in the function. I think what you ask for is impossible to implement, and impossible to detect. -Steve
I agree, however it could know weather members are likely to be heap allocated or not. However I don't think that should raise errors. -Joel
Aug 19 2008
prev sibling parent JAnderson <ask me.com> writes:
Tim H wrote:
 
 Doh, can you guess what language I am coming from? :)
This page might be helpful then: http://prowiki.org/wiki4d/wiki.cgi?ShortFrequentAnswers -Joel
Aug 17 2008
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Tim H., others have already answered your main question. Regarding your code:

Add the list of names you want to use, importing just the names you need,
avoiding namespace pollution:
import std.c.stdlib: writefln;


         public int m_int = 0;
This is enough: public int m_int; Because variables are initialized to .init by default (and there's a way to avoid that), and int.init is 0.
 int main(string[] args)
You can use this, because the return value is automatic: void main() To print writef/writefln is generally better, because typesafe (but it makes your executable fatter): writefln(foo %d", f.m_int); Bye, bearophile
Aug 17 2008
next sibling parent reply Tim H <thockin+d hockin.org> writes:
bearophile Wrote:


         public int m_int = 0;
This is enough: public int m_int; Because variables are initialized to .init by default (and there's a way to avoid that), and int.init is 0.
So every variable is 0 initialized?
 int main(string[] args)
You can use this, because the return value is automatic: void main()
If I want to return a value other than 0, how do I do it?
 To print writef/writefln is generally better, because typesafe (but it makes
your executable fatter):
 writefln(foo %d", f.m_int);
What does that mean - to be typesafe? Can you give me a real example of where writef() is better than printf(). I'm looking for a good D tutorial. Something that would have all these answers. Can you recommend one? I've been writing C for a dozen years and C++ for a few, as well as other stuff here and there. Tim
Aug 17 2008
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Tim H" wrote
 bearophile Wrote:


         public int m_int = 0;
This is enough: public int m_int; Because variables are initialized to .init by default (and there's a way to avoid that), and int.init is 0.
So every variable is 0 initialized?
No, every variable is initialized to a default. Most of the time, this is zero (or null). However, sometimes, it is not. For instance, floating point numbers are initialized to NaN. If you want to know the initial value, it is stored as the inherent 'init' property. So for example, all ints are initialized to int.init (unless you override that with an assignment).
 int main(string[] args)
You can use this, because the return value is automatic: void main()
If I want to return a value other than 0, how do I do it?
The way you originally had it. I think bearophile was saying that in your particular example, you don't need to use it, because you never return anything but zero (EXIT_SUCCESS).
 To print writef/writefln is generally better, because typesafe (but it 
 makes your executable fatter):
 writefln(foo %d", f.m_int);
What does that mean - to be typesafe? Can you give me a real example of where writef() is better than printf().
Sure, if you do: printf("foo %d\n", "hello"), you will get the pointer of hello as an integer. if you do writef("foo, %d\n", "hello"), you get a type exception (I think), because writef is passed the type of all its arguments. A better example: printf("foo %s\n", 0), which gives you a segfault. With writef, %s is a 'catch all'. It means, 'check the type of the argument to see how to print it', and in the case: writef("foo %s\n", 0), you will get a 0. Most of the other % types are for formatting, like if you wanted a certain precision floating point, or to 0-pad, etc. Most of the time, you can just use %s: writef("%s, %s is an int, %s is a float, %s is a long", "hi", 5, 4.3, 1000000000000);
 I'm looking for a good D tutorial.  Something that would have all these 
 answers.  Can you recommend one?  I've been writing C for a dozen years 
 and C++ for a few, as well as other stuff here and there.
As I only use Tango (http://www.dsource.org/projects/tango), I don't know of tutorials that uses Phobos, but I would imagine there should be something on the digitalmars site. There's plenty of tutorials and instruction (and a book in print) if you want to use Tango. -Steve
Aug 17 2008
parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 The way you originally had it.  I think bearophile was saying that in your 
 particular example, you don't need to use it, because you never return 
 anything but zero (EXIT_SUCCESS).
This too works, even if it looks a bit strange: void main() { return 1 }
 Most of the time, you can just use %s:
 writef("%s, %s is an int, %s is a float, %s is a long", "hi", 5, 4.3, 
 1000000000000);
In some situations you can also just avoid using formatting: writef("The result is ", r0, " after ", n, " iterations."); But you have to be careful that the first string doesn't contain % for other purposes. To avoid that D 2.x has write/writeln (or you can use my better put/putr functions). (I think I now know enough of D that I may be able to start writing a "D best practices" web page). Bye, bearophile
Aug 18 2008
prev sibling next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Tim H wrote:
... 
 I'm looking for a good D tutorial.  Something that would have all these
 answers.  Can you recommend one?  I've been writing C for a dozen years
 and C++ for a few, as well as other stuff here and there.
 
 Tim
There is one wiki which contains a lot of information (probably the most) and further links: http://prowiki.org/wiki4d/wiki.cgi It has a section about learning D, I'd recommend reading 'text in d'. Perhaps the sections about porting C and C++ to D are also worthwhile in your case, to see differences. Furthermore, the digitalmars site has lots of good documentation, not only the spec but the articles are good too. Some articles are specific for C++ users. The book about Tango is really mostly a book about D, so that's good too. There is a sample chapter you may find useful here: http://www.gamedev.net/reference/programming/features/DTangoCh2/
Aug 17 2008
prev sibling parent BLS <nanali nospam-wanadoo.fr> writes:
Tim H schrieb:

 I'm looking for a good D tutorial.  Something that would have all these
answers.  Can you recommend one?  I've been writing C for a dozen years and C++
for a few, as well as other stuff here and there.
 
 Tim
Porting C++ to D at: http://prowiki.org/wiki4d/wiki.cgi?PortingFromCxx HTH, Bjoern
Aug 18 2008
prev sibling parent Jesse Phillips <jessekphillips gmail.com> writes:
On Sun, 17 Aug 2008 20:09:19 -0400, bearophile wrote:

 Tim H., others have already answered your main question. Regarding your
 code:
 
 Add the list of names you want to use, importing just the names you
 need, avoiding namespace pollution: import std.c.stdlib: writefln;
 
 
         public int m_int = 0;
This is enough: public int m_int; Because variables are initialized to .init by default (and there's a way to avoid that), and int.init is 0.
 int main(string[] args)
You can use this, because the return value is automatic: void main() To print writef/writefln is generally better, because typesafe (but it makes your executable fatter): writefln(foo %d", f.m_int); Bye, bearophile
http://www.dsource.org/ Most everything there is for D 1.0 many tutorials/examples written before its release and only for Phobos (which you are using), but still valid.
Aug 17 2008