1. 67
  1.  

  2. 8

    A few notes on this otherwise excellent post.

    C99 provides a macro SIZE_MAX with the maximum value possible in size_t. C89 doesn’t have it, although you can obtain the value by casting (size_t)-1. This assumes a twos’ complement architecture, which is the most common number representation on modern computers. You can enforce the requirement like this: […]

    This actually assumes nothing and is perfectly portable because the standard says so.

    From C89 (draft), “3.2.1.2 Signed and unsigned integers” (emphasis mine):

    When a signed integer is converted to an unsigned integer with equal or greater size, if the value of the signed integer is nonnegative, its value is unchanged. Otherwise: if the unsigned integer has greater size, the signed integer is first promoted to the signed integer corresponding to the unsigned integer; the value is converted to unsigned by adding to it one greater than the largest number that can be represented in the unsigned integer type.

    The rationale was explicitly to avoid a change in the bit pattern except filling the high-order bits.


    DOS used \n\r for line endings.

    As far as I know, DOS used \r\n and Mac OS (classic) used \n\r. EDIT: Mac OS (classic) used \r.


    OpenBSD provides arc4random() which returns crypto-grade randomness.

    arc4random() is also available on FreeBSD, NetBSD and macOS.

    1. 8

      arc4random() is also available on FreeBSD, NetBSD and macOS.

      And on illumos systems!

      1. 4

        MS-DOS used ‘\r\n’ (in that order). Classic Mac OS (pre-OS X) used ‘\r’ and Unix has always used ‘\n’.

        The wide character stuff was the most interesting to read.

        1. 1

          I stand corrected; thanks. I’ll fix my comment.

        2. 3

          Thank you (and the other commenters) for your corrections, I’ll update the article. Learning from the discussion is another great thing about writing these articles.

          1. 0

            arc4random() is also available on FreeBSD, NetBSD and macOS.

            This is also helpfully defined in stdlib.h on linux and can be linked to with -lbsd.

            1. 4

              libbsd is a thirdparty library with its own issues because it can’t decide which BSD to use as source, resulting in different APIs and random breaks when they switched between implementations. https://cgit.freedesktop.org/libbsd/commit/?id=e4e15ed286f7739682737ec2ca6d681dbdd00e79

              1. 3

                fwiw that doesn’t appear to have affected the arc4random* functions. The core issue seems to be different signatures between the bsds. While changing implementations may be a problem for code using libbsd to port programs, it isn’t as big of a problem for software written with the library in mind. Additionally, the arc4random functions appear to have consistent signatures across the BSDs, so a breacking change like what you linked wouldn’t be necessary. As it is, libbsd is an easy and sane way to get random numbers across different unixes.

          2. 4

            This is a post worthy of a deep read. Thanks for writing it!

            1. 4

              In addition to “design” of C Standard Library, “implementation” side also contains some amazing stuffs. strstr is ANSI C and does string search. Correct implementation is trivial. Efficient implementation is decidedly not. You may imagine it uses Knuth-Morris-Pratt or Boyer-Moore, but no, production algorithm is called Two-Way. Here it is:

              https://sourceware.org/git/?p=glibc.git;a=blob;f=string/str-two-way.h;hb=HEAD