www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strange error when compiling with dmd, not with ldc

reply Fra Mecca <me francescomecca.eu> writes:
I have this struct:

immutable struct Configuration {
     string title;
     string baseurl;
     string url;
     string email;
     string author;
     string parser;
     string target;
     string urlFormat;
     string urlFormatCmd;

     short port;

     string[] ignore;
     string[] extensions;

      property string toString()
     {
         auto urlF = (urlFormatCmd ? "url_format_cmd: " ~ 
urlFormatCmd : "") ~ "\n";
         return
         "title: "        ~ title ~ "\n" ~
         "baseurl: "      ~ baseurl ~ "\n" ~
         "url: "          ~ url ~ "\n" ~
         "email: "        ~ email ~ "\n" ~
         "author: "       ~ author ~ "\n" ~
         "parser: "       ~ parser ~ "\n" ~
         "target: "       ~ target ~ "\n" ~
         "url_format: "   ~ urlFormat ~ "\n" ~
         "ignore: "       ~ to!string(ignore)[1 .. $ - 1] ~ "\n" ~
         "extensions: "   ~ to!string(extensions)[1 .. $ - 1] ~ 
"\n" ~
         urlF;
     }
}

and this function:

void show_config()
{
     writef("%s", parse_config(
                 exists("config.sdl") ? "config.sdl" : 
"").toString);
}


Whenever I compile with ldc2 I get no errors, while with dmd I 
get:

source/configuration.d(105,27): Error: immutable method 
configuration.Configuration.toString is not callable using a 
mutable object


What is the problem?
Nov 28
parent reply user1234 <user1234 12.nl> writes:
On Wednesday, 29 November 2017 at 06:18:09 UTC, Fra Mecca wrote:
 I have this struct:

 immutable struct Configuration {
     string title;
     string baseurl;
     string url;
     string email;
     string author;
     string parser;
     string target;
     string urlFormat;
     string urlFormatCmd;

     short port;

     string[] ignore;
     string[] extensions;

      property string toString()
     {
         auto urlF = (urlFormatCmd ? "url_format_cmd: " ~ 
 urlFormatCmd : "") ~ "\n";
         return
         "title: "        ~ title ~ "\n" ~
         "baseurl: "      ~ baseurl ~ "\n" ~
         "url: "          ~ url ~ "\n" ~
         "email: "        ~ email ~ "\n" ~
         "author: "       ~ author ~ "\n" ~
         "parser: "       ~ parser ~ "\n" ~
         "target: "       ~ target ~ "\n" ~
         "url_format: "   ~ urlFormat ~ "\n" ~
         "ignore: "       ~ to!string(ignore)[1 .. $ - 1] ~ "\n" 
 ~
         "extensions: "   ~ to!string(extensions)[1 .. $ - 1] ~ 
 "\n" ~
         urlF;
     }
 }

 and this function:

 void show_config()
 {
     writef("%s", parse_config(
                 exists("config.sdl") ? "config.sdl" : 
 "").toString);
 }


 Whenever I compile with ldc2 I get no errors, while with dmd I 
 get:

 source/configuration.d(105,27): Error: immutable method 
 configuration.Configuration.toString is not callable using a 
 mutable object


 What is the problem?
You must also use a type constructor later, when a Configuration is declared: ``` immutable(Configuration) config; config.toString.writeln; // okay this time ``` What happens is that all the member functions have the `immutable` attribute, but the instance you declared was not itself `immutable`. actually this: ``` immutable struct Configuration { property string toString(){return "";} } ``` is like: ``` struct Configuration { property string toString() immutable {return "";} } ``` I would personally prefer the second form. Why ? Because the variable members will be set immutable anyway when an instance is declared.
Nov 29
parent user1234 <user1234 12.nl> writes:
On Wednesday, 29 November 2017 at 10:55:35 UTC, user1234 wrote:
 On Wednesday, 29 November 2017 at 06:18:09 UTC, Fra Mecca wrote:
 [...]
You must also use a type constructor later, when a Configuration is declared: ``` immutable(Configuration) config; config.toString.writeln; // okay this time ``` What happens is that all the member functions have the `immutable` attribute, but the instance you declared was not itself `immutable`. actually this: ``` immutable struct Configuration { property string toString(){return "";} } ``` is like: ``` struct Configuration { property string toString() immutable {return "";} } ``` I would personally prefer the second form. Why ? Because the variable members will be set immutable anyway when an instance is declared.
And about the DMD vs LDC thing, i thing that the difference can be simply explained by the fact that LDC uses a slightly older compiler front end version, meaning that after 1 or 2 updates, the same error would happen. Now i don't know which change in particular has been made recently in the front-end. Maybe the semantic of the leading qualifier when "immutable struct {}" is used but i would bet too much on that.
Nov 29