www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why does this simple program segfault?

reply convert <convert somewhere.com> writes:
Hi, 

I wrote this very simple class, but the call to fun.testIt() segfaults.
If I put the function outside of the class it works just fine.
What am I missing?
I have tried this with dmd v1.015 and the tango dmd v1.018, same thing.

Thank you very much.

-------------------
import std.stdio;

class Tester
{
    void testIt() {}
}

void main()
{
  Tester fun;
  fun.testIt();
  writefln("I made it!");
}
Aug 14 2007
parent reply BCS <ao pathlink.com> writes:
Reply to convert,

 Hi,
 
 I wrote this very simple class, but the call to fun.testIt()
 segfaults.
 If I put the function outside of the class it works just fine.
 What am I missing?
 I have tried this with dmd v1.015 and the tango dmd v1.018, same
 thing.
 Thank you very much.
 
 -------------------
 import std.stdio;
 class Tester
 {
 void testIt() {}
 }
 void main()
 {
 Tester fun;
 fun.testIt();
 writefln("I made it!");
 }

you don't new the Tester
 Tester fun = new Tester();

Aug 14 2007
next sibling parent convert <convert somewhere.com> writes:
 you don't new the Tester
 
 Tester fun = new Tester();


Argh. Thanks a lot!
Aug 14 2007
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to convert,
 
 Hi,

 I wrote this very simple class, but the call to fun.testIt()
 segfaults.
 If I put the function outside of the class it works just fine.
 What am I missing?
 I have tried this with dmd v1.015 and the tango dmd v1.018, same
 thing.
 Thank you very much.

 -------------------
 import std.stdio;
 class Tester
 {
 void testIt() {}
 }
 void main()
 {
 Tester fun;
 fun.testIt();
 writefln("I made it!");
 }

you don't new the Tester
 Tester fun = new Tester();


Isn't there something we can do about this? I do this about once a day when in a heavy D using phase. It bites newbies and not-so-newbies alike. I almost think it should be made so that no initializer calls the default constructor, and if you really want it to be null then you should initialize with null: Tester fun; // creates a new Tester Tester nofun = null; // doesn't create anything But then there's all sorts of questions that crop up, like what should "new Tester[5]" do? Or "Tester m_fun;" as a class/struct member. I guess the best we can hope for is some kind of better error message than just a generic segfault, or perhaps a compiler warning if you forget to initialize a class instance. --bb
Aug 14 2007
next sibling parent reply Ary Manzana <ary esperanto.org.ar> writes:
Bill Baxter escribió:
 BCS wrote:
 Reply to convert,

 Hi,

 I wrote this very simple class, but the call to fun.testIt()
 segfaults.
 If I put the function outside of the class it works just fine.
 What am I missing?
 I have tried this with dmd v1.015 and the tango dmd v1.018, same
 thing.
 Thank you very much.

 -------------------
 import std.stdio;
 class Tester
 {
 void testIt() {}
 }
 void main()
 {
 Tester fun;



The compiler should do the following: Since fun wasn't assigned to something, any access to it before an assignment to fun should result in a compiler error.
 fun.testIt();
 writefln("I made it!");
 }

you don't new the Tester
 Tester fun = new Tester();


Isn't there something we can do about this? I do this about once a day when in a heavy D using phase. It bites newbies and not-so-newbies alike. I almost think it should be made so that no initializer calls the default constructor, and if you really want it to be null then you should initialize with null: Tester fun; // creates a new Tester Tester nofun = null; // doesn't create anything But then there's all sorts of questions that crop up, like what should "new Tester[5]" do? Or "Tester m_fun;" as a class/struct member.

Any access to Tester[i] before Tester[i] is assigned something should result in a compiler error.
 
 I guess the best we can hope for is some kind of better error message 
 than just a generic segfault, or perhaps a compiler warning if you 
 forget to initialize a class instance.
 
 --bb

Aug 14 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Ary Manzana wrote:
 Bill Baxter escribió:
 BCS wrote:
 Reply to convert,

 Hi,

 I wrote this very simple class, but the call to fun.testIt()
 segfaults.
 If I put the function outside of the class it works just fine.
 What am I missing?
 I have tried this with dmd v1.015 and the tango dmd v1.018, same
 thing.
 Thank you very much.

 -------------------
 import std.stdio;
 class Tester
 {
 void testIt() {}
 }
 void main()
 {
 Tester fun;



The compiler should do the following: Since fun wasn't assigned to something, any access to it before an assignment to fun should result in a compiler error.
 fun.testIt();
 writefln("I made it!");
 }

you don't new the Tester
 Tester fun = new Tester();


