git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [RFC] Convert builin-mailinfo.c to use The Better String Library.

From
WBWalter Bright <boost@digitalmars.com>
Date
Sep 7, 2007, 09:14 UTC
Message-ID
<fbr4oi$5ko$1@sea.gmane.org>
In-Reply-To
<851wda7ufz.fsf@lola.goethe.zz>
David Kastrup wrote:
Show 21 quoted lines
> Walter Bright <boost@digitalmars.com> writes:
> 
>> A canonical example is that of a loop. Consider a simple C loop over
>> an array:
>>
>> void foo(int array[10])
>> {
>>     for (int i = 0; i < 10; i++)
>>     {   int value = array[i];
>>         ... do something ...
>>     }
>> }
>>
>> It's simple, but it has a lot of problems:
>>
>> 1) i should be size_t, not int
> 
> Wrong.  size_t is for holding the size of memory objects in bytes, not
> in terms of indices.  For indices, the best variable is of the same
> type as the declared index maximum size, so here it is typeof(10),
> namely int.

The easiest way to show the error is consider the code being ported to a typical 64 bit C compiler. int's are still 32 bits, yet the array can be larger than 32 bits. You're right in that what we want to be able to do is typeof(array dimension), but there is no way to do that automatically in C, which is my point. If the array dimension changes, you have to carefully check to make sure every loop dependency on the type is updated, too.

size_t will always work, however, making it a better choice than int, at least for C.

>> 2) array is not checked for overflow
> 
> Why should it?

Because the 10 array dimension is not statically checked in C. I could pass it a pointer to 3 ints without the compiler complaining. This makes it a potential maintenance problem. Also, the maintenance programmer may change the array dimension in the function signature, but overlook changing it in the for loop. Again, a maintenance problem.

>> 3) 10 may not be the actual array dimension
> 
> Your point is?

Array buffer overflow errors are commonplace in C, because array dimensions are not automatically checked at either compile or run time. This is an expensive problem. Some C APIs try to deal with this by passing a second argument for arrays giving the dimension (snprintf, for example), but this tends to be sporadic, not conventional. It being extra work for the programmer inevitably means it doesn't get done.

Show 8 quoted lines
>> 4) may be more efficient to step through the array with pointers,
>> rather than indices
> 
> No.  It is a beginners' and advanced users' mistake to think using
> pointers for access is a good idea.  Trivial optimizations are what a
> compiler is best at, not the user.  Using pointer manipulation will
> more often than not break loop unrolling, loop reversal, strength
> reduction and other things.

C compilers vary widely in the optimizations they'll do for simple loops. I see often enough attempts by programmers to take such matters into their own hands. I agree with you on that - and suggest the language should not tempt the user to do such optimizations.

>> 5) type of array may change, but the type of value may not get
>> updated
> 
> Huh?

Let's say our fearless maintenance programmer decides to make it an array of longs, not an array of ints. He overlooks changing the type of value in the loop. Suddenly, things subtly break because of overflows. Or maybe he changed the int to an unsigned, now the divides in the loop give different answers. Etc. There really isn't any compiler/language help in finding these kinds of problems.

>> 6) crashes if array is NULL
> 
> Certainly.  Your point being?

I consider an array that is NULL to have no members, so instead of crashing the loop should execute 0 times.

>> 7) only works with arrays and pointers
> 
> Since there are only arrays and pointers in C, not really a restriction.

C has structs, too, as well as more complicated user defined collections. Essentially, you cannot (simply) write generic algorithms in C, because you cannot (simply) generically express iteration. Of course, you can still express anything in C if you're willing to work hard enough to get it. Me, I'm too lazy <g>. It's like why I can't play chess - everytime I try to play it instead I think about writing a program to do the hard work for me.

Show 16 quoted lines
>> As a programmer, I'm specifying exactly what I want to happen without
>> much extra puffery. It's less typing, simpler, and more resistant to
>> bugs.
>>
>> 1) correct loop index type is selected based on the type of array
>> 2) arrays carry with them their dimension, so foreach is guaranteed to
>> step through the loop the correct number of times
>> 3) implementation decides if pointers will do a better job than
>> indices, based on the compilation target
>> 4) type of value is inferred automatically from the type of array, so
>> no worries if the type changes
>> 5) Null arrays have 0 length, so no crashing
>> 6) works with any collection type
> 
> Most of those are toy concerns.  They prevent problems that don't
> actually occur much in practice.

I beg to differ - buffer overflow bugs are common and expensive. The nice thing about the D loop is it is LESS typing than the C one - you get the extra robustness for free.

Let's look at the code gen for the inner loop for C:
L8:             push    [EBX*4][ESI]
                 call    near ptr _bar
                 inc     EBX
                 add     ESP,4
                 cmp     EBX,0Ah
                 jb      L8
and for D:
LE:            mov     EAX,[EBX]
                call    near ptr _D4test3barFiZv
                add     EBX,4
                cmp     EBX,ESI
                jb      LE
