Skip to content
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

Illegal storage access (Attempt to read from nil?): when attempting to pass proc to proc #6137

Closed
uqtredd1 opened this issue Jul 24, 2017 · 5 comments

Comments

@uqtredd1
Copy link

Nim newbie here, the following code fails with "SIGSEGV: Illegal storage access. (Attempt to read from nil?)"

image

Am I implementing incorrectly? The equivalent code for a float works as intended

image

@andreaferretti
Copy link
Collaborator

Of course the compiler should not crash - I will just mention that the code as written could not work, since the line

result = 2.0 * x

is not defined (scalar multiplication for vectors is not defined anywhere).

Also, it would be much more useful if you could post a snippet of code instead of a screenshot (use ```nim code here ```)

@uqtredd1
Copy link
Author

I had actually defined scalar to vector multipilcation but left it out of that code snippet accidentally: The full code is below:

type
  # simple vector of declared fixed length
  vector[N : static[int]] = array[0..N-1, float]

proc `*`[T](x: float, a: vector[T]): vector[T] =
  # multiplication by scalar
  for ii in 0..high(a):
    result[ii] = a[ii]*x

let
  # define a vector of length 3
  x: vector[3] = [1.0, 3.0, 5.0]

proc vectFunc[T](x: vector[T]): vector[T] {.procvar.} =
  # Define a vector function
  result = 2.0*x

proc passVectFunction[T](g: proc(x: vector[T]): vector[T], x: vector[T]): vector[T] =
  # pass a vector function as input in another procedure
  result = g(x)

let
  xNew = passVectFuncion(vectFunc,x)

It does seem to be related to the use of a generic length vector, if the vector is enforced to have length 3 for example, then the code runs as intended:

type
  vector3 = array[0..2, float]

proc `*`(x: float, a: vector3): vector3 =
  for ii in 0..high(a):
    result[ii] = a[ii]*x

let
  y: vector3 = [1.0,3.0,5.0]

proc vect3Func(x: vector3): vector3 {.procvar.} =
  result = 2.0*x

proc passVect3Function(g: proc(x: vector3): vector3 , x: vector3): vector3 =
  result = g(x)

let
  yNew = passVect3Function(vect3Func,y)

I would however like the passVectFunction to have the ability to accept generic length vectors. Is there any way to make this work?

Thanks

@andreaferretti
Copy link
Collaborator

This compiles:

type
  # simple vector of declared fixed length
  vector[N : static[int]] = array[0..N-1, float]

proc `*`[T](x: float, a: vector[T]): vector[T] =
  # multiplication by scalar
  for ii in 0..high(a):
    result[ii] = a[ii]*x

let
  # define a vector of length 3
  x: vector[3] = [1.0, 3.0, 5.0]

proc vectFunc[T](x: vector[T]): vector[T] {.procvar.} =
  # Define a vector function
  result = 2.0*x

proc passVectFunction[T](x: vector[T], g: proc(x: vector[T]): vector[T]): vector[T] =
  # pass a vector function as input in another procedure
  result = g(x)

let
  xNew = passVectFunction(x, vectFunc)

I think it has to do with the fact that type inference does not (unfortunately) perform backtracking, and Nim is not able to figure out T from the first parameter (it needs the vector to resolve T).

Still a bug, but maybe this can help you in the meantime. You can also define a template with untyped parameters to flip the order if you prefer it the other way round

@uqtredd1
Copy link
Author

Interestingly that still did not compile for me (on 0.17.0). However, when I removed the generic specifiers from vectFunc and passVectFunc (remainder of code segment unchanged)

proc vectFunc(x: vector): vector {.procvar.} =
  # Define a vector function
  result = 2.0*x

proc passVectFunction(x: vector, g: proc(x: vector): vector): vector =
  # pass a vector function as input in another procedure
  result = g(x)

It now compiles and returns the correct result, and still seems to work for generic length vectors. Thanks for your help.

@mratsim
Copy link
Collaborator

mratsim commented Aug 8, 2018

This does no crash anymore, but throws the error: Error: 'vectFunc' doesn't have a concrete type, due to unspecified generic parameters.

Close it?

Araq pushed a commit that referenced this issue Aug 8, 2018
* Add tests to confirm #7231 is fixed.

* Add test for closed #6137

* Add test for #7141
timotheecour pushed a commit to timotheecour/Nim that referenced this issue Aug 8, 2018
* Add tests to confirm nim-lang#7231 is fixed.

* Add test for closed nim-lang#6137

* Add test for nim-lang#7141
timotheecour pushed a commit to timotheecour/Nim that referenced this issue Aug 8, 2018
* Add tests to confirm nim-lang#7231 is fixed.

* Add test for closed nim-lang#6137

* Add test for nim-lang#7141
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants