Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #147976 > unrolled thread

OT: improve this simple algorithm?

Started byDFS <nospam@dfs.com>
First post2019-11-12 15:55 -0500
Last post2019-11-13 05:21 -0800
Articles 20 on this page of 100 — 16 participants

Back to article view | Back to comp.lang.c


Contents

  OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-12 15:55 -0500
    Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-12 21:20 +0000
      Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-12 23:28 -0500
        Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-13 10:52 +0100
          Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-13 10:16 -0500
            Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-13 16:53 +0100
        Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-13 11:18 +0000
    Re: OT: improve this simple algorithm? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-12 23:30 +0000
      Re: OT: improve this simple algorithm? Ian Collins <ian-news@hotmail.com> - 2019-11-15 05:12 +1300
        Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 16:34 +0000
          Re: OT: improve this simple algorithm? Ian Collins <ian-news@hotmail.com> - 2019-11-15 10:07 +1300
            Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 22:25 +0000
              Re: OT: improve this simple algorithm? Ian Collins <ian-news@hotmail.com> - 2019-11-15 12:02 +1300
                Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 23:27 +0000
                  Re: OT: improve this simple algorithm? Ian Collins <ian-news@hotmail.com> - 2019-11-15 19:06 +1300
                    Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-15 10:45 +0000
                      Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-15 13:28 +0100
                        Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-15 12:58 +0000
                          Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-15 15:39 +0100
                            Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-15 15:04 +0000
                              Re: OT: improve this simple algorithm? Richard Damon <Richard@Damon-Family.org> - 2019-11-15 12:19 -0500
                                Re: OT: improve this simple algorithm? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-11-15 09:46 -0800
                                Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-15 18:59 +0000
                            Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-16 11:59 +0000
                      Re: OT: improve this simple algorithm? Ian Collins <ian-news@hotmail.com> - 2019-11-16 09:02 +1300
                Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-15 11:17 +0100
                  Re: OT: improve this simple algorithm? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2019-11-15 21:38 +0000
      Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-14 11:44 -0500
        Re: OT: improve this simple algorithm? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-14 18:11 +0000
          Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-14 13:33 -0500
            Re: OT: improve this simple algorithm? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-15 01:49 +0000
        Re: OT: improve this simple algorithm? Barry Schwarz <schwarzb@delq.com> - 2019-11-14 10:38 -0800
      Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-14 12:56 -0500
        Re: OT: improve this simple algorithm? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-14 13:50 -0500
          Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-14 14:42 -0500
            Re: OT: improve this simple algorithm? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-14 15:25 -0500
        Re: OT: improve this simple algorithm? Barry Schwarz <schwarzb@delq.com> - 2019-11-14 11:03 -0800
          Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-14 16:08 -0500
            Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-15 11:30 +0100
              Re: OT: improve this simple algorithm? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-15 11:17 +0000
                Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-15 17:35 -0500
                  Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-15 17:39 -0500
                  Re: OT: improve this simple algorithm? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-15 23:19 +0000
                    Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-15 18:53 -0500
                      Re: OT: improve this simple algorithm? Richard Damon <Richard@Damon-Family.org> - 2019-11-15 19:08 -0500
                      Re: OT: improve this simple algorithm? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-16 01:30 +0000
                        Re: OT: improve this simple algorithm? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-16 07:39 -0500
                  Re: OT: improve this simple algorithm? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-16 07:37 -0500
            Re: OT: improve this simple algorithm? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-15 09:46 -0500
              Re: OT: improve this simple algorithm? Richard Damon <Richard@Damon-Family.org> - 2019-11-15 12:38 -0500
                Re: OT: improve this simple algorithm? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-15 23:07 +0000
                Re: OT: improve this simple algorithm? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-28 16:54 -0800
                  Re: OT: improve this simple algorithm? Richard Damon <Richard@Damon-Family.org> - 2019-11-28 20:17 -0500
                    Re: OT: improve this simple algorithm? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-29 06:08 -0800
        Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 20:45 +0100
      Re: OT: improve this simple algorithm? Keith Thompson <kst-u@mib.org> - 2019-11-14 10:10 -0800
        Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 20:19 +0100
      Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-12 23:57 -0500
        Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-13 10:34 +0100
      Re: OT: improve this simple algorithm? DFS <nospam@dfs.com> - 2019-11-13 23:57 -0500
        Re: OT: improve this simple algorithm? Barry Schwarz <schwarzb@delq.com> - 2019-11-13 23:00 -0800
        Re: OT: improve this simple algorithm? Ike Naar <ike@sdf.lonestar.org> - 2019-11-14 07:53 +0000
          Re: OT: improve this simple algorithm? guinness.tony@gmail.com - 2019-11-14 02:34 -0800
        Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 10:01 +0100
          Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 11:27 +0000
            Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 12:46 +0100
              Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 12:01 +0000
                Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 14:05 +0100
    Re: OT: improve this simple algorithm? Barry Schwarz <schwarzb@delq.com> - 2019-11-12 18:34 -0800
      Re: OT: improve this simple algorithm? Keith Thompson <kst-u@mib.org> - 2019-11-12 19:01 -0800
        Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 17:08 +0100
          Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 17:06 +0000
          Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 19:11 +0000
        Re: OT: improve this simple algorithm? Ian Collins <ian-news@hotmail.com> - 2019-11-15 05:15 +1300
        Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 18:13 +0000
          Re: OT: improve this simple algorithm? Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-14 20:16 +0100
            Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 20:03 +0000
              Re: OT: improve this simple algorithm? Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-15 04:51 +0100
        Re: OT: improve this simple algorithm? Keith Thompson <kst-u@mib.org> - 2019-11-14 10:15 -0800
          Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 20:52 +0100
        Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-13 10:57 +0100
          Re: OT: improve this simple algorithm? Ian Collins <ian-news@hotmail.com> - 2019-11-13 23:23 +1300
          Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-13 11:53 +0000
            Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-13 14:02 +0100
              Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-13 13:40 +0000
                Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-13 17:01 +0100
                  Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-13 16:28 +0000
                    Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-13 22:49 +0100
                      Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-13 22:38 +0000
                        Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-13 23:06 +0000
                        Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 10:10 +0100
                          Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 10:42 +0000
                            Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 12:53 +0100
                              Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 12:28 +0000
                                Re: OT: improve this simple algorithm? David Brown <david.brown@hesbynett.no> - 2019-11-14 14:21 +0100
                                  Re: OT: improve this simple algorithm? Bart <bc@freeuk.com> - 2019-11-14 14:28 +0000
                                    Re: OT: improve this simple algorithm? Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-14 15:38 +0100
                        Re: OT: improve this simple algorithm? Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-14 13:37 +0100
                          Re: OT: improve this simple algorithm? Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-14 13:38 +0100
            Re: OT: improve this simple algorithm? Thiago Adams <thiago.adams@gmail.com> - 2019-11-13 05:21 -0800

