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

Assignment for an array element fails in a loop #1962

Closed
evertrol opened this issue Jan 8, 2025 · 7 comments
Closed

Assignment for an array element fails in a loop #1962

evertrol opened this issue Jan 8, 2025 · 7 comments

Comments

@evertrol
Copy link

evertrol commented Jan 8, 2025

I have this simple procedure

pro testarray
  a = dblarr(2)
  k = 1
  for j = 0, 2 do begin
     print, j
     if j eq k then a[1] = -1
     print, a
     ind = where(a lt 0, /null)
     print, ind
     a[ind] = 0
     print, a
  endfor
end

When I run this (gdl -X -e testarray), the output is

       0
       0.0000000       0.0000000
!NULL
       0.0000000       0.0000000
       1
       0.0000000      -1.0000000
           1
       0.0000000      -1.0000000
       2
       0.0000000      -1.0000000
           1
       0.0000000      -1.0000000

which is not what I expect: the -1 should be changed to 0, and only show up once in the output.

If I change k to 2, similar incorrect behaviour happens. But if I change k to 0, the expected/correct behaviour happens (i.e., -1 shows up only once in the output).

If I remove the loop (and the j eq k condition), I also observe the correct behaviour.

I don't know if I'm missing something here, or whether this is an actual bug in GDL. (I am not able to test this behaviour with IDL.)

My set up is a Macbook Pro M1, Sonoma 14.6.1 (Darwin 23.6.0), running a self-installed GDL in the terminal (iTerm), with the GDL version given as GDL - GNU Data Language, Version v1.1-30-g35d32bbc.

@alaingdl
Copy link
Contributor

alaingdl commented Jan 8, 2025

Thanks for the clear report. Two bad news :

  • I succeed to reproduce the problem, on x86_64 :(
  • I absolutely not understood what happen :(

@GillesDuvert
Copy link
Contributor

IDL indeed gives

IDL> testarray
% Compiled module: TESTARRAY.
       0
       0.0000000       0.0000000
!NULL
       0.0000000       0.0000000
       1
       0.0000000      -1.0000000
           1
       0.0000000       0.0000000
       2
       0.0000000       0.0000000
!NULL
       0.0000000       0.0000000
IDL> 

@GillesDuvert
Copy link
Contributor

I wonder if this has not been around for a long time.

@GillesDuvert
Copy link
Contributor

This is a side-effect (totally unexpected) of the use of /NULL in ind = where(a lt 0, /null)
Old style to do testarray would be:

pro testarray
  a = dblarr(2)
  k = 1
  for j = 0, 2 do begin
     print, j
     if j eq k then a[1] = -1
     print, a
     ind = where(a lt 0, count)
     print, count
     if count then a[ind] = 0
     print, a
  endfor
end

With the above code (count instead of /null) the output is OK:

 GDL> testarray     
% Compiled module: TESTARRAY.
       0
       0.0000000       0.0000000
           0
       0.0000000       0.0000000
       1
       0.0000000      -1.0000000
           1
       0.0000000       0.0000000
       2
       0.0000000       0.0000000
           0
       0.0000000       0.0000000

Meaning only 'new' code using /NULL in such circumstances could be affected.

Now, this is still a bug and must be solved.

@evertrol
Copy link
Author

Thanks for the workaround.

But when I tried it, I ran into a completely different issue, as exemplified as follows:

  for i = 0, 20 do begin
     if i then print, i
  endfor

which will print only the odd values.

Even with hardcoded values, the if clause appears to evaluate to some false value for even numbers:

  if 0 then print, '0'
  if 1 then print, '1'
  if 2 then print, '2'
  if 3 then print, '3'
  if 4 then print, '4'
  if 5 then print, '5'
  if 6 then print, '6'

yields

1
3
5

I don't know what the actual expected (IDL) behaviour is for such cases where there is only an integer in the if-clause; I couldn't find where this is explicitly stated on the IDL manual pages (if this is documented somewhere). Perhaps it's even an actual error (or should be), or undefined behaviour, but someone else with IDL access will have test this.

Of course, this is easy to work around: if i gt 0 or if count gt 0 works as expected.

GillesDuvert added a commit that referenced this issue Jan 14, 2025
ignoreMe was not reset to 0 in AssignAt

Probably other cases where !NULL is not properly handled will appear.
@GillesDuvert
Copy link
Contributor

Just patched directly in master ( line 278 of arrayindexlistnoassoc.hpp )
Probably other cases where !NULL is not properly handled will surface.

@GillesDuvert
Copy link
Contributor

Thanks for the workaround.

But when I tried it, I ran into a completely different issue, as exemplified as follows:

  for i = 0, 20 do begin
     if i then print, i
  endfor

which will print only the odd values.

Even with hardcoded values, the if clause appears to evaluate to some false value for even numbers:

  if 0 then print, '0'
  if 1 then print, '1'
  if 2 then print, '2'
  if 3 then print, '3'
  if 4 then print, '4'
  if 5 then print, '5'
  if 6 then print, '6'

yields

1
3
5

I don't know what the actual expected (IDL) behaviour is for such cases where there is only an integer in the if-clause; I couldn't find where this is explicitly stated on the IDL manual pages (if this is documented somewhere). Perhaps it's even an actual error (or should be), or undefined behaviour, but someone else with IDL access will have test this.

Of course, this is easy to work around: if i gt 0 or if count gt 0 works as expected.

The behaviour depends on compile_opt logical_predicate wich is not set by default, you may want to look at the IDL documentation of this keyword on their site.
In normal case (loop variable is an integer) one gets:

IDL> for i = 0, 20 do begin & if i then print, i & end
       1
       3
       5
       7
       9
      11
      13
      15
      17
      19
IDL> 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants