Что вы можете сделать в C без "std" включает? Являются ли они частью "C" или просто библиотеками? - PullRequest
43 голосов
/ 04 апреля 2010

Прошу прощения, если это субъективный или повторный вопрос. Искать неловко, поэтому я не знал, какие термины включить.

Что мне хотелось бы знать, так это то, что представляют собой базовые инструменты / функции Foundation в C, если вы не включаете стандартные библиотеки, такие как stdio и stdlib.

Что я могу сделать, если нет printf(), fopen() и т. Д.?

Кроме того, эти библиотеки технически являются частью языка "C", или они просто очень полезны и эффективно необходимы?

Ответы [ 10 ]

26 голосов
/ 04 апреля 2010

В стандарте C это сказано (5.1.2.3/5):

Наименьшие требования по соответствию Реализация:

- В точках последовательности летучие объекты стабильны в том смысле, что предыдущие доступы завершены и последующие доступы еще не произошли.

- При завершении программы все данные записанные в файлы должны быть идентичными в результате этого исполнения программа согласно аннотации семантика произвела бы.

- динамика ввода и вывода интерактивные устройства должны иметь место как указано в 7.19.3.

Таким образом, без стандартных библиотечных функций единственное поведение, которое гарантированно должна выполнять программа, относится к значениям изменчивых объектов, поскольку вы не можете использовать любой из гарантированного доступа к файлу или «интерактивных устройств». «Чистый C» обеспечивает взаимодействие только через стандартные библиотечные функции.

Pure C - это еще не все, так как ваше оборудование может иметь определенные адреса, которые делают определенные вещи при чтении или записи (будь то шина SATA или PCI, необработанная видеопамять, последовательный порт, что-то делать) звуковой сигнал или мигающий светодиод). Итак, зная кое-что о вашем оборудовании , вы можете много писать на C без использования стандартных библиотечных функций. Потенциально вы можете реализовать стандартную библиотеку C, хотя для этого может потребоваться доступ к специальным инструкциям процессора, а также к специальным адресам памяти.

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

Стандартные библиотеки являются частью спецификации языка Си, но в любом языке, как правило, существует грань между языком "как таковым" и библиотеками. Это концептуальная разница, но в принципе не очень важная, потому что в стандарте говорится, что они собираются вместе. Любой, кто делает что-то нестандартное, может так же легко удалить языковые функции, как и библиотеки. В любом случае, результат не соответствует реализации C.

Обратите внимание, что "автономная" реализация C должна реализовывать только подмножество стандартов, не включающее ни одного ввода-вывода, поэтому вы находитесь в положении, которое я описал выше, полагаясь на аппаратные расширения для получения ничего интересного сделано. Если вы хотите провести различие между «базовым языком» и «библиотеками» на основе стандарта, тогда это может быть хорошим местом для проведения линии.

13 голосов
/ 04 апреля 2010

Что вы могли бы сделать? Все!

В Си нет магии, кроме, возможно, препроцессора.

Самое сложное, пожалуй, написать putchar - так как это зависит от платформы ввода / вывода.

Это хорошее упражнение для старшекурсников по созданию собственной версии varargs, и, как только вы ее получите, создайте свою собственную версию vaprintf, затем printf и sprintf.

Я делал все это на Macintosh в 1986 году, когда меня не устраивали процедуры stdio, поставляемые с Lightspeed C - я написал свой собственный обработчик окон с win_putchar, win_printf, in_getchar и win_scanf.

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

7 голосов
/ 04 апреля 2010

Вы, конечно, не обязаны использовать стандартные библиотеки, если они вам не нужны. Многие встроенные системы либо не поддерживают стандартную библиотеку, либо не могут использовать ее по тем или иным причинам. Стандарт даже специально говорит о реализациях без поддержки библиотеки, стандарт C99 5.1.2.1 «Отдельно стоящая среда»:

В автономной среде (в которой выполнение программы на С может осуществляться без какой-либо выгоды от операционной системы), имя и тип функции, вызываемой при запуске программы, определяются реализацией. Любые библиотечные средства, доступные для автономной программы, кроме минимального набора, требуемого пунктом 4, определяются реализацией.

Заголовки, требуемые C99, чтобы быть доступными в автономной реализации: <float.h>, <iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h> и <stdint.h>. Эти заголовки определяют только типы и макросы, поэтому нет необходимости в библиотеке функций для их поддержки.

Без стандартной библиотеки вы полностью зависите от своего собственного кода, любых нестандартных библиотек, которые могут быть вам доступны, и любых вызовов операционной системы, с которыми вы можете взаимодействовать (которые могут считаться не стандартная библиотека звонков). Вполне возможно, что для взаимодействия с устройствами и / или с любой другой операционной системой на платформе вам потребуются процедуры сборки вызовов программы на C.

5 голосов
/ 01 марта 2017

Что я могу сделать, если нет printf (), fopen () и т. Д.?

Пока вы знаете, как взаимодействовать с системой, которую вы используете, вы можете жить без стандартной библиотеки C. Во встроенных системах, где у вас всего несколько килобайт памяти, вы, вероятно, вообще не хотите использовать стандартную библиотеку.

Это Привет, Мир! пример на Linux и Windows без использования каких-либо стандартных функций C:

Например, в Linux вы можете вызывать системные вызовы Linux непосредственно во встроенной сборке:

/* 64 bit linux. */

#define SYSCALL_EXIT 60
#define SYSCALL_WRITE 1

void sys_exit(int error_code)
{
    asm volatile
    (
        "syscall"
        : 
        : "a"(SYSCALL_EXIT), "D"(error_code)
        : "rcx", "r11", "memory"
    );
}

int sys_write(unsigned fd, const char *buf, unsigned count)
{
    unsigned ret;

    asm volatile
    (
        "syscall"
        : "=a"(ret)
        : "a"(SYSCALL_WRITE), "D"(fd), "S"(buf), "d"(count)
        : "rcx", "r11", "memory"
    );

    return ret;
}

int _start()
{
    const char hwText[] = "Hello world!\n";

    sys_write(1, hwText, sizeof(hwText));
    sys_exit(12);

    return 0;
}

Скомпилируйте это с:

gcc -nostdlib nostd.c 

И выводит Hello world! и выходит.

В Windows системные вызовы не публикуются, вместо этого они скрыты за другим уровнем абстракции, kernel32.dll. Который всегда загружается при запуске вашей программы, хотите вы этого или нет. Таким образом, вы можете просто включить windows.h и использовать Win32 API:

#include <windows.h>

int _start()
{
    const char str[] = "Hello world!\n";
    HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD written;

    WriteFile(stdout, str, sizeof(str), &written, NULL);
    ExitProcess(12);

    return 0;
}

windows.h не имеет ничего общего со стандартной библиотекой C, так как вы сможете писать программы для Windows и на любом другом языке.

Вы можете скомпилировать его с помощью инструментов MinGW, например:

gcc -nostdlib C:\Windows\System32\kernel32.dll nostdlib.c

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

Если вы дизассемблируете программу, вы увидите, что там присутствует только ваш код, в ней нет стандартного раздувания библиотеки.

Таким образом, вы можете использовать C без стандартной библиотеки.

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

Библиотеки std являются «стандартными» библиотеками, поскольку для того, чтобы компилятор C соответствовал стандарту (например, C99), эти библиотеки должны быть «включаемыми». Для интересного примера, который может помочь в понимании того, что это значит, взгляните на вызов Джессики МакКеллар здесь:

http://blog.ksplice.com/2010/03/libc-free-world/

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

Ни одно из них не является частью ключевых слов языка. Однако все дистрибутивы C должны включать реализацию этих библиотек. Это обеспечивает переносимость многих программ.

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

В практическом плане функции библиотеки в первую очередь предназначены для того, чтобы избавить вас от необходимости изобретать велосипед. Некоторые вещи (например, строковые и библиотечные функции) легче реализовать. Другие вещи (например, ввод / вывод) очень сильно зависят от операционной системы. Написание собственной версии было бы возможно для одного O / S, но это сделает программу менее переносимой.

Но вы могли бы писать программы, которые делают много полезных вещей (например, вычисляют PI или смысл жизни или моделируют автоматы). Однако, если вы непосредственно не использовали ОС для ввода / вывода, было бы очень трудно наблюдать за выходными данными.

В повседневном программировании успех языка программирования обычно требует наличия полезной высококачественной стандартной библиотеки и библиотек для многих полезных задач. Они могут быть первыми или сторонними, но они должны быть там.

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

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

Элегантность C заключается в ее простоте, однако. В отличие от Fortran, который включает в себя большую часть функциональности как часть языка, C довольно сильно зависит от своей библиотеки. Это дает ему большую степень гибкости за счет того, что он несколько менее согласован от платформы к платформе.

Это хорошо работает, например, в операционной системе, где реализованы совершенно отдельные «библиотеки», чтобы обеспечить аналогичную функциональность с реализацией внутри самого ядра.

Некоторые части библиотек указаны как часть ANSI C; я полагаю, что они являются частью языка, но не в его основе.

0 голосов
/ 16 января 2012

Язык ассемблера имеет простые команды, которые перемещают значения в регистры процессора, памяти и других основных функций, а также выполняют основные возможности и вычисления машины. Библиотеки C - это в основном куски кода сборки. Вы также можете использовать ассемблерный код в своих программах на Си. var - это инструкция кода сборки. Когда вы используете 0x перед числом, чтобы сделать его шестнадцатеричным, это инструкция по сборке. Ассемблерный код - это читаемая форма машинного кода, которая представляет собой визуальную форму фактических состояний переключения путей цепей.

Таким образом, в то время как машинный код и, следовательно, ассемблерный код встроен в машину, языки C объединяются со всеми видами предварительно сформированных комбинаций кода, включая ваши собственные функции, которые могут быть частично на языке ассемблера и частично вызов других функций на ассемблере или других C-библиотек. Таким образом, ассемблерный код является основой всего программирования, и после этого можно догадаться, что к чему. Вот почему так много языков и так мало настоящих стандартов.

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

Библиотека Standard C является частью ANSI C89 / ISO C90. Недавно я работал над библиотекой для компилятора C, который ранее не был ANSI-совместимым.

Книга П. Дж. Плаугера Стандартная библиотека С была отличным справочным материалом для этого проекта. В дополнение к изложению требований стандарта Plauger объясняет историю каждого файла .h и причины, лежащие в основе разработки API. Он также предоставляет полную реализацию библиотеки, что мне очень помогло, когда что-то в стандарте было неясно.

Стандарт описывает макросы, типы и функции для каждого из 15 заголовочных файлов (включая stdio.h, stdlib.h, но также float.h, limit.h, math.h, locale.h и другие).

Компилятор не может претендовать на статус ANSI C, если он не включает стандартную библиотеку.

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

CRT является частью языка C так же, как ключевые слова и синтаксис. Если вы используете C, ваш компилятор ДОЛЖЕН предоставить реализацию для вашей целевой платформы.

Edit: Это так же, как STL для C ++. Все языки имеют стандартную библиотеку. Может быть, ассемблер в качестве исключения, или некоторые другие языки низкого уровня. Но большинство средних / высоких уровней имеют стандартные библиотеки.

...