Преодоление ограничений C для больших проектов - PullRequest
15 голосов
/ 28 апреля 2010

Одним из аспектов, где C показывает свой возраст, является инкапсуляция кода. Многие современные языки имеют классы, пространства имен, пакеты ... гораздо удобнее организовывать код, чем просто "включить".

Поскольку C по-прежнему является основным языком для многих крупных проектов. Как вам преодолеть его ограничения?

Я полагаю, что одним из основных факторов должно быть много дисциплины . Я хотел бы знать, что вы делаете для обработки большого количества кода на языке C, какие авторы или книги вы можете порекомендовать.

Ответы [ 5 ]

19 голосов
/ 28 апреля 2010
  • Разделите код на функциональные единицы.
  • Соберите эти блоки кода в отдельные библиотеки.
  • Использование скрытых символов в библиотеках для уменьшения конфликтов пространства имен.

Подумайте об открытом исходном коде. В ядре Linux, библиотеке GNU C, системе X Window и настольном проекте Gnome имеется огромное количество кода C Тем не менее, все это работает вместе. Это потому, что большая часть кода не видит другой код. Он общается только через четко определенные интерфейсы. Сделайте то же самое в любом большом проекте.

3 голосов
/ 29 апреля 2010

Некоторым людям это не нравится, но я сторонник организации своих структур и связанных функций вместе, как если бы они были классом, где указатель this передается явно. Например, в сочетании с согласованным соглашением об именах, чтобы сделать пространство имен явным. Заголовок будет что-то вроде:

typedef struct foo {
  int x;
  double y;
} FOO_T

FOO_T * foo_new();

int foo_set_x(FOO_T * self, int arg1);

int foo_do_bar(FOO_T * self, int arg1);

FOO_T * foo_delete(FOO_T * self);

В реализации все "частные" функции будут статическими. Недостатком этого является то, что вы не можете на самом деле обеспечить, чтобы пользователь не шутил с членами структуры. Это просто жизнь в с. Я нахожу, что этот стиль делает для многократно используемых C-типов.

2 голосов
/ 28 апреля 2010

Хороший способ добиться некоторой инкапсуляции - объявить внутренние методы или переменные модуля как static

1 голос
/ 28 апреля 2010

Как говорит Андрес, static ваш друг. Но если говорить о друзьях ... если вы хотите разделить библиотеку на два файла, то некоторые символы из одного файла, которые нужно видеть в другом, не могут быть static. Определите некоторые соглашения об именах: все нестатические символы из библиотеки foo начинаются с foo_. И убедитесь, что они всегда соблюдаются: именно символы, для которых это кажется сдерживающим («Мне нужно назвать это foo_max ?! Но это просто max!»), Что будут столкновения.

Как говорит Зан, типичный дистрибутив Linux можно рассматривать как огромный проект, написанный в основном на C. Он работает. Существуют интерфейсы, а крупные подпроекты реализованы в виде отдельных процессов . Реализация в отдельных процессах помогает отладке, тестированию, повторному использованию кода и обеспечивает вторую иерархию в дополнение к единственной, существующей на уровне ссылок. Когда ваш проект становится достаточно большим, может иметь смысл поместить некоторые функции в отдельные процессы. Что-то уже специализированное, как компилятор C, обычно реализуется в виде трех процессов: препроцессор, компилятор, ассемблер.

0 голосов
/ 29 апреля 2010

Если вы можете контролировать проект (например, на месте или платите кому-то другому за это), вы можете просто установить правила и использовать обзоры и инструменты для их обеспечения. В этом нет особой необходимости в языке, вы можете, например, потребовать, чтобы все функции, используемые вне модуля (= набор файлов, даже не должны быть отдельными), были помечены таким образом. По сути, вы заставляете разработчиков думать об интерфейсах и придерживаться их.

Если вы действительно хотите высказать свое мнение, вы можете определить макросы, чтобы показать это, например,

#define PUBLIC 
#define PRIVATE static

или что-то подобное.

Так что вы правы, дисциплина является ключом здесь. Он включает в себя установление правил и обеспечение их соблюдения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...