www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to declare immutable struct outside of try catch and reference it

reply Fra Mecca <me francescomecca.eu> writes:
I have this code:
     Configuration conf = void ;
     try {
         conf = parse_config("config.sdl");
     } catch (Exception e) {
         std.stdio.stderr.writeln("Error reading configuration 
file: ", e.msg);
         exit(1);
     }

// other code
function(value, conf);
// end

I get:
source/app.d(18,3): Error: cannot modify struct conf 
Configuration with immutable members

Is there a way to declare conf outside of the try catch block and 
use it later?
I thought void explicitly avoid inizialization.
Dec 02
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, December 03, 2017 05:49:54 Fra Mecca via Digitalmars-d-learn 
wrote:
 I have this code:
      Configuration conf = void ;
      try {
          conf = parse_config("config.sdl");
      } catch (Exception e) {
          std.stdio.stderr.writeln("Error reading configuration
 file: ", e.msg);
          exit(1);
      }

 // other code
 function(value, conf);
 // end

 I get:
 source/app.d(18,3): Error: cannot modify struct conf
 Configuration with immutable members

 Is there a way to declare conf outside of the try catch block and
 use it later?
 I thought void explicitly avoid inizialization.
It's not possible to delay initialization with const or immutable variables unless they're member variables (which then have to be initialized in a constructor before they're used), but you can wrap the try-catch block in a function or lambda that returns the struct so that the code is separated out in a way that the variable is then directly initialized. - Jonathan M Davis
Dec 02
prev sibling next sibling parent reply kdevel <kdevel vogtner.de> writes:
On Sunday, 3 December 2017 at 05:49:54 UTC, Fra Mecca wrote:
 I have this code:
     Configuration conf = void ;
     try {
         conf = parse_config("config.sdl");
     } catch (Exception e) {
         std.stdio.stderr.writeln("Error reading configuration 
 file: ", e.msg);
         exit(1);
     }
Since most programs have more than place where execution must be terminated, you end up dupliating that try-catch-code all over the program making it unreadable. When you try to avoid calling exit this problem will not arise. You can simply write ``` auto conf = parse_config("config.sdl"); ``` The exception unwinds the stack and terminates the program. If a stacktrace on the command line does not suffice I would wrap the main-code in a try-catch block. Your function parse_config should support this coding style by putting a whole sentence into the Exception instead of the mere filename, then the try-catch wrapper in main may look like this: ``` int main () { try { real_main (); } catch (Exception e) { std.stdio.stderr.writeln(e.msg); return 1; } return 0; } ```
Dec 03
parent kdevel <kdevel vogtner.de> writes:
On Sunday, 3 December 2017 at 14:16:42 UTC, kdevel wrote:
 int main ()
 {
    try {
       real_main ();
    }
    catch (Exception e) {
       std.stdio.stderr.writeln(e.msg);
       return 1;
    }
    return 0;
 }
 ```
This is better: int main () { try { return real_main (); } catch (Exception e) { std.stdio.stderr.writeln(e.msg); return 1; } }
Dec 03
prev sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Sunday, 3 December 2017 at 05:49:54 UTC, Fra Mecca wrote:
 I have this code:
     Configuration conf = void ;
     try {
         conf = parse_config("config.sdl");
     } catch (Exception e) {
         std.stdio.stderr.writeln("Error reading configuration 
 file: ", e.msg);
         exit(1);
     }

 // other code
 function(value, conf);
 // end

 I get:
 source/app.d(18,3): Error: cannot modify struct conf 
 Configuration with immutable members

 Is there a way to declare conf outside of the try catch block 
 and use it later?
 I thought void explicitly avoid inizialization.
In this case i'd go for a typed pointer, e.g --- immutable struct Configuration { this(string){/*load some file...*/} int value; } Configuration* config; void main() { try config = new Configuration("config.sdl"); catch(Exception){} // config.value = 42; // ok, read only } ---
Dec 03
parent reply kdevel <kdevel vogtner.de> writes:
On Sunday, 3 December 2017 at 14:58:03 UTC, Basile B. wrote:
 In this case i'd go for a typed pointer, e.g

 ---
 immutable struct Configuration
 {
     this(string){/*load some file...*/}
     int value;
 }

 Configuration* config;

 void main()
 {
     try config = new Configuration("config.sdl");
     catch(Exception){}
     // config.value = 42; // ok, read only
 }
 ---
When config is null, e.g. in case "load some file..." threw, you get a segfault. No error handling at all!
Dec 03
parent reply Basile B. <b2.temp gmx.com> writes:
On Sunday, 3 December 2017 at 22:33:40 UTC, kdevel wrote:
 On Sunday, 3 December 2017 at 14:58:03 UTC, Basile B. wrote:
 In this case i'd go for a typed pointer, e.g

 ---
 immutable struct Configuration
 {
     this(string){/*load some file...*/}
     int value;
 }

 Configuration* config;

 void main()
 {
     try config = new Configuration("config.sdl");
     catch(Exception){}
     // config.value = 42; // ok, read only
 }
 ---
When config is null, e.g. in case "load some file..." threw, you get a segfault. No error handling at all!
I don't follow you...the file thing happens in the __ctor. Exceptions are well handled. Maybe you've missed the try (w/o braces) ? --- immutable struct Configuration { this(string){/*parse_config...*/} } Configuration* config; int main() { try { config = new Configuration("config.sdl"); // instead of "conf = parse_config("config.sdl");" } catch(Exception e){ std.stdio.stderr.writeln("Error reading configuration file: ", e.msg); return 1; } } ---
Dec 03
parent kdevel <kdevel vogtner.de> writes:
On Sunday, 3 December 2017 at 23:29:01 UTC, Basile B. wrote:
 On Sunday, 3 December 2017 at 22:33:40 UTC, kdevel wrote:
 On Sunday, 3 December 2017 at 14:58:03 UTC, Basile B. wrote:
 In this case i'd go for a typed pointer, e.g

 ---
 immutable struct Configuration
 {
     this(string){/*load some file...*/}
     int value;
 }

 Configuration* config;

 void main()
 {
     try config = new Configuration("config.sdl");
     catch(Exception){}
     // config.value = 42; // ok, read only
 }
 ---
When config is null, e.g. in case "load some file..." threw, you get a segfault. No error handling at all!
I don't follow you...the file thing happens in the __ctor. Exceptions are well handled.
But not in the code you provided first. You used to ignore the exception: catch(Exception){}
 Maybe you've missed the try (w/o braces) ?
Not really.
 ---
 immutable struct Configuration {
     this(string){/*parse_config...*/}
 }

 Configuration* config;

 int main() {
     try {
         config = new Configuration("config.sdl");
         // instead of "conf = parse_config("config.sdl");"
     } catch(Exception e){
         std.stdio.stderr.writeln("Error reading configuration 
 file: ", e.msg);
         return 1;
     }
 }
 ---
Are my eyes too weak or is my compiler too old? For this piece of code test.d ``` immutable struct C { this (string filename) { } } void main () { auto config = new C ("config.sdl"); } ``` it says: test.d(9): Error: immutable method test.C.this is not callable using a mutable object → https://issues.dlang.org/show_bug.cgi?id=13628http://forum.dlang.org/thread/mailman.926.1413747186.9932.digitalmars-d-bugs puremagic.com
Dec 04