-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: deprecate implicit conversions from procvar => pointer
and ptr T => pointer
; enable function merging
#229
Comments
Just to be clear, I really want "MSVC aggressively COMDAT folds functions, so two functions with the same implementation can be turned into one function)," for Nim too. |
If procs can be compared then Having said that, fewer implicit conversions are a good thing and the RFC is good, but it doesn't really address the "function merging" problem. |
This RFC is stale because it has been open for 1095 days with no activity. Contribute a fix or comment on the issue, or it will be closed in 7 days. |
This wasn't done already? |
in C++
C++ (and other languages) rightfully disallow implicit conversion from function pointer to
void*
, giving errors like:no known conversion from 'void (int, double)' to 'void *' for 1st argument
Likewise,
==
between function pointers of different types is also disallowed. giving errors like:error: comparison of distinct pointer types ('void (*)(int, double)' and 'void (*)(int)')
However,
==
between function pointers of same type is allowed and works.in nim
nim defines:
combine this with the fact that
proc
(actually,procvar
, which is now the default) implicitly converts to pointer, and you get both of C++ guarantees thrown out, so that==
works between unrelated types, including between aptr Foo
and aptr Bar
or between aptr Foo
and aproc fun(a: int)
or aproc fun(a: int)
and aproc bar(b: string): bool
, which makes no sense from type safety point of view.proposal
--legacy:ptrliketopointer
, in which case just warning) implicit conversions from procvar to pointerptr T
to pointerfoo.pointer
orpointer(foo)
(and it'd apply to all ptr-like types, including proc, ref T, ptr T, cstring and pointer)==
stays valid for procs orptr T
so long the type of operands is the same; for procvar, what matters is the type, not whether it's a generic instantiation or not==
stays valid forref T
(unchanged)related
ptr char
implicitly converts to cstring, resulting in undefined behavior Nim#13790==
for refs and procs #224compared to Deprecate
==
for refs and procs #224, this RFC doesn't deprecate==
for procvar norref T
, instead it deprecates implicit conversion topointer
, which as a side effect deprecates==
for uncompatible procvars andptr T
. Andref T
==
stays valid, unchanged.This makes
ptr T
and procvar consistent withref T
for both==
and for how conversion to pointer works (explicit, not implicit)enables function merging
==
for refs and procs #224 (I will rebut the other aspects from that RFC later); if 2 procs fn1, fn2 generate identical code, the optimizer can merge them so that they'll have the same address; if they're the same type than there's no contradiction withfn1 == fn2
; and if they're different types thanfn1 == fn2
does not compile so there's also no contradictionnote
https://stackoverflow.com/questions/26533740/do-distinct-functions-have-distinct-addresses
function merging is controversial and some compilers do it (
MSVC aggressively COMDAT folds functions, so two functions with the same implementation can be turned into one function
), whereas most others (eg clang) don't or at least only do it under the "as-if" rule whereby merge only happens if no visible behavior changes, including by taking function address; that last fact makes it tricky to tell whether function merging happens so you have to disassemble to check. Nim perhaps could be smart here and do some function merging before handing it to cgen to avoid relying in C compiler doing it. At least nim could be smarter about caching generic instantiations in light of this.The text was updated successfully, but these errors were encountered: