Recently, I poorly refactored some code, which introduced an obvious bug. But to my astonishment, the broken code compiled without any warnings or notifications. A minimum example is shown below:

alias ID = uint;
struct Data
{
        ID id;
        this(ID id)
        {
                this.id = id;
        }
}

// Forgot to refactor a function to return its
// loaded data, rather than a success/fail bool
bool load_data()
{
        // some processing
        return true;
}

int main()
{
        // Very obviously a bug,
        // but it still compiles
        Data d = load_data();
        return 0;
}


So I'm assigning a boolean value to a struct with one uint field. The compiler interprets the attempted assignment as calling the constructor with one argument, and then converts the boolean to a uint to match the function overload. So in effect, my struct is implicitly convertible from a bool.

My question is basically... how do I make this not compile? What methods do I have to prevent this sort of crazy implicit conversion? I'm not familiar enough with the language to know my options. I think there are a few:

* Enable more warnings. DMD seems to only have "-w", which I believe is enabled through dub. Are there more pedantic settings that would catch this conversion?

* Change "ID" from an alias to a struct of some sort. I've been trying to find similar issues, and I saw once suggested that a person could make a struct with one member and conversions to and from different types. I've also seen "alias X this;" a lot. But my main issues is stopping these conversions, and everything I've seen is about enabling automatic conversion. Ideally, I would have something that's convertible TO a uint when needed, but can't be converted FROM other data types.

* Replace the constructor with a static function. This happened because D implicitly converted my assignment into a constructor call. If I just don't have constructors, and instead define a static function to build instances of the struct, I could then have more control over assignment and avoid this more easily.


If anyone has other options, I would really want to hear them. I know for a fact these types of issues are going to crop up in my project, and I want to nip them in the bud before the become harder to track down.

Reply via email to