Page 3 of 5 — ← Prev page 1 2 [3] 4 5  Next page →


#148038

FromDFS <nospam@dfs.com>
Date2019-11-15 17:35 -0500
Message-ID<GHFzF.8708$%o2.5811@fx31.iad>
In reply to#148024
On 11/15/2019 6:17 AM, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
>> On 14/11/2019 22:08, DFS wrote:
>>> On 11/14/2019 2:03 PM, Barry Schwarz wrote:
> <cut>
>>>> ...  Some even put the definition of i inside the for
>>>> statement as in
>>>>       for (unsigned int i = 0; ...
>>>> to insure the scope is limited to the loop.  This will work even if
>>>> there is an i defined before the for statement.  The i in the for
>>>> statement hides the i defined previously but only for the duration of
>>>> the loop.
>>>
>>>
>>> Interesting.  Works in nested for..loops too:
>>>
>>>
>>>   int i = 100, j = 200;
>>>
>>>    for(int i = 0; i < 3; i++) {
>>>      for(int j = 0; j < 3; j++) {
>>>        printf("(%d %d) ",i,j);
>>>      }
>>>    }
>>>
>>>    printf("\n%d %d\n",i,j);
> 
> I though you were going to show this:
> 
>    #include <stdio.h>
>     
>    int main(void)
>    {
>         int i = 100, j = 100;
>         for (int i = 0; i < 3; i++)
>              for (int i = 0; i < 3; i++)
>                   printf("x");
>         printf(" %d %d\n", i, j);
>    }
> 
> because it really /does/ work for nested loops!


I did try that:

int i = 100, j = 200;
   for(int i = 0; i < 3; i++) {
     for(int i = 0; i < 3; i++) {
       printf("(%d %d) ",i,i);
     }		
   }
printf("\n%d %d\n",i,j);

got this output:
(0 0) (1 1) (2 2) (0 0) (1 1) (2 2) (0 0) (1 1) (2 2)
100 200

So it's not clear if there are 2 i's or not.



tried this:

int i = 100, j = 200;
   for(int i = 0; i < 3; i++) {
     for(int i = 4; i < 7; i++) {
       printf("(%d %d) ",i,i);
     }		
   }
printf("\n%d %d\n",i,j);

output:
(4 4) (5 5) (6 6) (4 4) (5 5) (6 6) (4 4) (5 5) (6 6)
100 200

So the inner i 'takes over' from the outer i.







>>> But... I see danger ahead.  I'll probably not use that technique.
> 
> I see danger the other way.  Using a short variable name like i or j for
> several different things can be confusing for the reader, and you can't
> get any help from the compiler.  But if your for-loop-constrained
> variable happens to shadow the same name in an outer scope, you can get
> the compiler to tell you.
> 

[toc] | [prev] | [next] | [standalone]


#148040

FromDFS <nospam@dfs.com>
Date2019-11-15 17:39 -0500
Message-ID<lLFzF.28660$1S4.26070@fx01.iad>
In reply to#148038
On 11/15/2019 5:35 PM, DFS wrote:
> On 11/15/2019 6:17 AM, Ben Bacarisse wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>
>>> On 14/11/2019 22:08, DFS wrote:
>>>> On 11/14/2019 2:03 PM, Barry Schwarz wrote:
>> <cut>
>>>>> ...  Some even put the definition of i inside the for
>>>>> statement as in
>>>>>       for (unsigned int i = 0; ...
>>>>> to insure the scope is limited to the loop.  This will work even if
>>>>> there is an i defined before the for statement.  The i in the for
>>>>> statement hides the i defined previously but only for the duration of
>>>>> the loop.
>>>>
>>>>
>>>> Interesting.  Works in nested for..loops too:
>>>>
>>>>
>>>>   int i = 100, j = 200;
>>>>
>>>>    for(int i = 0; i < 3; i++) {
>>>>      for(int j = 0; j < 3; j++) {
>>>>        printf("(%d %d) ",i,j);
>>>>      }
>>>>    }
>>>>
>>>>    printf("\n%d %d\n",i,j);
>>
>> I though you were going to show this:
>>
>>    #include <stdio.h>
>>    int main(void)
>>    {
>>         int i = 100, j = 100;
>>         for (int i = 0; i < 3; i++)
>>              for (int i = 0; i < 3; i++)
>>                   printf("x");
>>         printf(" %d %d\n", i, j);
>>    }
>>
>> because it really /does/ work for nested loops!
> 
> 
> I did try that:
> 
> int i = 100, j = 200;
>    for(int i = 0; i < 3; i++) {
>      for(int i = 0; i < 3; i++) {
>        printf("(%d %d) ",i,i);
>      }
>    }
> printf("\n%d %d\n",i,j);
> 
> got this output:
> (0 0) (1 1) (2 2) (0 0) (1 1) (2 2) (0 0) (1 1) (2 2)
> 100 200
> 
> So it's not clear if there are 2 i's or not.

Whoops... it IS clear the outer i is replaced by the inner.

> 
> 
> tried this:
> 
> int i = 100, j = 200;
>    for(int i = 0; i < 3; i++) {
>      for(int i = 4; i < 7; i++) {
>        printf("(%d %d) ",i,i);
>      }
>    }
> printf("\n%d %d\n",i,j);
> 
> output:
> (4 4) (5 5) (6 6) (4 4) (5 5) (6 6) (4 4) (5 5) (6 6)
> 100 200
> 
> So the inner i 'takes over' from the outer i.
> 
> 
> 
> 
> 
> 
> 
>>>> But... I see danger ahead.  I'll probably not use that technique.
>>
>> I see danger the other way.  Using a short variable name like i or j for
>> several different things can be confusing for the reader, and you can't
>> get any help from the compiler.  But if your for-loop-constrained
>> variable happens to shadow the same name in an outer scope, you can get
>> the compiler to tell you.
>>
> 

[toc] | [prev] | [next] | [standalone]


#148042

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2019-11-15 23:19 +0000
Message-ID<87bltck9rs.fsf@bsb.me.uk>
In reply to#148038
DFS <nospam@dfs.com> writes:
<cut>
> I did try that:
>
> int i = 100, j = 200;
>   for(int i = 0; i < 3; i++) {
>     for(int i = 0; i < 3; i++) {
>       printf("(%d %d) ",i,i);
>     }		
>   }
> printf("\n%d %d\n",i,j);
>
> got this output:
> (0 0) (1 1) (2 2) (0 0) (1 1) (2 2) (0 0) (1 1) (2 2)
> 100 200
>
> So it's not clear if there are 2 i's or not.

At different times in the program's execution there are one, two or
three objects named i, but at every point only one of them can be
accessed using the name i.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#148043

FromDFS <nospam@dfs.com>
Date2019-11-15 18:53 -0500
Message-ID<bTGzF.61896$kt1.27048@fx46.iad>
In reply to#148042
On 11/15/2019 6:19 PM, Ben Bacarisse wrote:
> DFS <nospam@dfs.com> writes:
> <cut>
>> I did try that:
>>
>> int i = 100, j = 200;
>>    for(int i = 0; i < 3; i++) {
>>      for(int i = 0; i < 3; i++) {
>>        printf("(%d %d) ",i,i);
>>      }		
>>    }
>> printf("\n%d %d\n",i,j);
>>
>> got this output:
>> (0 0) (1 1) (2 2) (0 0) (1 1) (2 2) (0 0) (1 1) (2 2)
>> 100 200
>>
>> So it's not clear if there are 2 i's or not.
> 
> At different times in the program's execution there are one, two or
> three objects named i, but at every point only one of them can be
> accessed using the name i.

How do you inspect the value of the 2 'outer' i objects once you reach 
the inner loop?

[toc] | [prev] | [next] | [standalone]


#148044

FromRichard Damon <Richard@Damon-Family.org>
Date2019-11-15 19:08 -0500
Message-ID<o6HzF.93604$FT5.87499@fx03.iad>
In reply to#148043
On 11/15/19 6:53 PM, DFS wrote:
> On 11/15/2019 6:19 PM, Ben Bacarisse wrote:
>> DFS <nospam@dfs.com> writes:
>> <cut>
>>> I did try that:
>>>
>>> int i = 100, j = 200;
>>>    for(int i = 0; i < 3; i++) {
>>>      for(int i = 0; i < 3; i++) {
>>>        printf("(%d %d) ",i,i);
>>>      }       
>>>    }
>>> printf("\n%d %d\n",i,j);
>>>
>>> got this output:
>>> (0 0) (1 1) (2 2) (0 0) (1 1) (2 2) (0 0) (1 1) (2 2)
>>> 100 200
>>>
>>> So it's not clear if there are 2 i's or not.
>>
>> At different times in the program's execution there are one, two or
>> three objects named i, but at every point only one of them can be
>> accessed using the name i.
> 
> How do you inspect the value of the 2 'outer' i objects once you reach
> the inner loop?
> 
> 

You can't, except by ending that scope and going out to the scope that
the outer i exists in. (or making a pointer to them at the outer scope
where they are accessable)

This is one reason it isn't a good idea, those outer i's are in
accessable by name.

[toc] | [prev] | [next] | [standalone]


#148045

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2019-11-16 01:30 +0000
Message-ID<875zjkk3qa.fsf@bsb.me.uk>
In reply to#148043
DFS <nospam@dfs.com> writes:

> On 11/15/2019 6:19 PM, Ben Bacarisse wrote:
>> DFS <nospam@dfs.com> writes:
>> <cut>
>>> I did try that:
>>>
>>> int i = 100, j = 200;
>>>    for(int i = 0; i < 3; i++) {
>>>      for(int i = 0; i < 3; i++) {
>>>        printf("(%d %d) ",i,i);
>>>      }		
>>>    }
>>> printf("\n%d %d\n",i,j);
>>>
>>> got this output:
>>> (0 0) (1 1) (2 2) (0 0) (1 1) (2 2) (0 0) (1 1) (2 2)
>>> 100 200
>>>
>>> So it's not clear if there are 2 i's or not.
>>
>> At different times in the program's execution there are one, two or
>> three objects named i, but at every point only one of them can be
>> accessed using the name i.
>
> How do you inspect the value of the 2 'outer' i objects once you reach
> the inner loop?

You could, for example, use a pointer:

     for (int i = 0, *ip = &i; i < 3; i++)
          for (int i = 0; i < 3; i++)
               printf("%d %d\n", i, *ip);

However, why would you?  You'd use different names if you wanted to talk
about both objects.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#148049

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-11-16 07:39 -0500
Message-ID<qqoqli$lqf$2@dont-email.me>
In reply to#148045
On 11/15/19 8:30 PM, Ben Bacarisse wrote:
> DFS <nospam@dfs.com> writes:
...
>> How do you inspect the value of the 2 'outer' i objects once you reach
>> the inner loop?
> 
> You could, for example, use a pointer:
> 
>      for (int i = 0, *ip = &i; i < 3; i++)
>           for (int i = 0; i < 3; i++)
>                printf("%d %d\n", i, *ip);
> 
> However, why would you?  You'd use different names if you wanted to talk
> about both objects.

The only point in doing so is to prove that there are two different
objects, both named i - which was his original purpose in writing this code.

[toc] | [prev] | [next] | [standalone]


#148048

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-11-16 07:37 -0500
Message-ID<qqoqi2$lqf$1@dont-email.me>
In reply to#148038
On 11/15/19 5:35 PM, DFS wrote:
...
> int i = 100, j = 200;
>    for(int i = 0; i < 3; i++) {
>      for(int i = 0; i < 3; i++) {
>        printf("(%d %d) ",i,i);
>      }		
>    }
> printf("\n%d %d\n",i,j);
> 
> got this output:
> (0 0) (1 1) (2 2) (0 0) (1 1) (2 2) (0 0) (1 1) (2 2)
> 100 200
> 
> So it's not clear if there are 2 i's or not.

How in the world did you expect to be able to refer to two different i's
using the same name for both? 'i' is necessarily either ambiguous or can
refer to only one particular object. In C, it is the latter. Identifiers
have a scope, and identifiers declared in an inner scope hide
identifiers in an outer scope. Identifiers declared in a block (like the
first i) have a scope that extends to the end of the block. The scope of
identifiers declared in the first part of a for-statement have a scope
that extends to the end of the for-statement. The first for-statement
occurs inside the outer block, and the second for-statement occurs
inside the second for statement, so each declaration of 'i' hides the
previous ones.

[toc] | [prev] | [next] | [standalone]


#148029

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-11-15 09:46 -0500
Message-ID<qqmdp6$98o$1@dont-email.me>
In reply to#148004
On 11/14/19 4:08 PM, DFS wrote:
> On 11/14/2019 2:03 PM, Barry Schwarz wrote:
...
>> warning at all.  Some even put the definition of i inside the for
>> statement as in
>>      for (unsigned int i = 0; ...
>> to insure the scope is limited to the loop.  This will work even if
>> there is an i defined before the for statement.  The i in the for
>> statement hides the i defined previously but only for the duration of
>> the loop.
> 
> 
> Interesting.  Works in nested for..loops too:
> 
> 
>   int i = 100, j = 200;
> 
>    for(int i = 0; i < 3; i++) {
>      for(int j = 0; j < 3; j++) {
>        printf("(%d %d) ",i,j);
>      }		
>    }
> 
>    printf("\n%d %d\n",i,j);
> 
> 
> (0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2)
> 100 200
> 
> But... I see danger ahead.  I'll probably not use that technique.

I'm curious: what danger do you think you see? This feature was added
specifically to reduce the danger of your loop variables interacting
with code outside the loop. If you want your variables to interact with
code outside the loop, declare them outside the loop, as has always been
permitted - this feature does nothing to interfere with the old ways of
doing things.

[toc] | [prev] | [next] | [standalone]


#148032

FromRichard Damon <Richard@Damon-Family.org>
Date2019-11-15 12:38 -0500
Message-ID<BoBzF.13507$MR5.3188@fx28.iad>
In reply to#148029
On 11/15/19 9:46 AM, James Kuyper wrote:
> On 11/14/19 4:08 PM, DFS wrote:
>> On 11/14/2019 2:03 PM, Barry Schwarz wrote:
> ...
>>> warning at all.  Some even put the definition of i inside the for
>>> statement as in
>>>      for (unsigned int i = 0; ...
>>> to insure the scope is limited to the loop.  This will work even if
>>> there is an i defined before the for statement.  The i in the for
>>> statement hides the i defined previously but only for the duration of
>>> the loop.
>>
>>
>> Interesting.  Works in nested for..loops too:
>>
>>
>>   int i = 100, j = 200;
>>
>>    for(int i = 0; i < 3; i++) {
>>      for(int j = 0; j < 3; j++) {
>>        printf("(%d %d) ",i,j);
>>      }		
>>    }
>>
>>    printf("\n%d %d\n",i,j);
>>
>>
>> (0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2)
>> 100 200
>>
>> But... I see danger ahead.  I'll probably not use that technique.
> 
> I'm curious: what danger do you think you see? This feature was added
> specifically to reduce the danger of your loop variables interacting
> with code outside the loop. If you want your variables to interact with
> code outside the loop, declare them outside the loop, as has always been
> permitted - this feature does nothing to interfere with the old ways of
> doing things.
> 
As I remember, at one stage in the development of this feature, the
statement

for(int i = 0; i < 3; i++){
}

was the equivalent of

int i;
for(i = 0; i < 3; i++){
}

i.e., the defined variable existed after the loop. It was thought that
since the definition wasn't within the braces, the scope shouldn't be
limited to the braces. I am fairly sure this even appeared in some of
the draft standard documents. In working with this, it was decided that
this caused too many issues, so they added a bit of complexity to the
language by moving the effective scope of the block to include the
control statement.

One advantage of the older definition was that a loop like

for(int i = 0; i < nentries; i++) if(table[i] == key) break;

could be a one liner to find an entry in a table and the value available
after the loop. It now needs to be written as

int i; for(i = 0; i < nentries; i++) if(table[i] == key) break;

so the initialization of i get removed from its creation.

It also means that some compilers have a switch to bring back the now
'incorrect' scoping rule, and if you get some code that needs that
switch, you can get confused. At least it wasn't that common to shadow
definitions as the definition to shadow needed to be another layer out.

[toc] | [prev] | [next] | [standalone]


#148041

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2019-11-15 23:07 +0000
Message-ID<87h834kab8.fsf@bsb.me.uk>
In reply to#148032
Richard Damon <Richard@Damon-Family.org> writes:
<cut>
> As I remember, at one stage in the development of this feature, the
> statement
>
> for(int i = 0; i < 3; i++){
> }
>
> was the equivalent of
>
> int i;
> for(i = 0; i < 3; i++){
> }
<cut>
> One advantage of the older definition was that a loop like
>
> for(int i = 0; i < nentries; i++) if(table[i] == key) break;
>
> could be a one liner to find an entry in a table and the value available
> after the loop. It now needs to be written as
>
> int i; for(i = 0; i < nentries; i++) if(table[i] == key) break;

Some would say it should always have been written as

  int i = 0; while (i < nentries && table[i] != key) i++;

:-)

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#148207

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2019-11-28 16:54 -0800
Message-ID<86a78f8pto.fsf@linuxsc.com>
In reply to#148032
Richard Damon <Richard@Damon-Family.org> writes:

> On 11/15/19 9:46 AM, James Kuyper wrote:
>
>> On 11/14/19 4:08 PM, DFS wrote:
>>
>>> On 11/14/2019 2:03 PM, Barry Schwarz wrote:
>>
>> ...
>>
>>>> warning at all.  Some even put the definition of i inside the for
>>>> statement as in
>>>>      for (unsigned int i = 0; ...
>>>> to insure the scope is limited to the loop.  This will work even if
>>>> there is an i defined before the for statement.  The i in the for
>>>> statement hides the i defined previously but only for the duration of
>>>> the loop.
>>>
>>> Interesting.  Works in nested for..loops too:
>>>
>>>
>>>   int i = 100, j = 200;
>>>
>>>    for(int i = 0; i < 3; i++) {
>>>      for(int j = 0; j < 3; j++) {
>>>        printf("(%d %d) ",i,j);
>>>      }		
>>>    }
>>>
>>>    printf("\n%d %d\n",i,j);
>>>
>>>
>>> (0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2)
>>> 100 200
>>>
>>> But... I see danger ahead.  I'll probably not use that technique.
>>
>> I'm curious:  what danger do you think you see?  This feature was
>> added specifically to reduce the danger of your loop variables
>> interacting with code outside the loop.  If you want your variables
>> to interact with code outside the loop, declare them outside the
>> loop, as has always been permitted - this feature does nothing to
>> interfere with the old ways of doing things.
>
> As I remember, at one stage in the development of this feature,
> the statement
>
> for(int i = 0; i < 3; i++){
> }
>
> was the equivalent of
>
> int i;
> for(i = 0; i < 3; i++){
> }
>
> i.e., the defined variable existed after the loop.  It was thought
> that since the definition wasn't within the braces, the scope
> shouldn't be limited to the braces.  I am fairly sure this even
> appeared in some of the draft standard documents.

To set the record straight, this was never true for C.  The draft
where declarations-in-for's first appeared limited the scope of
the declared variable(s) to the for statement (and its body), and
not further.

What you may have been thinking of was C++.  Before C++ was first
standardized, it did have for-declarations with the semantics you
describe.  It was defined that way in one of Stroustrup's books
(second edition, roughly 1995, IIRC).  This behavior was actually
part of the official language, and programs made use of it.  Last I
checked there are still gcc options -ffor-scope and -fno-for-scope
to allow getting the old semantics (and they apply only to C++).

> In working with this, it was decided that this caused too many
> issues, so they added a bit of complexity to the language by
> moving the effective scope of the block to include the control
> statement.

Here again this statement holds for C++ but not for C.  The original
C++ semantics (ie, in draft standards) was a bit messy.  The C
semantics did change between the original introduction and the next
draft, but has always been pretty clean, and was never of the
"moving scopes around" variety that the early C++ standards (or
drafts thereof) used.

Thus we see that James Kuyper's statement "This feature was added
specifically to reduce the danger of your loop variables interacting
with code outside the loop" isn't really right.  That is where the
feature ended up, but it is not where it started.

[toc] | [prev] | [next] | [standalone]


#148208

FromRichard Damon <Richard@Damon-Family.org>
Date2019-11-28 20:17 -0500
Message-ID<Ik_DF.214923$oT5.41805@fx47.iad>
In reply to#148207
On 11/28/19 7:54 PM, Tim Rentsch wrote:
> Richard Damon <Richard@Damon-Family.org> writes:
> 
>> On 11/15/19 9:46 AM, James Kuyper wrote:
>>
>>> On 11/14/19 4:08 PM, DFS wrote:
>>>
>>>> On 11/14/2019 2:03 PM, Barry Schwarz wrote:
>>>
>>> ...
>>>
>>>>> warning at all.  Some even put the definition of i inside the for
>>>>> statement as in
>>>>>      for (unsigned int i = 0; ...
>>>>> to insure the scope is limited to the loop.  This will work even if
>>>>> there is an i defined before the for statement.  The i in the for
>>>>> statement hides the i defined previously but only for the duration of
>>>>> the loop.
>>>>
>>>> Interesting.  Works in nested for..loops too:
>>>>
>>>>
>>>>   int i = 100, j = 200;
>>>>
>>>>    for(int i = 0; i < 3; i++) {
>>>>      for(int j = 0; j < 3; j++) {
>>>>        printf("(%d %d) ",i,j);
>>>>      }		
>>>>    }
>>>>
>>>>    printf("\n%d %d\n",i,j);
>>>>
>>>>
>>>> (0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2)
>>>> 100 200
>>>>
>>>> But... I see danger ahead.  I'll probably not use that technique.
>>>
>>> I'm curious:  what danger do you think you see?  This feature was
>>> added specifically to reduce the danger of your loop variables
>>> interacting with code outside the loop.  If you want your variables
>>> to interact with code outside the loop, declare them outside the
>>> loop, as has always been permitted - this feature does nothing to
>>> interfere with the old ways of doing things.
>>
>> As I remember, at one stage in the development of this feature,
>> the statement
>>
>> for(int i = 0; i < 3; i++){
>> }
>>
>> was the equivalent of
>>
>> int i;
>> for(i = 0; i < 3; i++){
>> }
>>
>> i.e., the defined variable existed after the loop.  It was thought
>> that since the definition wasn't within the braces, the scope
>> shouldn't be limited to the braces.  I am fairly sure this even
>> appeared in some of the draft standard documents.
> 
> To set the record straight, this was never true for C.  The draft
> where declarations-in-for's first appeared limited the scope of
> the declared variable(s) to the for statement (and its body), and
> not further.
> 
> What you may have been thinking of was C++.  Before C++ was first
> standardized, it did have for-declarations with the semantics you
> describe.  It was defined that way in one of Stroustrup's books
> (second edition, roughly 1995, IIRC).  This behavior was actually
> part of the official language, and programs made use of it.  Last I
> checked there are still gcc options -ffor-scope and -fno-for-scope
> to allow getting the old semantics (and they apply only to C++).
> 
>> In working with this, it was decided that this caused too many
>> issues, so they added a bit of complexity to the language by
>> moving the effective scope of the block to include the control
>> statement.
> 
> Here again this statement holds for C++ but not for C.  The original
> C++ semantics (ie, in draft standards) was a bit messy.  The C
> semantics did change between the original introduction and the next
> draft, but has always been pretty clean, and was never of the
> "moving scopes around" variety that the early C++ standards (or
> drafts thereof) used.
> 
> Thus we see that James Kuyper's statement "This feature was added
> specifically to reduce the danger of your loop variables interacting
> with code outside the loop" isn't really right.  That is where the
> feature ended up, but it is not where it started.
> 

I will admit that could be how it started. I have been using both
languages for a long time and can easily have mixed the rules that differed.

[toc] | [prev] | [next] | [standalone]


#148287

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2019-11-29 06:08 -0800
Message-ID<86wobi7p1y.fsf@linuxsc.com>
In reply to#148208
Richard Damon <Richard@Damon-Family.org> writes:

>> [..how we might have arrived at the current semantics for
>>    declarations in for() loops..]
>
> I will admit that could be how it started.  I have been using both
> languages for a long time and can easily have mixed the rules that
> differed.

I should say here that my comments were meant only to clarify the
actual history.  What you were saying is basically right, just an
accidental switch of C and C++, which is perfectly understandable
given how long ago it happened and what was going on with the two
languages at the time.  I was confused at first when I looked just
at the C historical documents, but when I dug a little deeper and
looked at C++ it all made sense.  Despite how my comments may have
sounded my intention was to affirm the core thesis that you were
suggesting.  Sorry if it came across otherwise.

[toc] | [prev] | [next] | [standalone]


#148000

FromDavid Brown <david.brown@hesbynett.no>
Date2019-11-14 20:45 +0100
Message-ID<qqkask$elg$1@dont-email.me>
In reply to#147987
On 14/11/2019 18:56, DFS wrote:
> On 11/14/2019 4:01 AM, David Brown wrote:
>> On 14/11/2019 05:57, DFS wrote:
>>>
>>> That recursion is pretty cool.
>>>
>>> I was inspired to decrapify mine (still iterative tho):
>>> ================================================================
>>> #include <stdio.h>
>>> #include <stdlib.h>
>>>
>>> int main(void) {
>>>
>>>    int seq[] = {1, 2, 4, 5, 7, 8, 12, 1300, 10000};
>>>
>>>    for(int i=0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
>>>      if(seq[i + 1] - seq[i] > 1) {
>>>        if( seq[i + 1] - (seq[i] + 1) >= 1) {
>>>          printf("[%d,%d] ", seq[i] + 1, seq[i + 1] - 1);
>>>        }
>>>      }
>>>    }
>>>
>>> }
>>> ================================================================
> 
> 
> This is a really good analysis, David.  I'm embarrassed to mess up such 
> a tiny bit of C code - but it works anyway?
> 

Making mistakes is part of the learning process.  And it was a nice 
mistake for demonstrating tools to help catch such mistakes, so it was a 
positive thing that you posted it.

But don't get the idea that "it worked anyway".  Don't get in the habit 
of thinking "it worked when I tested it, it must be correct" - bad code 
can work by luck during testing, and you can be sure it will fail by 
luck when used later on.

> 
> The fix is subtract 1 from the seq size:
> 
> i < (sizeof(seq) / sizeof(seq[0])) - 1
> 

Yes.  Or you can use Ben's alternative of starting from 1.  Or my own 
preference:

int main(void) {
     const int seq[] = {1, 2, 4, 5, 7, 8, 12, 1300, 10000};
     const int seqlen = sizeof(seq) / sizeof(seq[0]);

     for (int i = 0; i < seqlen - 1; i++) {
         if (seq[i + 1] - seq[i] > 1) {
             printf("[%d, %d] ", seq[i] + 1, seq[i + 1] - 1);
         }
     }

     printf("\n");
}

I prefer not to have overly complex expressions in the "for" controlling 
expressions.  Local variables are free - use them whenever they might 
help clarity.

(And note, if you will, the more consistent use of spacing.  I am a 
strong fan of space in code.  The exact details of where you have spaces 
and where you don't is a matter of style and preference, but consistency 
is always good.)


> 
> 
>> This is getting good, but is not bug-free yet.
> 
> It's not bloat-free, either.  Barry Schwarz pointed out the line before 
> the printf() is redundant.
> 
> if( seq[i + 1] - (seq[i] + 1) >= 1) {
> 
> The code works with or without that line.

It was redundant, yes.  But it wasn't the source of a bug.

> 
> 
> 
>> Let's look at how tools can help, with this program saved as "seq.c".
>>
>>     tcc seq.c -Wall -o seq
>>
>> No output - tcc is happy, and can't help you any more.
>>
>> (But it runs in 4 ms on my machine.  Yeah!  That's more than ten times
>> faster than gcc, saving me 50 milliseconds!  If I do this often enough,
>> tcc will have saved me enough time to blink.)
> 
> ha!
> 
> 
>>     gcc -Wall -Wextra seq.c -o seq
>>
>> seq.c: In function ‘main’:
>> seq.c:8:18: warning: comparison between signed and unsigned integer
>> expressions [-Wsign-compare]
>>     for(int i=0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
>>
>>
>> gcc has found a potential problem.  It is not, in this case, a real
>> problem in the code.  It is fine to compare a signed type and an
>> unsigned type - /if/ you know the values will be valid after the integer
>> promotions used by C to make both sides the same type.  These integer
>> promotion rules are not always obvious, especially to someone new to the
>> language, and it is easy to make mistakes.  So many compilers can warn
>> you when you mix signed and unsigned types in comparisons, even though
>> it is a false positive in this case.
> 
> Since sizeof(seq)/sizeof(seq[0]) can only be >= 0 the compiler? decides 
> the result is unsigned, is that right?

No.  "sizeof" gives an expression of type "size_t", which is always an 
unsigned type (typically an alias for "unsigned long" or "unsigned long 
long" on most systems).  Thus is is of unsigned type.

So when when comparing the signed int "i" to this expression, the 
compiler (following the rules of the language) will convert "i" to the 
same unsigned type as "size_t" (unless size_t is smaller than an "int" - 
hypothetically possible, but not at all likely).  Converting a signed 
value into an unsigned value could change its value.  So the compiler 
can give a warning here to tell you there might be something unexpected 
going on.

<https://en.cppreference.com/w/c/language/conversion>


> 
> Comparing int i to the (unsigned int) number of elements in the array is 
> somehow worth a warning?  Not an egregious warning, but this is the kind 
> of thing that makes some people dislike C.  It's like you can't write 
> working, reasonable code without being smacked on the back of the hand 
> with a ruler.
> 

The day you find that "(-1 > 0x80000000)" evaluates as "true" on most C 
systems, you will be glad of compilers giving you such warnings.

There is no choice of implicit conversion rules that would work well in 
every case and be as efficient as people want from a language like C - 
the rules were picked to give the best (or least bad) results for most 
cases.

> 
> 
>> So let's disable that particular warning for now.  (Alternatively, we
>> could change the type of "i" to "unsigned int", or cast the sizeof
>> expression to an int.)
> 
> Or we could run screaming from C... but that execution speed is very 
> addicting.
> 

C is not for everyone, nor for every programming task.  It is an 
excellent choice in some circumstances, but you need to know its rules 
and quirks.  And you need to learn to work /with/ the language and 
tools, not /against/ them.  That does not mean you have to like all the 
rules - no one does.  You just have to obey them when you use C.  (And 
feel free to use other languages too - no one in c.l.c. will be upset.)

> 
> 
>>     gcc -Wall -Wextra seq.c -o seq -Wno-sign-compare
>>
>> No warnings now.  gcc has done all it can.
>>
>> Or has it?
> 
>> Remember I told you to enable optimisation for better static analysis?
>>
>> gcc -Wall -Wextra seq.c -o seq -Wno-sign-compare -O2
>>
>> seq.c: In function ‘main’:
>> seq.c:9:11: warning: iteration 8 invokes undefined behavior
>> [-Waggressive-loop-optimizations]
>>       if(seq[i + 1] - seq[i] > 1) {
>>          ~~~^~~~~~~
>> seq.c:8:3: note: within this loop
>>     for(int i=0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
>>     ^~~
> 
> 
> Bingo!
> 
> I've just been replaced by 3 letters in the compiler instruction.
> 
> 
> 
>> There we go.  gcc has found your bug.  It has pointed out exactly what
>> is going wrong, and where. 
> 
> I'm sure you know python doesn't let you get away with running past the 
> last element.
> 
> seq = [1, 2, 4, 5, 7, 8, 12, 13, 1300, 10000]
> for i in range(len(seq)):
>      if (seq[i + 1] - seq[i]) > 1:
>          print("[%d,%d] " % (seq[i] + 1, seq[i + 1] - 1)),
> 
> 
> $ python getintervals.py
> [3,3]  [6,6]  [9,11]  [14,1299]  [1301,9999]
> Traceback (most recent call last):
>    File "getintervals2.py", line 3, in <module>
>      if (seq[i + 1] - seq[i]) > 1:
> IndexError: list index out of range
> 
> 
> It's interesting that C will let you hang yourself in some ways, but is 
> so demanding in others.
> 

C is a language that trusts the programmer - it does not add any extra 
checks that you have not asked for.

> 
> 
>> /That/ is why you should use gcc (or clang,
>> or MSVC) for development, with warnings enabled and with optimisation
>> enabled.  Ignore the muppets who tell you you want a fast and simple
>> compiler for development, and ignore the muppets who tell you to use
>> "debug" builds with no optimisation.
>>
>>
>> Let us progress - we will take the blasé attitude that "it's only a
>> warning", and try the generated program:
>>
>> ./seq
>> [3,3] [6,6] [9,11] [13,1299] [1301,9999] [10001,32743]
>>
>> We see two things here.  One is the unexpected extra interval at the
>> end.  This shows that something has gone wrong.  (The value it shows for
>> the last number will vary.) 
> 
> 
> If I print each [seq[i],seq[i+1]], the last 2 are:
> 
> gcc in MSYS2: [1301,9999]     [10000,0]
> tcc Windows : [10000,1310544] [10001,1310543]
> 

This is undefined behaviour - /anything/ could happen.  It is unlikely, 
but you /could/ get :

   [1301,9999] [10001,reformating hard drive...]

More realistically, you will get whatever happened to be in the invalid 
memory at the time.

> 
>> We also see that you should add a
>> "printf("\n");" line at the end of the function.
> 
> a nit
> 

Yes - but strive to make your programs as nice as you can.  It's all 
good practice.

> 
>> So (still pretending we did not see the warning from gcc showing the
>> problem), we know something is wrong - but we don't know what.  That is
>> where sanitizers come in:
>>
>> gcc -Wall -Wextra seq.c -o seq -Wno-sign-compare -O2 -fsanitize=undefined
>>
>> ./seq
>>
>> seq.c:9:11: runtime error: index 9 out of bounds for type 'int [9]'
>> seq.c:9:11: runtime error: load of address 0x7ffc5116f764 with
>> insufficient space for an object of type 'int'
>> 0x7ffc5116f764: note: pointer points here
>>    10 27 00 00 00 00 00 00  00 9a ab 7b ce 5c 60 44  a0 d9 c2 c8 07 7f 00
>> 00  00 00 00 00 00 00 00 00
>>
>> The sanitizer has spotted the problem with the out of bounds access to
>> the array, on line 9 of the seq.c file.  That is plenty of information
>> for finding and fixing the error.
> 
> Yep.  Perfect.
> 
> 
> 
>> Give these gcc options a shot before you fix the program.  Then use them
>> regularly in your development for checking your code.
>>
>> Other useful sanitize options include:
>>
>>     -fsanitize=address
>>
>> for checking memory and pointers,
>>
>>     -fsanitize=leak
>>
>> for checking malloc/free leaks, and
>>
>>     -fsanitize=thread
>>
>> for multi-threaded stuff.
> 
> 
> I'll definitely look into them.

(Skip the multi-threading stuff for now!)

> 
> Thanks again for your in-depth assistance.  I appreciate you taking the 
> time.

I hope it helps you and others.

[toc] | [prev] | [next] | [standalone]


#147988

FromKeith Thompson <kst-u@mib.org>
Date2019-11-14 10:10 -0800
Message-ID<ln7e422ush.fsf@kst-u.example.com>
In reply to#147978
Bart <bc@freeuk.com> writes:
[...]
>> gcc -Wall -Wextra seq.c -o seq -Wno-sign-compare -O2 -fsanitize=undefined
>
> I get 'cannot find -lubsan', on Windows.
[...]

Apparently in some gcc configurations, the "-fsanitize=undefined"
option causes to (attempt to) link a "libubsan" library.  UBSan is an
"undefined behaviour sanitizer".

I have that library on my Ubuntu system, but I don't see it being
linked when I invoke gcc with those options.  I haven't reproduced
the problem on Windows, but I'm sure my Windows environment is
different from Bart's.

A quick look at the gcc documentation reveals the
'-fsanitize-undefined-trap-on-error' option, which causes it to use
'__builtin_trap' rather than a libubsan library routine.  That would
be a way to avoid the dependency.

Readers other than Bart might find this interesting.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#147998

FromDavid Brown <david.brown@hesbynett.no>
Date2019-11-14 20:19 +0100
Message-ID<qqk9cq$50a$1@dont-email.me>
In reply to#147988
On 14/11/2019 19:10, Keith Thompson wrote:
> Bart <bc@freeuk.com> writes:
> [...]
>>> gcc -Wall -Wextra seq.c -o seq -Wno-sign-compare -O2 -fsanitize=undefined
>>
>> I get 'cannot find -lubsan', on Windows.
> [...]
> 
> Apparently in some gcc configurations, the "-fsanitize=undefined"
> option causes to (attempt to) link a "libubsan" library.  UBSan is an
> "undefined behaviour sanitizer".
> 
> I have that library on my Ubuntu system, but I don't see it being
> linked when I invoke gcc with those options.  I haven't reproduced
> the problem on Windows, but I'm sure my Windows environment is
> different from Bart's.

Libusbsan has the code for printing out the error messages and stack 
dumps when undefined behaviour is found (the actual checking is handled 
inline in the generated code).  It may be a shared library, or a static 
library, and that may vary from system to system.  I haven't looked at 
that in detail.

> 
> A quick look at the gcc documentation reveals the
> '-fsanitize-undefined-trap-on-error' option, which causes it to use
> '__builtin_trap' rather than a libubsan library routine.  That would
> be a way to avoid the dependency.
> 

Yes.  Typically, on hosted systems, you will still get a hard exit.  But 
you'll get less detailed information shown after the program stops.  (It 
is, however, a good choice for embedded systems or anything else that 
doesn't have a stderr output.)

> Readers other than Bart might find this interesting.
> 

[toc] | [prev] | [next] | [standalone]


#148214

FromDFS <nospam@dfs.com>
Date2019-11-12 23:57 -0500
Message-ID<S1MyF.7466$Uo6.4509@fx32.iad>
In reply to#147978
On 11/12/2019 6:30 PM, Ben Bacarisse wrote:
> DFS <nospam@dfs.com> writes:
> 
>> You clc guys are masters at this stuff.
>>
>> Goal: Find all the open intervals in an ordered set of numbers
>>
>> nbrs  = [1, 2, 4, 5, 7, 12, 1300, 10000]
>> opens = [(3, 3), (6, 6), (8, 11), (13, 1299), (1301, 9999)]
>>
>> I think 'open intervals' is the right terminology.
> 
> Not really.  The open interval (3, 3) contains no integers where as the
> closed interval [3, 3] contains exactly one integer: 3.


OK.  'gaps of closed intervals in a bounded, monotonically increasing, 
integer sequence' it is.


>    void print_gaps(int n, const int *data)
>    {
>         if (n > 1) {
>              if (data[0] + 1 < data[1])
>                   printf(" (%d, %d)", data[0] + 1, data[1] - 1);
>              print_gaps(n - 1, data + 1);
>         }
>    }
> 
> To test drive it I used:
> 
>    int main(int argc, char **argv)
>    {
>         if (argc > 1) {
>              int seq[argc-1];
>              for (int a = 1; a < argc; a++)
>                   seq[a-1] = atoi(argv[a]);
>              print_gaps(argc-1, seq);
>              putchar('\n');
>         }
>    }


If you print the whole code I'll run it.



[toc] | [prev] | [next] | [standalone]


#148218

FromDavid Brown <david.brown@hesbynett.no>
Date2019-11-13 10:34 +0100
Message-ID<qqgimg$isl$1@dont-email.me>
In reply to#148214
On 13/11/2019 05:57, DFS wrote:
> On 11/12/2019 6:30 PM, Ben Bacarisse wrote:
>> DFS <nospam@dfs.com> writes:
>>
>>> You clc guys are masters at this stuff.
>>>
>>> Goal: Find all the open intervals in an ordered set of numbers
>>>
>>> nbrs  = [1, 2, 4, 5, 7, 12, 1300, 10000]
>>> opens = [(3, 3), (6, 6), (8, 11), (13, 1299), (1301, 9999)]
>>>
>>> I think 'open intervals' is the right terminology.
>>
>> Not really.  The open interval (3, 3) contains no integers where as the
>> closed interval [3, 3] contains exactly one integer: 3.
> 
> 
> OK.  'gaps of closed intervals in a bounded, monotonically increasing,
> integer sequence' it is.
> 
> 
>>    void print_gaps(int n, const int *data)
>>    {
>>         if (n > 1) {
>>              if (data[0] + 1 < data[1])
>>                   printf(" (%d, %d)", data[0] + 1, data[1] - 1);
>>              print_gaps(n - 1, data + 1);
>>         }
>>    }
>>
>> To test drive it I used:
>>
>>    int main(int argc, char **argv)
>>    {
>>         if (argc > 1) {
>>              int seq[argc-1];
>>              for (int a = 1; a < argc; a++)
>>                   seq[a-1] = atoi(argv[a]);
>>              print_gaps(argc-1, seq);
>>              putchar('\n');
>>         }
>>    }
> 
> 
> If you print the whole code I'll run it.
> 

That was almost the whole code.  You need to add:

#include <stdio.h>
#include <stdlib.h>

at the start, then Ben's print_gaps and main functions.  That is it.

If you call the program "gaps", then you run it with:

./gaps 1 2 4 5 7 12 1300 10000


[toc] | [prev] | [next] | [standalone]


#148250

FromDFS <nospam@dfs.com>
Date2019-11-13 23:57 -0500
Message-ID<_85zF.5075$II7.2317@fx17.iad>
In reply to#147978
On 11/12/2019 6:30 PM, Ben Bacarisse wrote:
> DFS <nospam@dfs.com> writes:
> 
>> You clc guys are masters at this stuff.
>>
>> Goal: Find all the open intervals in an ordered set of numbers
>>
>> nbrs  = [1, 2, 4, 5, 7, 12, 1300, 10000]
>> opens = [(3, 3), (6, 6), (8, 11), (13, 1299), (1301, 9999)]
>>
>> I think 'open intervals' is the right terminology.
> 
> Not really.  The open interval (3, 3) contains no integers where as the
> closed interval [3, 3] contains exactly one integer: 3.
> 
>    void print_gaps(int n, const int *data)
>    {
>         if (n > 1) {
>              if (data[0] + 1 < data[1])
>                   printf(" (%d, %d)", data[0] + 1, data[1] - 1);
>              print_gaps(n - 1, data + 1);
>         }
>    }
> 
> To test drive it I used:
> 
>    int main(int argc, char **argv)
>    {
>         if (argc > 1) {
>              int seq[argc-1];
>              for (int a = 1; a < argc; a++)
>                   seq[a-1] = atoi(argv[a]);
>              print_gaps(argc-1, seq);
>              putchar('\n');
>         }
>    }



That recursion is pretty cool.

I was inspired to decrapify mine (still iterative tho):
================================================================
#include <stdio.h>
#include <stdlib.h>

int main(void) {

   int seq[] = {1, 2, 4, 5, 7, 8, 12, 1300, 10000};

   for(int i=0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
     if(seq[i + 1] - seq[i] > 1) {
       if( seq[i + 1] - (seq[i] + 1) >= 1) {
         printf("[%d,%d] ", seq[i] + 1, seq[i + 1] - 1);
       }
     }		
   }

}
================================================================

[toc] | [prev] | [next] | [standalone]


Page 3 of 5 — ← Prev page 1 2 [3] 4 5  Next page →

Back to top | Article view | comp.lang.c


csiph-web