Problem parsing IPv4/IPv6 addresses with std.socket.parseAddress

Marc Schütz via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Sep 28 02:56:06 PDT 2016


On Tuesday, 27 September 2016 at 14:57:26 UTC, Dsciple wrote:
> struct ConfigParams {
>   // ...
>   // Define configuration parameters' static default fields
>   static immutable BindAddresses defaultBindAddresses = 
> BindAddresses([
>     BindAddress("192.168.2.10")
>   ]);
>   // ...
> }

Yepp, that's definitely the culprit.

>
> I don't understand why the unit tests of all individual members 
> of ConfigParams (BindAddresses, BindAddress and so on) would 
> work in isolation using the same kind of initialization, 
> whereas some of them would fail as members of ConfigParams.

Because in your unit tests, your BindAddress variables are 
probably normal, local variables. These are initial at runtime as 
you would expect. Only in places where a static initialization is 
required, the compiler will evaluate the initializer at compile 
time. Examples:

     // global, but no initializer => ok
     BindAddress global1;
     // global with initializer => needs to be evaluated at 
compile time
     BindAddress global2 = BindAddress("127.0.0.1");
     struct Config {
         // default value for members => evaluate at compile time
         BindAddress bindAddress = BindAddress("0.0.0.0");
     }

     void main() {
         // assignment to globals at runtime works (of course)
         global1 = BindAddress("192.168.1.2");
         // local with initializer => works at runtime
         BindAddress local1 = BindAddress("10.0.0.1");
         // static => same as global, evaluated at compile time
         static BindAddress static1 = BindAddress("127.0.0.1");
     }

You could solve the problem as you suggested by moving the 
initializations into a constructor, but if your default values 
are only ever IPs (i.e., no hostname resolution necessary), you 
could also add an additional function that parse them without 
calling into the C library, e.g.

     struct BindAddress {
         // ...
         static BindAddress fromIP(string addr) {
             // ...
         }
     }

     struct Config {
         // ...
         BindAddress bindAddress = BindAddress.fromIP("127.0.0.1");
     }

You can try whether InternetAddress.parse() [1] works at compile 
time, otherwise you would have to implement it by hand.

[1] 
https://dlang.org/phobos/std_socket.html#.InternetAddress.parse


More information about the Digitalmars-d-learn mailing list