I think you can see that performance isn't an impediment.
Previous: David KastrupNext: David Kastrup
Message 41 of 102 in “[RFC] Convert builin-mailinfo.c to use The Better String Library.”
  1. Lukas SandströmSep 4, 2007
  2. Alex RiesenSep 4, 2007
  3. Pierre HabouzitSep 4, 2007
  4. Kristian HøgsbergSep 5, 2007
  5. Matthieu MoySep 5, 2007
  6. Miles BaderSep 6, 2007
  7. Dmitry KakurinSep 6, 2007
  8. Shawn O. PearceSep 6, 2007
  9. Andreas EricssonSep 6, 2007
  10. Junio C HamanoSep 6, 2007
  11. Andreas EricssonSep 6, 2007
  12. David KastrupSep 6, 2007
  13. Miles BaderSep 6, 2007
  14. Johannes SchindelinSep 6, 2007
  15. Linus TorvaldsSep 6, 2007
  16. Dmitry KakurinSep 7, 2007
  17. Linus TorvaldsSep 7, 2007
  18. Dmitry KakurinSep 7, 2007
  19. Linus TorvaldsSep 7, 2007
  20. Dmitry KakurinSep 7, 2007
  21. David SymondsSep 7, 2007
  22. Theodore TsoSep 7, 2007
  23. Steven BurnsSep 20, 2007
  24. Andreas EricssonSep 20, 2007
  25. Andreas EricssonSep 7, 2007
  26. Dmitry KakurinSep 7, 2007
  27. David KastrupSep 7, 2007
  28. Dmitry KakurinSep 8, 2007
  29. David KastrupSep 8, 2007
  30. Andreas EricssonSep 9, 2007
  31. David KastrupSep 7, 2007
  32. Johannes SchindelinSep 7, 2007
  33. Johannes SchindelinSep 7, 2007
  34. David KastrupSep 7, 2007
  35. Linus TorvaldsSep 7, 2007
  36. alanSep 7, 2007
  37. Walter BrightSep 7, 2007
  38. David KastrupSep 7, 2007
  39. Walter BrightSep 7, 2007
  40. David KastrupSep 7, 2007
  41. Walter BrightSep 7, 2007
  42. David KastrupSep 7, 2007
  43. Walter BrightSep 7, 2007
  44. David KastrupSep 7, 2007
  45. Walter BrightSep 7, 2007
  46. Andreas EricssonSep 8, 2007
  47. Pierre HabouzitSep 9, 2007
  48. Andreas EricssonSep 9, 2007
  49. Wincent ColaiutaSep 7, 2007
  50. Pierre HabouzitSep 7, 2007
  51. Walter BrightSep 7, 2007
  52. David KastrupSep 7, 2007
  53. Walter BrightSep 7, 2007
  54. Pierre HabouzitSep 7, 2007
  55. David KastrupSep 7, 2007
  56. Pierre HabouzitSep 7, 2007
  57. Walter BrightSep 7, 2007
  58. Pierre HabouzitSep 7, 2007
  59. Walter BrightSep 7, 2007
  60. John 'Z-Bo' ZabroskiSep 8, 2007
  61. David KastrupSep 8, 2007
  62. Steven BurnsSep 19, 2007
  63. Wincent ColaiutaSep 7, 2007
  64. Paul WankadiaSep 7, 2007
  65. Nicolas PitreSep 7, 2007
  66. Wincent ColaiutaSep 7, 2007
  67. Andreas EricssonSep 7, 2007
  68. Johannes SchindelinSep 7, 2007
  69. Andreas EricssonSep 7, 2007
  70. Wincent ColaiutaSep 7, 2007
  71. Karl HasselströmSep 7, 2007
  72. Andreas EricssonSep 7, 2007
  73. Wincent ColaiutaSep 7, 2007
  74. Andreas EricssonSep 9, 2007
  75. David KastrupSep 7, 2007
  76. Wincent ColaiutaSep 7, 2007
  77. Walter BrightSep 7, 2007
  78. Andreas EricssonSep 7, 2007
  79. Walter BrightSep 7, 2007
  80. David KastrupSep 7, 2007
  81. Andreas EricssonSep 9, 2007
  82. Bernd JendrissekSep 17, 2009
  83. Wincent ColaiutaSep 7, 2007
  84. Walter BrightSep 7, 2007
  85. Steven BurnsSep 22, 2007
  86. David KastrupSep 7, 2007
  87. Andy ParkinsSep 7, 2007
  88. David KastrupSep 7, 2007
  89. Johannes SchindelinSep 7, 2007
  90. Dmitry KakurinSep 8, 2007
  91. David KastrupSep 8, 2007
  92. Alex RiesenSep 8, 2007
  93. figoSep 24, 2007
  94. David KastrupSep 24, 2007
  95. Steven BurnsSep 25, 2007
  96. David KastrupSep 25, 2007
  97. Syed M RaihanMay 22, 2012
  98. Ian MoltonJun 10, 2010
  99. Jakub NarebskiJun 11, 2010
  100. Dario RodriguezJun 11, 2010
  101. Kristian HøgsbergSep 5, 2007
  102. Lukas SandströmSep 7, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.