Архив 18 августа 2020

Язык Си образца 70-х годов

Есть одна статейка, описывающая портирование Unix с PDP-11 на VAX (кстати, вопреки обычно озвучиваемому мнению о легкой переносимости Unix между разными архитектурами, именно продукция фирмы Digital долгое время была основной и практически единственной “платформой” для Unix):

https://www.bell-labs.com/usr/dmr/www/otherports/32v.pdf

На последней страничке приведены пожелания для доработки компилятора, очень интересны пункты 2 и 3:

Based on our experience, we strongly recommend that the C language and its compilers be enhanced so that:
<…>
2. The ’->’ operator is checked to insure that the structure element on the right is a member of a structure to which the pointer on the left may point.
3. A structure element may be declared with any name as long as the name is unique within the immediately surrounding structure. (The current requirement that a structure element name must uniquely correspond to an offset from the beginning of the structure, across all structures in a compilation, creates naming problems and frequently leads to errors of the type noted in item 2 above.)

Написанное немного непонятно для тех, кто никогда не задумывался, как структурки лежат в памяти – поэтому коротенький пример с примером двух ошибок:

struct A {
    int first;
    int second;
};

struct B {
    int first; /* Так нельзя - имена членов структур должны быть уникальны, first уже есть в struct A, см. пункт 3 */
    int second;
};

struct C {
    char c_first;
    int c_second;
};

struct C c;
c.second = 123; /* Компилятор съест и не подавится, но запишет это 123 совсем не туда, куда хотелось бы, см. пункт 2 */
/* То же самое с точки зрения современного Си: */
((struct *A) &c)->second = 123; /* Ты сам себе злобный Буратино */

При этом это поведение, странное с точки зрения “высокоуровневого” программиста и абсолютно нормальное – с точки зрения “низкоуровневой”, когда мы думаем о байтиках в памяти, использовалось в коде Unix сплошь и рядом, как подсказывает нам статья, и явно привело к немалому количеству сюрпризов при переходе с 16 бит на 32.