Isn't there something we can do about this? I do this about once a day when in a heavy D using phase. It bites newbies and not-so-newbies alike. I almost think it should be made so that no initializer calls the default constructor, and if you really want it to be null then you should initialize with null: Tester fun; // creates a new Tester Tester nofun = null; // doesn't create anything But then there's all sorts of questions that crop up, like what should "new Tester[5]" do? Or "Tester m_fun;" as a class/struct member.

Any access to Tester[i] before Tester[i] is assigned something should result in a compiler error.

I don't think that's something that could be realistically enforced using static analysis. How would you propose implementing that? --bb
Aug 14 2007
parent Ary Manzana <ary esperanto.org.ar> writes:
Bill Baxter escribió:
 Ary Manzana wrote:
 Bill Baxter escribió:
 BCS wrote:
 Reply to convert,

 Hi,

 I wrote this very simple class, but the call to fun.testIt()
 segfaults.
 If I put the function outside of the class it works just fine.
 What am I missing?
 I have tried this with dmd v1.015 and the tango dmd v1.018, same
 thing.
 Thank you very much.

 -------------------
 import std.stdio;
 class Tester
 {
 void testIt() {}
 }
 void main()
 {
 Tester fun;



The compiler should do the following: Since fun wasn't assigned to something, any access to it before an assignment to fun should result in a compiler error.
 fun.testIt();
 writefln("I made it!");
 }

you don't new the Tester
 Tester fun = new Tester();


Isn't there something we can do about this? I do this about once a day when in a heavy D using phase. It bites newbies and not-so-newbies alike. I almost think it should be made so that no initializer calls the default constructor, and if you really want it to be null then you should initialize with null: Tester fun; // creates a new Tester Tester nofun = null; // doesn't create anything But then there's all sorts of questions that crop up, like what should "new Tester[5]" do? Or "Tester m_fun;" as a class/struct member.

Any access to Tester[i] before Tester[i] is assigned something should result in a compiler error.

I don't think that's something that could be realistically enforced using static analysis. How would you propose implementing that?

Umm... Now that I think of, the first comment I made is doable (Java does it), but the second... forget it.
Aug 14 2007
prev sibling next sibling parent BCS <ao pathlink.com> writes:
Reply to Bill,

 Isn't there something we can do about this?  I do this about once a
 day when in a heavy D using phase.  It bites newbies and
 not-so-newbies alike.  I almost think it should be made so that no
 initializer calls the default constructor, and if you really want it
 to be null then you should initialize with null:

we could change the seg-v message to "Did you forget to new somthing?"
Aug 14 2007
prev sibling next sibling parent Jascha Wetzel <"[firstname]" mainia.de> writes:
Bill Baxter wrote:
 Isn't there something we can do about this?  I do this about once a day 
 when in a heavy D using phase.  It bites newbies and not-so-newbies 
 alike.  I almost think it should be made so that no initializer calls 
 the default constructor, and if you really want it to be null then you 
 should initialize with null:
 
    Tester fun;  // creates a new Tester
    Tester nofun = null;  // doesn't create anything
 
 But then there's all sorts of questions that crop up, like what should 
 "new Tester[5]" do?  Or "Tester m_fun;" as a class/struct member.
 
 I guess the best we can hope for is some kind of better error message 
 than just a generic segfault, or perhaps a compiler warning if you 
 forget to initialize a class instance.
 
 --bb

it would be nice to have a way to specify the default initializer for any type.
Aug 14 2007
prev sibling next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Bill Baxter Wrote:

 Isn't there something we can do about this?  I do this about once a day 
 when in a heavy D using phase.  It bites newbies and not-so-newbies 
 alike.  I almost think it should be made so that no initializer calls 
 the default constructor, and if you really want it to be null then you 
 should initialize with null:
 
     Tester fun;  // creates a new Tester
     Tester nofun = null;  // doesn't create anything

