The comment from @Jehan deserves to be explained better in the Manual. This 
took a long time to debug. The problem is that `cast[]` is not simply "unsafe"; 
it's downright deceitful.

I had an if-statement which was never evaluating to `true`. I couldn't believe 
it, so I printed the elements of the expression, and then the full expression. 
It was always printed as `true`! But `if` looked at the same expression 
differently than `echo` did.

Here it is:
    
    
    if aln.aln_str_size > 500 and
            (cast[cdouble](aln.dist) / cast[cdouble](aln.aln_str_size)) < 
max_diff:
          echo "HELLO"
    

See if you can figure it out...

...

...

...

...

For the answer, I had to look at the generated source code. (I am so thankful 
to be able to view the generated code.) Because `dist` and `size` are used as 
both actual type (`int`) and casted type (`double`), the **Nim** compiler 
decided to use a union: 
    
    
    union { int source; double dest; } LOC34;
    

But in my `echo` statements, there is no union, so a C-style cast is performed 
instead.

Why not just be clear in the Manual:

> "cast[]" assumes that the types are bitwise compatible, e.g. "int32" and 
> "uint32". Beware "cast[]" in general. For example, never use "cast[double]" 
> to convert from an integer, nor vice versa.

I made this mistake because I am cleaning up thousands of lines of code 
produced by **c2nim**, and it's hard to catch everything. It started as this:
    
    
    if (aln->aln_str_size > 500 &&
            ((double) aln->dist / (double) aln->aln_str_size) < max_diff) {
    

Reply via email to