@Araq Here is a minimal example. This is compiled with "vcc". It compiles to C, but not to C++. type VolatilePtr*[T] = distinct ptr T proc toVolatilePtr*[T](t: var T): VolatilePtr[T] = cast[VolatilePtr[T]](addr t) # Pretend we're actually checking it's volatile, which is apparently not possible to do. var my_vbyte {.volatile.}: byte = 42'u8 var my_vbyte_ptr = toVolatilePtr[byte](my_vbyte) type AtomType* = SomeNumber|pointer|ptr|char|bool when defined(cpp): proc interlockedOr8(p: pointer; value: int8): int8 {.importcpp: "_InterlockedOr8(static_cast<char volatile *>(#), #)", header: "<intrin.h>".} else: proc interlockedOr8(p: pointer; value: int8): int8 {.importc: "_InterlockedOr8", header: "<intrin.h>".} proc atomicLoadFull*[T: AtomType](p: VolatilePtr[T]): T {.inline.} = let pp = cast[pointer](p) when sizeof(T) == 1: cast[T](interlockedOr8(pp, 0'i8)) else: # TODO, sizeof(T) == (2|4|8) static: assert(false, "invalid parameter size: " & $sizeof(T)) assert(atomicLoadFull(my_vbyte_ptr) == 42'u8) src\nimcache\abc_volatile2.cpp(306): error C2664: 'NU8 *toVolatilePtr_EP8VL8ilqAQ1Zz9bJAA4rwQ(NU8 &)': cannot convert argument 1 from 'volatile NU8' to 'NU8 &' src\nimcache\abc_volatile2.cpp(306): note: Conversion loses qualifiers
I've had the issue that the error doesn't always come, if I don't delete the nimcache, but I think it's caused by VS Code compiling automatically as well, using a different configuration.