But then I (coming from a Java background) would be bitten by it about once a day. I think the best way is to make a compiler warning for every local variable that's used before it's explicitly assigned, a la Java (actually, it's an error in Java).
Aug 14 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Robert Fraser wrote:
 Bill Baxter Wrote:
 
 Isn't there something we can do about this?  I do this about once a day 
 when in a heavy D using phase.  It bites newbies and not-so-newbies 
 alike.  I almost think it should be made so that no initializer calls 
 the default constructor, and if you really want it to be null then you 
 should initialize with null:

     Tester fun;  // creates a new Tester
     Tester nofun = null;  // doesn't create anything

But then I (coming from a Java background) would be bitten by it about once a day. I think the best way is to make a compiler warning for every local variable that's used before it's explicitly assigned, a la Java (actually, it's an error in Java).

Assuming it applied only to classes in D, that seems like a good idea. --bb
Aug 14 2007
parent reply Chad J <gamerChad _spamIsBad_gmail.com> writes:
Bill Baxter wrote:
 Robert Fraser wrote:
 Bill Baxter Wrote:

 Isn't there something we can do about this?  I do this about once a 
 day when in a heavy D using phase.  It bites newbies and 
 not-so-newbies alike.  I almost think it should be made so that no 
 initializer calls the default constructor, and if you really want it 
 to be null then you should initialize with null:

     Tester fun;  // creates a new Tester
     Tester nofun = null;  // doesn't create anything

But then I (coming from a Java background) would be bitten by it about once a day. I think the best way is to make a compiler warning for every local variable that's used before it's explicitly assigned, a la Java (actually, it's an error in Java).

Assuming it applied only to classes in D, that seems like a good idea. --bb

Probably a good idea. I hesitated because I sometimes use null as a sentinel value, but null can be assigned explicitly, so all is good. I think a worse problem though is how D errors on null dereferencing. On windows I get Access Violations, and I think the segv is a linux thing if I remember correctly. Such error messages are completely unhelpful while debugging. The following should probably be done: instance.member = something; becomes assert(instance !is null, format("%s,%d: %s is null!", __FILE__,__LINE__,instance.stringof) ); instance.member = something; It would be sort of like how arrays are bounds checked at runtime unless in release mode.
Aug 14 2007
next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Chad J wrote:

 I think a worse problem though is how D errors on null dereferencing. On 
 windows I get Access Violations, and I think the segv is a linux thing 
 if I remember correctly.

Correct. They're called Bus Errors on Mac. "Kärt barn har många namn"*. --anders * translated to english: We find many names for those we love
Aug 14 2007
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Chad J" <gamerChad _spamIsBad_gmail.com> wrote in message 
news:f9tu35$1d7q$1 digitalmars.com...
 I think a worse problem though is how D errors on null dereferencing. On 
 windows I get Access Violations, and I think the segv is a linux thing if 
 I remember correctly.  Such error messages are completely unhelpful while 
 debugging.  The following should probably be done:

 instance.member = something;

 becomes

 assert(instance !is null,
   format("%s,%d: %s is null!",
   __FILE__,__LINE__,instance.stringof)
   );
 instance.member = something;

 It would be sort of like how arrays are bounds checked at runtime unless 
 in release mode.

Was suggested, shot down, forgotten. :\
Aug 15 2007
parent Chad J <gamerChad _spamIsBad_gmail.com> writes:
Jarrett Billingsley wrote:
 "Chad J" <gamerChad _spamIsBad_gmail.com> wrote in message 
 news:f9tu35$1d7q$1 digitalmars.com...
 I think a worse problem though is how D errors on null dereferencing. On 
 windows I get Access Violations, and I think the segv is a linux thing if 
 I remember correctly.  Such error messages are completely unhelpful while 
 debugging.  The following should probably be done:

 instance.member = something;

 becomes

 assert(instance !is null,
   format("%s,%d: %s is null!",
   __FILE__,__LINE__,instance.stringof)
   );
 instance.member = something;

 It would be sort of like how arrays are bounds checked at runtime unless 
 in release mode.

Was suggested, shot down, forgotten. :\

grrrr. This seems like low-lying fruit to me. Considering the impressive stuff dmd does, I figured this would take very little effort to accomplish. At the same time, this fix would save many programmers many hours of time, same as bounds checks. This stuff has worked me over more than enough times. The ubiquitous crappy runtime error messages need to go.
Aug 15 2007
prev sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Bill Baxter wrote:

 I guess the best we can hope for is some kind of better error message 
 than just a generic segfault, or perhaps a compiler warning if you 
 forget to initialize a class instance.

Aren't those segfaults the famous "hardware exceptions", that you get "for free" instead of the compiler having to throw real exceptions ? Doesn't seem too impossible to discover in the debugger, I'm worried that having the compiler error on it would trip up some valid code... gdb says: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000000 0x00002d81 in D main () at Tester.d:11 11 fun.testIt(); --anders
Aug 14 2007
parent Lars Noschinski <lars-2006-1 usenet.noschinski.de> writes:
* Anders F Björklund <afb algonet.se> [07-08-15 08:38]:
Bill Baxter wrote:

I guess the best we can hope for is some kind of better error message than 
just a generic segfault, or perhaps a compiler warning if you forget to 
initialize a class instance.

Aren't those segfaults the famous "hardware exceptions", that you get "for free" instead of the compiler having to throw real exceptions ?

On Unix systems, a segmentation fault triggers a SIGSEGV signal, which - by default - results in program termination. It can be catched, but IIRC the state of the program is undefined afterwards.
Aug 17 2007