Стандартные функции, определенные в файлах заголовков или связанные автоматически?

#c #standards

#c #стандарты

Вопрос:

При написании базовой программы на c.

 #include <stdio.h>

main(){
  printf("program");
}
  

Есть ли определение printf в «stdio.h» или printf функция связана автоматически?

Ответ №1:

Обычно в stdio.h есть только прототип; определение должно быть внутри библиотеки, с которой ваш объектный модуль автоматически связан (различные msvcrt для VC в Windows, libcsomething для gcc в Linux).

Кстати, это <stdio.h> , не "stdio.h" .

Комментарии:

1. Я полагаю, что библиотека также может быть динамической (например, GNU libc в Linux).

2. Есть ли способ автоматически связать мои собственные библиотеки, как это делает компилятор? Просто пытаюсь понять происходящую хитрость.

3. @Lime: если это возможно, это очень зависит от компилятора.

4. @Lime — Какую цель вы преследуете, желая это сделать?

5. @Chris Просто пытаюсь понять, почему для стандартных библиотек был создан специальный сценарий. «Стандарты» не всегда были стандартными, поэтому у них должна была быть причина добавить эту функциональность. Если это было исключительно для удобства, я удивлен, что они не предоставили такую же функциональность общим библиотекам.

Ответ №2:

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

#include Все еще необходим, потому что он выводит стандартные функции в область видимости.

Комментарии:

1. Как работает это волшебство? Есть ли способ, которым я могу достичь того же волшебства?

2. Зависит от компилятора. Но зачем вам такая же магия?

3. Просто пытаюсь понять, почему для стандартных библиотек был создан специальный сценарий. В принципе, почему Деннис Ричи сотворил это волшебство ;)?

4. @Lime — В C Денниса Ричи не было много волшебства. У них был оператор, потому что компиляторы тогда не знали, как оптимизировать = 1 инструкцию increment. Я подозреваю, что все волшебство пришло намного позже.

5. Я могу только строить предположения. Я полагаю, что в первые дни не было стандартной библиотеки; каждая система (думаю, мэйнфреймы) имела свою собственную библиотеку C, которую мог модифицировать каждый программист. Не было необходимости в других библиотеках. Я бы предположил, что отдельные библиотеки появились довольно поздно. Но я повторяю: я здесь размышляю.

Ответ №3:

Строго говоря, компилятор и компоновщик — это разные вещи (и я не уверен, что стандарт C говорит о компиляции и компоновке, он более абстрактно говорит о проблемах перевода и реализации).

Например, в Linux вы часто используете gcc для перевода вашего hello.c исходного файла, и gcc является «управляющей программой», которая запускает компилятор cc1 , ассемблер as , компоновщик ld и т.д.

В Linux <stdio.h> заголовок представляет собой обычный файл. Запустите gcc -v -Wall -H hello.c -o hello , чтобы понять, что происходит. -v Опция запрашивает gcc показать вам фактические программы ( cc1 и другие), которые используются. -Wall Флаг запрашивает все предупреждения (не игнорируйте их!). -H Флаг запрашивает компилятор показать вам файлы заголовков, которые включены.

Файл заголовка /usr/include/stdio.h сам #include содержит другие заголовки. В какой-то момент появляется объявление printf , компилятор анализирует его и соответствующим образом корректирует его состояние.

Позже gcc команда запустит компоновщик ld и попросит его связать стандартную библиотеку C (в моей системе /usr/lib/x86_64-linux-gnu/libc.so ). Эта библиотека содержит [объектный] код printf

Я не уверен, что понял ваш вопрос. Чтение страницы википедии о компиляторах, компоновщиках, ядре Linux, системных вызовах должно быть полезным.

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

Комментарии:

1. Спасибо за ответ. Хм, я не смог найти cc1 в своей системе? Может ли in иметь другое имя в ubuntu 11.10?

2. У вас есть cc1 , но это скрыто в каком-то трудно угадываемом пути (его нет и не должно быть в вашем $ PATH). Просто запустите, gcc -v как я предложил, вам будет показано, какие cc1 используются.