-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Codegen: Faulty code with global pragma and indirect overload based initialization #5132
Comments
Well that cannot work, so it just needs a better error message. |
Why it cannot work but the two bellow can? I don't see what is wrong with that combination. |
proc initX(it: float): int = 8
proc main() =
var f: float
var x {.global.} = initX(f)
main() initX(f) depends on a local variable? |
Nope, it is dependent just on the type of the variable given to initX. In the manual it says that "When used within a generic proc, a separate unique global variable will be created for each instantiation of the proc." Here something more similar to what I actually used in my program (gives the same codegen error): proc initX(unused: float): int = 8
proc foo(bar: float) =
var x {.global.} = initX(bar)
echo x, bar
let f: float = 2.0
foo(f) And here a functionally equivalent version that works (and actually may be the perfect workaround for now): proc initX[T](): int = 8
proc foo[T](bar: T) =
var x {.global.} = initX[T]()
echo x, bar
let f: float = 2.0
foo(f) I don't remember anything in the manual that forbids the first form. EDIT: Actually, not perfect at all. It fails in my actual use case: proc initX[float](): int = 8
proc initX[int](): int = 1
proc foo[T](bar: T) =
var x {.global.} = initX[T]()
echo x, bar
let f: float = 2.0
foo(f) With
While w/o the {.global.} that overloading works: proc initX(unused:float): int = 8
proc initX(unused: int): int = 1
proc foo(bar: float|int) =
var x = initX(bar)
echo x, bar
let f: int = 2
foo(f) |
But there is no generic involved.
It might be equivalent for your use case, but it's completely different from my perspective: It doesn't depend on a runtime value (ignored in the proc body or not doesn't matter).
Come on, that's not why it works and you know it. |
I'm actually coming back to nim after a while away so I'm not totally up to speed. The following code gives exactly the same error:
I suppose that no specialization is going on there either.
Ok, so the compiler isn't supposed to be clever enough to detect that it doesn't actually depends on a runtime value because it is ignored by the called proc. A better error message would indeed help (and ideally some documentation on that limitation would be good too). So what actually solved my problem is to create a wrapper proc that calls two different plain procs depending on a typedesc parameter. I'm basically doing the overload manually and for this case at least I can manage. This works perfectly: proc initX(T: typedesc): auto =
when T is float|float32:
return initXf()
else:
return initXi()
proc initXf(): int = 8
proc initXi(): string = "bla"
proc foo(bar: int|uint|float|float32) =
var x {.global.} = initX(bar.type)
echo x, bar
let f: float = 2.0
foo(f) |
AFAIR, C++ does handle this case by emitting initialization code right in the place where its written and protecting it with "once". So runtime value dependancy is not a problem at all. Also such behavior looks more intuitive to me. I was really surprised that initialization code is executed long before the var definition is encountered. So to summarize my opinion: changing codegen to produce lazy initializer looks both more logical to me plus it fixes this issue. |
This issue has been automatically marked as stale because it has not had recent activity. If you think it is still a valid issue, write a comment below; otherwise it will be closed. Thank you for your contributions. |
…20812) * fix #3505 wrong var {.global.} initialization, asign variable to it * fix #5132 as well * follow suggestions * handle all call kinds * Update tests/global/t3505.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * follow suggestion * Update compiler/semstmts.nim Co-authored-by: Andreas Rumpf <[email protected]>
… to it (nim-lang#20812) * fix nim-lang#3505 wrong var {.global.} initialization, asign variable to it * fix nim-lang#5132 as well * follow suggestions * handle all call kinds * Update tests/global/t3505.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * follow suggestion * Update compiler/semstmts.nim Co-authored-by: Andreas Rumpf <[email protected]>
…20812) * fix #3505 wrong var {.global.} initialization, asign variable to it * fix #5132 as well * follow suggestions * handle all call kinds * Update tests/global/t3505.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * follow suggestion * Update compiler/semstmts.nim Co-authored-by: Andreas Rumpf <[email protected]> (cherry picked from commit 1410243)
…20812) * fix #3505 wrong var {.global.} initialization, asign variable to it * fix #5132 as well * follow suggestions * handle all call kinds * Update tests/global/t3505.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * follow suggestion * Update compiler/semstmts.nim Co-authored-by: Andreas Rumpf <[email protected]> (cherry picked from commit 1410243)
…20812) * fix #3505 wrong var {.global.} initialization, asign variable to it * fix #5132 as well * follow suggestions * handle all call kinds * Update tests/global/t3505.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * follow suggestion * Update compiler/semstmts.nim Co-authored-by: Andreas Rumpf <[email protected]> (cherry picked from commit 1410243)
…20812) * fix #3505 wrong var {.global.} initialization, asign variable to it * fix #5132 as well * follow suggestions * handle all call kinds * Update tests/global/t3505.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * follow suggestion * Update compiler/semstmts.nim Co-authored-by: Andreas Rumpf <[email protected]> (cherry picked from commit 1410243)
…20812) * fix #3505 wrong var {.global.} initialization, asign variable to it * fix #5132 as well * follow suggestions * handle all call kinds * Update tests/global/t3505.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * follow suggestion * Update compiler/semstmts.nim Co-authored-by: Andreas Rumpf <[email protected]> (cherry picked from commit 1410243)
… to it (nim-lang#20812) * fix nim-lang#3505 wrong var {.global.} initialization, asign variable to it * fix nim-lang#5132 as well * follow suggestions * handle all call kinds * Update tests/global/t3505.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * Update compiler/semstmts.nim * follow suggestion * Update compiler/semstmts.nim Co-authored-by: Andreas Rumpf <[email protected]>
Sorry for the horrible title, but I don't fully understand what went wrong.
gives:
I'm using overload to control my program flow and this function generates the above error. It also give the same error if I replace the
float
byint
too. The following variations of the main functions are fine:W/o parameters
W/o {.global.}
The text was updated successfully, but these errors were encountered: